perfsrv/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp
changeset 51 98307c651589
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/perfsrv/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp	Mon Sep 06 15:00:47 2010 +0300
@@ -0,0 +1,228 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include "MemSpyDriverObjectIx.h"
+
+// System includes
+#include <kern_priv.h>
+//#include <dobject.h>
+
+//const TInt KObjectIxGranularity=8;
+const TInt KObjectIndexMask=0x7fff;
+//const TInt KObjectMaxIndex=0x7fff;
+const TInt KObjectInstanceShift=16;
+const TInt KObjectInstanceMask=0x3fff;
+//const TInt KObjectIxMaxHandles=0x8000;
+
+inline TInt index(TInt aHandle)
+	{return(aHandle&KObjectIndexMask);}
+inline TInt instance(TInt aHandle)
+	{return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
+inline TInt instanceLimit(TInt& aCount)
+	{return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
+inline TInt makeHandle(TInt aIndex, TInt aInstance)
+	{return((TInt)((aInstance<<KObjectInstanceShift)|aIndex));}
+
+enum TDObjectPanic
+	{
+	EObjObjectStillReferenced,
+	EObjNegativeAccessCount,
+	EObjRemoveObjectNotFound,
+	EObjRemoveContainerNotFound,
+	EObjRemoveBadHandle,
+	EObjFindBadHandle,
+	EObjFindIndexOutOfRange,
+	EDObjectConDestroyed,
+	EArrayIndexOutOfRange,
+	EObjInconsistent,
+	};
+
+inline void Panic(TDObjectPanic aPanic)
+	{ Kern::Fault("DOBJECT",aPanic); }
+	
+
+TBool MemSpyObjectIx::Find(DObject* aObj)
+	{
+	//Check preconditions(debug build only)
+	__ASSERT_CRITICAL;
+	__ASSERT_NO_FAST_MUTEX;
+
+	// I don't like the implementation of At() that was here before, it wasn't safe at all without HandleMutex. So I'm replacing it with a simpler
+	// version based on operator[] that only does what we need and does it safely.
+
+	TBool found = EFalse;
+	MemSpyObjectIx_HandleLookupLock();
+	const TInt count = Count();
+	for (TInt i = 0; i < count; i++)
+		{
+		if ((*this)[i] == aObj)
+			{
+			found = ETrue;
+			break;
+			}
+		}
+	MemSpyObjectIx_HandleLookupUnlock();
+	return found;
+	}
+
+#if MCL_ROBJECTIX_DUPLICATION
+
+#define asserta(x)	do { if (!(x)) { __crash(); } } while(0)
+
+RMemSpyObjectIx::RMemSpyObjectIx()
+  : iRWL(TSpinLock::EOrderGenericIrqLow3)
+    {
+    }
+
+
+/*
+void RMemSpyObjectIx::Wait()
+	{
+	Kern::MutexWait(*HandleMutex);
+	} // RObjectIx::Wait
+
+
+void RMemSpyObjectIx::Signal()
+	{
+	Kern::MutexSignal(*HandleMutex);
+	} // RObjectIx::Signal
+*/
+
+DObject* RMemSpyObjectIx::operator[](TInt aIndex)
+	{
+	DObject* obj = 0;
+	AcquireReadLock();
+	asserta(TUint(aIndex)<TUint(iCount));
+	SSlot* slot = iSlots + aIndex;
+	obj = Occupant(slot);
+	ReleaseReadLock();
+	return obj;
+	} // RObjectIx::operator[]
+
+
+#elif MCL_DOBJECTIX_DUPLICATION
+
+/*
+void DMemSpyObjectIx::Wait( DMemSpyObjectIx* aObjectIndex )
+	{
+//	Kern::MutexWait(*aObjectIndex->HandleMutex);
+	}
+
+void DMemSpyObjectIx::Signal( DMemSpyObjectIx* aObjectIndex )
+	{
+//	Kern::MutexSignal(*aObjectIndex->HandleMutex);
+	}
+*/
+
+/** Counts the number of times an object appears in this index.
+
+	@param	aObject	Object whose occurrences are to be counted.
+
+	@return	Number of times aObject appears in the index.
+
+    @pre    Calling thread must be in a critical section.
+    @pre    No fast mutex can be held.
+	@pre	Call in a thread context.
+	@pre	DObject::HandleMutex held
+ */
+TInt DMemSpyObjectIx::Count(DObject* aObject)
+	{
+	//Check preconditions(debug build only)
+	__ASSERT_CRITICAL;
+	__ASSERT_NO_FAST_MUTEX;
+
+	TInt c=0;
+	if (iCount)
+		{
+		SDObjectIxRec* pS=iObjects;
+		SDObjectIxRec* pE=pS+iCount;
+		do
+			{
+			if (pS->obj==aObject)
+				c++;
+			} while (++pS<pE);
+		}
+	return c;
+	}
+
+
+/**	Looks up an object in the index by handle.
+	
+	The object must be of a specified type (specified by container ID)
+
+	@param	aHandle		Handle to look up.
+	@param	aUniqueID	Unique ID (container ID) that object should have.
+	
+	@return	Pointer to object or NULL if handle invalid.
+
+	@pre	Call in a thread context.
+	@pre    System lock must be held.
+ */
+DObject* DMemSpyObjectIx::At(TInt aHandle, TInt aUniqueID)
+	{
+	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
+	TInt i=index(aHandle);
+	if (i>=iCount)
+		return(NULL);
+	SDObjectIxRec *pS=iObjects+i;
+	if (pS->str.instance!=instance(aHandle) || pS->str.uniqueID!=aUniqueID)
+		return(NULL);
+	return(pS->obj);
+	}
+
+
+/**	Looks up an object in the index by handle.
+
+	The object may be of any type.
+
+	@param	aHandle		Handle to look up.
+	
+	@return	Pointer to object or NULL if handle invalid.
+
+	@pre	Call in a thread context.
+	@pre    System lock must be held.
+ */
+DObject* DMemSpyObjectIx::At(TInt aHandle)
+	{
+	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
+	TInt i=index(aHandle);
+	if (i>=iCount)
+		return NULL;
+	SDObjectIxRec *pS=iObjects+i;
+	if (pS->str.instance!=instance(aHandle))
+		return NULL;
+	return pS->obj;
+	}
+
+/** Finds the object at a specific position in the index array.
+
+	@param	aIndex	Index into array.
+	
+	@return	Pointer to the object at that position (could be NULL).
+
+	@pre	Call in a thread context. 
+    @pre    System lock must be held.
+ */
+DObject* DMemSpyObjectIx::operator[](TInt aIndex)
+	{
+	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
+	__ASSERT_ALWAYS(aIndex>=0 && aIndex<iCount,Panic(EArrayIndexOutOfRange));
+	return iObjects[aIndex].obj;
+	}
+
+#endif
+