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

com.vmlens.trace.agent.bootstrap.interleave.normalized.RelationMap Maven / Gradle / Ivy

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

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import com.vmlens.trace.agent.bootstrap.interleave.operation.VolatileFieldAccess;
import com.vmlens.trace.agent.bootstrap.parallize.ParallizeFacade;
import com.vmlens.trace.agent.bootstrap.callback.AgentLogCallback;
import com.vmlens.trace.agent.bootstrap.interleave.MonitorPosition;
import com.vmlens.trace.agent.bootstrap.interleave.MonitorState;
import com.vmlens.trace.agent.bootstrap.interleave.actualAccess.Comparator4LockAccess;
import com.vmlens.trace.agent.bootstrap.interleave.operation.ThreadJoin;
import com.vmlens.trace.agent.bootstrap.interleave.operation.ThreadStarted;
import gnu.trove.map.hash.THashMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import gnu.trove.map.hash.TLongObjectHashMap;
import gnu.trove.map.hash.TObjectIntHashMap;
import gnu.trove.set.hash.TIntHashSet;
import gnu.trove.iterator.TIntObjectIterator;
import gnu.trove.iterator.TLongObjectIterator;
import gnu.trove.iterator.TObjectIntIterator;
import gnu.trove.list.linked.TLinkedList;

public class RelationMap {

	public final TIntObjectHashMap> volatileAccess = new TIntObjectHashMap>();
	public final TIntObjectHashMap> atomicAccess = new TIntObjectHashMap>();
	public final TIntObjectHashMap> monitorAccess = new TIntObjectHashMap>();
	
	public final TObjectIntHashMap  monitorKey2Count = new TObjectIntHashMap();
	
	public final TLinkedList tasks = new TLinkedList();
	
	public final TLinkedList callBackAccess = new TLinkedList();
	
	public final TLinkedList exclusiveLockExitAccess = new TLinkedList();
	public final TLinkedList sharedLockEnterAccess = new TLinkedList();
	
	public final TLinkedList startThread = new TLinkedList();
	public final TLinkedList joinThread = new TLinkedList();
	
	public final TLongObjectHashMap> volatileArrayAccess = new TLongObjectHashMap>();

	private final int[] maxPositionPerThread;
	
	private final MonitorState[][] threadIndex2Position2MonitorArray;
	
	
	
	

	public RelationMap(int[] maxPositionPerThread, MonitorState[][] threadIndex2Position2MonitorArray) {
		super();
		this.maxPositionPerThread = maxPositionPerThread;
		this.threadIndex2Position2MonitorArray = threadIndex2Position2MonitorArray;
	}

	public RelationList create() {
		
		TIntHashSet knownVolatileFields = new TIntHashSet();
		
		
		for( int i :  volatileAccess.keys() )
		{
			knownVolatileFields.add(i);
		}
		
		
		RelationList orderList = new RelationList(maxPositionPerThread,knownVolatileFields,threadIndex2Position2MonitorArray);




		addFromValueCollection(orderList, volatileAccess , "volatileAccess");
		
		addFromList(orderList, tasks , "tasks" );
		
		addFromList(orderList, callBackAccess , "callBackAccess" );
		addFromValueCollection(orderList, atomicAccess , "atomicAccess");
		
		addFromList(orderList, exclusiveLockExitAccess, "exclusiveLockExitAccess");
		addFromList(orderList, sharedLockEnterAccess, "sharedLockEnterAccess");
		
		addFromValueCollection(orderList, monitorAccess , "monitorAccess");

		addFromValueCollection(orderList, volatileArrayAccess);
		
		
		Iterator startIterator = startThread.iterator();
		
		while( startIterator.hasNext() )
		{
			PositionAndOperation current = startIterator.next();
			
			orderList.addStartRelation(  current.position , new Position( ((ThreadStarted) current.operation).startedThreadIndex , 0 )    );
				
		}
		
		Iterator joinIterator = joinThread.iterator();
		
		while( joinIterator.hasNext() )
		{
			PositionAndOperation current = joinIterator.next();
			
			orderList.addJoinRelation(  current.position ,  ((ThreadJoin) current.operation).joinedThreadIndex   );
			
		}
		
		
		
		

		return orderList;
	}

	//

	private void addFromValueCollection(RelationList orderList,TIntObjectHashMap> values, String name) {
		 TIntObjectIterator> it = values.iterator();

		while (it.hasNext()) {
			it.advance();
			
			
			
			addFromList(orderList, it.value() ,name + it.key());
		}

	}
	
	
	
	
	private void addFromValueCollection(RelationList orderList,TLongObjectHashMap> values) {
		 TLongObjectIterator> it = values.iterator();

		while (it.hasNext()) {
			it.advance();
			
			
			
			addFromList(orderList, it.value() , "volatile array " + it.key());
		}

	}
	
	
	
	
	

//	public void setMaxPositionPerThread(int[] maxPositionPerThread) {
//		this.maxPositionPerThread = maxPositionPerThread;
//	}

	private static void addFromList(RelationList orderList, TLinkedList accessList,String name) {
		
		
		int startSize = orderList.potentialOrderSize();
		
		PositionAndOperation[] posArray = (PositionAndOperation[]) accessList.toArray(new PositionAndOperation[0]);

		Arrays.sort( posArray , new Comparator4PositionAndOperation() );
		
		int startIndex = 0;

		while (startIndex < posArray.length) {
			int endIndex = 0;
			int currentThreadIndex = -1;

			for (endIndex = startIndex; endIndex < posArray.length; endIndex++) {
				int newIndex = posArray[endIndex].position.threadIndex;

				if (currentThreadIndex == -1) {
					currentThreadIndex = newIndex;
				} else if (currentThreadIndex != newIndex) {
					break;
				}
			}

			for (int i = startIndex; i < endIndex; i++) {
				for (int j = endIndex; j < posArray.length; j++) {
					PositionAndOperation a = posArray[i];
					PositionAndOperation b = posArray[j];
							
					if (a.operation.createsSyncRelation(b.operation)) {
						
						a.operation.addPotentialRelation(orderList , a.position,b.operation ,  b.position    );
						
		
					}
				}

			}

			startIndex = endIndex;

		}
		
		if(ParallizeFacade.ENABLE_LOGGING  )
		{
			AgentLogCallback.log( name +  " " + ( orderList.potentialOrderSize() -  startSize ));
		}
		

	}
	
	
	private static boolean isSameFor(TIntObjectHashMap>  myValues,TIntObjectHashMap> other )
	{
		if(  myValues.size() < other.size())
		{
			if(ParallizeFacade.ENABLE_LOGGING ||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING )
			{
				AgentLogCallback.log( "volatileAccess.size() smaller " + myValues.size() + " " + other.size());
			}
			
			
			return  false;
		}
		
		
		TIntObjectIterator> iterator = myValues.iterator();
		
		while(iterator.hasNext())
		{
			iterator.advance();
			
			if(   other.contains(iterator.key()) )
			{
				TLinkedList otherList = other.get(iterator.key());
				
				if( iterator.value().size() < otherList.size())
				{
					if(ParallizeFacade.ENABLE_LOGGING||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING)
					{
						AgentLogCallback.log( "  iterator.value().size smaller " +   iterator.value().size() + " " +  otherList.size() );
					}
					
					
					return false;
				}
				
				
			}
			else
			{
				if(ParallizeFacade.ENABLE_LOGGING||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING)
				{
					AgentLogCallback.log( "not there "  + iterator.key());
				}
				
				
				return false;
			}
			
			
			
		}
		
		return true;
		
	}
	
	

	public boolean isSame(RelationMap relationMap) {
	
		
		if( ! isSameFor( volatileAccess , relationMap.volatileAccess ) )
		{
			if(ParallizeFacade.ENABLE_LOGGING||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING)
			{
				AgentLogCallback.log( "not same volatileAccess " );
			}
			
			return false;
		}
		
		
		if( ! isSameFor( atomicAccess , relationMap.atomicAccess ) )
		{
			if(ParallizeFacade.ENABLE_LOGGING||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING)
			{
				AgentLogCallback.log( "not same atomicAccess " );
			}
			
			return false;
		}
		
		
	
		
		
		if(callBackAccess.size() iter = monitorKey2Count.iterator();
		
		while( iter.hasNext() )
		{
			iter.advance();
			
			if( iter.value() < relationMap.monitorKey2Count.get(iter.key()) )
			{
				
				if(ParallizeFacade.ENABLE_LOGGING ||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING )
				{
					AgentLogCallback.log( "monitorKey2Count count smaller " + iter.key() );
				}
				
				return  false;
				
			}
		}
		
		
		
		if(exclusiveLockExitAccess.size() < relationMap.exclusiveLockExitAccess.size()  )
		{
			return false;
		}
		
		
		if(startThread.size() < relationMap.startThread.size()  )
		{
			if(ParallizeFacade.ENABLE_LOGGING||  ParallizeFacade.ENABLE_PERFORMANCE_LOGGING)
			{
				AgentLogCallback.log( "startThread.size smaller " +startThread.size() + " " + relationMap.startThread.size());
			}
			
			
			return false;
		}
		
		return true;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy