All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vmlens.trace.agent.bootstrap.parallize.logicState.ThreadId2State Maven / Gradle / Ivy

There is a newer version: 1.1.5
Show newest version
package com.vmlens.trace.agent.bootstrap.parallize.logicState;

import java.io.PrintWriter;
import java.lang.Thread.State;

import com.vmlens.trace.agent.bootstrap.callback.AgentLogCallback;
import com.vmlens.trace.agent.bootstrap.interleave.InterleaveFacade;
import com.vmlens.trace.agent.bootstrap.interleave.lock.LockOperation;
import com.vmlens.trace.agent.bootstrap.interleave.operation.OperationTyp;
import com.vmlens.trace.agent.bootstrap.interleave.operation.ThreadJoin;
import com.vmlens.trace.agent.bootstrap.parallize.ParallizeFacade;
import com.vmlens.trace.agent.bootstrap.parallize.operation.Operation;

import gnu.trove.iterator.TLongObjectIterator;
import gnu.trove.map.hash.TIntLongHashMap;
import gnu.trove.map.hash.TLongIntHashMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import gnu.trove.procedure.TLongObjectProcedure;
import gnu.trove.set.hash.TLongHashSet;

public class ThreadId2State {

	final TLongHashSet blockedThreads = new TLongHashSet();
	private final TLongObjectHashMap map = new TLongObjectHashMap();
	private final TLongIntHashMap startedThreadIds = new TLongIntHashMap();
	
	
	
	
	//private LoopList index2ThreadId = new LoopList();
	public static final int LOOP_DETECTION_UNDECIDED = -1;

	private final TIntLongHashMap index2ThreadId = new TIntLongHashMap();

	private int maxIndex = 0;

	private final InterleaveFacade interleaveFacade;

	public ThreadId2State(InterleaveFacade interleaveFacade) {
		super();
		this.interleaveFacade = interleaveFacade;
	}

	
	public long[] activeThreadIds() 
	{
		return map.keys();
	}
	
	
	
	public int incrementOperationCount(long threadId)
	{
		ThreadState threadState = map.get(threadId);
		
		if(threadState == null)
		{
			return 0;
		}
		
		threadState.operationCount++;
		
		return threadState.operationCount;
		
		
	}
	
	
	public long getActiveThreadId4ThreadEnded() {

		int result = interleaveFacade.activeThreadIndex();

		if (result == -1) {
			return index2ThreadId.get(0);
		} else {
			
			if(! index2ThreadId.contains(result))
			{
				//AgentLogCallback.log("not there: " + result);
				interleaveFacade.incrementCurrentIndex();
				
				return getActiveThreadId4ThreadEnded();
			}
			
			
			return index2ThreadId.get(result);
		}

	}
	
	
	private static final int MAX_OPERATIONS_IN_THREAD = 10;
	
	
	private long getActiveThreadIdAtEnd(long forThreadId)
	{
		
	

		if(  ! interleaveFacade.isSecondRun )
		{
			long mainThreadId= index2ThreadId.get(0);
			ThreadState threadState = map.get(mainThreadId);
			
			if(threadState != null)
			{
				if( threadState.timesReturnedForEndOfActiveThreadIndex < MAX_OPERATIONS_IN_THREAD )
				{
					 threadState.timesReturnedForEndOfActiveThreadIndex++;
					 return mainThreadId;
				}
				
				
				// threadState.timesReturnedForEndOfActiveThreadIndex = 0;
			}
			
		}
		
		
	
//		 
//			if( ! map.contains(forThreadId) )
//			{
//				AgentLogCallback.logException(new Exception("not there " + forThreadId));
//				return getActiveThreadId4ThreadEnded();
//			}
//		 
//		 
//		return forThreadId;
//		
//		
//	}
//	else {
	
		ThreadState  threadState = map.get(forThreadId);
		
		if( threadState.timesReturnedForEndOfActiveThreadIndex < MAX_OPERATIONS_IN_THREAD )
		{
			 threadState.timesReturnedForEndOfActiveThreadIndex++;
			 return forThreadId;
		}
		
		
		TLongObjectIterator iter = map.iterator();
		while( iter.hasNext() )
		{
			iter.advance();
			threadState = iter.value();
			
			
			if( threadState.timesReturnedForEndOfActiveThreadIndex < MAX_OPERATIONS_IN_THREAD )
			{
				 threadState.timesReturnedForEndOfActiveThreadIndex++;
				 return iter.key();
			}
			
			
			
		}
		
		iter = map.iterator();
		while( iter.hasNext() )
		{
			iter.advance();
			threadState = iter.value();
			threadState.timesReturnedForEndOfActiveThreadIndex = 0;
			
			
		}
		
		return forThreadId;
		
	//}	
		
		
	}
	
	
	public void setAtThreadJoin(long forThreadId,long joinWithThreadId)
	{
		ThreadState threadState = map.get(forThreadId);
		if( threadState != null )
		{
			threadState.joinWithThreadId = joinWithThreadId;
		}
		
		
	}
	
	

	public long getActiveThreadId4AfterOperation(long forThreadId) {

		int result = interleaveFacade.activeThreadIndex();

		if (result == -1) {
			return getActiveThreadIdAtEnd(forThreadId);
		} else {
			
			if( ! index2ThreadId.contains(result))
			{
				return forThreadId;
			}
			
			return index2ThreadId.get(result);
		}

	}
	
	
	
	public void setActivated(long threadId) {
		ThreadState state = map.get(threadId);

		if (state != null) {
			if (state.thread.getState() != State.RUNNABLE) {
				System.err.println(state.thread.getState());
				(new Exception()).printStackTrace();
			}

			state.activated = true;
			state.joinWithThreadId  = -1L;
		}

	}

	public void setDeactivated(long threadId) {
		ThreadState state = map.get(threadId);

		if (state != null) {

			state.activated     = false;
			state.joinWithThreadId  = -1L;
		}
	}

	public void debug(final PrintWriter writer) {

		writer.println(map.size());
		map.forEachEntry(new TLongObjectProcedure() {

			@Override
			public boolean execute(long a, ThreadState b) {

				writer.println(a + " " + b + " " + b.thread.getState());

				return true;
			}

		});

	}

	boolean isActive(long threadId) {
		ThreadState state = map.get(threadId);
		if (state == null) {
			return false;
		}
		if (!state.activated) {
			return true;
		}
		if (state.thread.getState() == State.RUNNABLE) {
			return true;
		}
		StackTraceElement[] elemArray = state.thread.getStackTrace();
		if (elemArray.length > 0) {
			if (elemArray[0].getClassName().startsWith("com.vmlens.trace.agent")) {
				return true;
			}

		}
		
		/*
		 * wegen:
		 * 	sun.misc.Unsafe.park(Native Method)
			com.vmlens.trace.agent.bootstrap.threadQueue.QueueCollection.park(QueueCollection.java:69)
			
			darf aber nicht com.vmlens.trace.agent sein wegen:
			java.lang.Object.wait(Native Method)
			com.vmlens.trace.agent.bootstrap.callback.SynchronizedStatementCallback.waitCall(SynchronizedStatementCallback.java:28)
			
			wird dann nicht als active erkannt
			
		 */
		
		
		if (elemArray.length > 1) {
			if (elemArray[1].getClassName().startsWith("com.vmlens.trace.agent.bootstrap.threadQueue.QueueCollection")) {
				return true;
			}

		}
		
		
		if( state.joinWithThreadId != -1L )
		{
			if( ! map.contains( state.joinWithThreadId)  )
			{
				
				if(ParallizeFacade.ENABLE_LOGGING)
				{
					AgentLogCallback.log( "joinWithThreadId "+   threadId+ " " + +state.joinWithThreadId );
				}
				
				return true;
			}
			
			
			
		}
		
		return false;

	}

	public Decision getExisting(long threadId, Operation operation) {
		if (!map.contains(threadId)) {
			return null;
		}
		return map.get(threadId).loopDetection.getExisting(operation, size());
	}

	int activeThreadCount() {
		return map.size();
	}

	public int size() {
		return map.size();
	}

	boolean isSingleThreaded() {
		return map.size() < 2;
	}

	boolean removeThread(long threadId) {
		
		if( ! map.contains(threadId) )
		{
			AgentLogCallback.logError("not there " + threadId);
			
			return true;
		}
		
		ThreadState state = map.get(threadId);
		state.addedCount--;
		if (state.addedCount == 0) {
			int index = map.get(threadId).index;

			index2ThreadId.remove(index);
			map.remove(threadId);
			
			return true;
			
		}
		
		return false;
	}

	boolean addThread(long threadId, Thread thread) {
		ThreadState state = map.get(threadId);
		if (state == null) {
			index2ThreadId.put(maxIndex, threadId);
			ThreadState threadState = new ThreadState(maxIndex, thread);
			map.put(threadId, threadState);
			maxIndex++;
			
			return true;
			
		} else {
			state.addedCount++;
			
			return false;
		}
	}

	public void setDecision4Loop(long threadId, Operation operation, Decision decision) {
		if (!map.contains(threadId)) {
			return;
		}

		map.get(threadId).loopDetection.setDecision(operation, decision);

	}

	void setTimeout(long activeThreadId) {
		// TODO Auto-generated method stub

	}

	void after(long threadId, OperationTyp operation)  {
		
		if( ! map.contains(threadId))
		{
		
			AgentLogCallback.logThreadId2StateError(this);
			return;
		}
		
		
		
		if(operation instanceof ThreadJoin)
		{
			
			ThreadJoin threadJoin = (ThreadJoin)  operation;
			
			/*
			 * 	public int waitingThreadIndex;
	public int joinedThreadIndex;
	
			 */
			
			 if( startedThreadIds.contains(threadJoin.joinedThreadId) )
			 {
				 
				 ThreadState state = map.get(threadId);
				 
				 state.position++;
				 
				 int from =state.index;
				// state.atThreadJoin = true;
				 
				 int to = startedThreadIds.get(threadJoin.joinedThreadId);
				 
				 threadJoin.waitingThreadIndex = from;
				 threadJoin.joinedThreadIndex = to;
				 
				 
				 interleaveFacade.afterOperation(from,threadJoin);
			 }
		}
		else
		{
			ThreadState state = map.get(threadId);
			 state.position++;
			//	state.atThreadJoin = false;
				
				interleaveFacade.afterOperation(state.index, operation);
		}
		
	}

	
	void afterThreadStart(long startingThreadId, long startedThreadId) 
	{
		if (ParallizeFacade.ENABLE_LOGGING) {
			AgentLogCallback.log("{\"loopId\":0,\"runId\":0,\"threadId\":"
					+startingThreadId + ",\"actualOperation\":{\"jsonClass\":\"StartThread\",\"threadId\":" + startedThreadId +"}}");
		}
 
		
		startedThreadIds.put(startedThreadId,   map.get(startedThreadId).index);
		
		ThreadState state =   map.get(startingThreadId);
		state.position++;
		int startingIndex = state.index;
				
		interleaveFacade.afterThreadStart(startingIndex ,   map.get(startedThreadId).index );
		
		interleaveFacade.newThreadBegan( map.get(startedThreadId).index);
		
	//	interleaveFacade.after( map.get(startedThreadId).index  , new BeginWithThread());
		
		
	}

	


	 void lockOperation(long threadId, LockOperation operation) {
		 
		 if( ! map.contains(threadId))
			{
			
				AgentLogCallback.logThreadId2StateError(this);
				return;
			}
		 
		 
			interleaveFacade.lockOperation(map.get(threadId).index, operation);
		
	}


	 
	 

	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy