--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,293 @@
+/*
+* 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); }
+
+
+#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[]
+
+
+TInt RMemSpyObjectIx::At(DObject* aObj)
+ {
+ //Check preconditions(debug build only)
+ __ASSERT_CRITICAL;
+ __ASSERT_NO_FAST_MUTEX;
+ //__ASSERT_MUTEX(HandleMutex);
+
+ if (iState==ETerminated)
+ {
+ return KErrNotFound;
+ }
+
+ TInt h = KErrNotFound;
+ AcquireWriteLock();
+ iState = (TUint8)ESearching; // enable monitoring of new handles
+ iModList.iMonitor.iObj = aObj; // object to check for
+ iModList.iMonitor.iBoundary = 0; // will change if aObj is added to a slot before this point
+ TInt pos = 0;
+ while (pos<iCount && iActiveCount) // stop if index empty
+ {
+ TInt limit = pos + EMaxLockedIter;
+ if (limit>iCount)
+ {
+ limit = iCount;
+ }
+ while (pos<limit)
+ {
+ SSlot* slot = iSlots + pos;
+ if (Occupant(slot) == aObj)
+ {
+ // found it, finish
+ h = MakeHandle(pos, slot->iUsed.iAttr);
+ break;
+ }
+ pos++;
+ }
+ if (h>0)
+ {
+ break; // found it, finish
+ }
+ iModList.iMonitor.iBoundary = pos; // will change if aObj is added to a slot already checked
+ ReleaseWriteLock(); // let other threads in
+ AcquireWriteLock();
+ pos = iModList.iMonitor.iBoundary; // next position to check
+ }
+ iState = (TUint8)ENormal;
+ ReleaseWriteLock();
+ return h;
+ } // RObjectIx::At
+
+
+
+
+
+
+#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;
+ }
+
+
+
+/** Looks up an object in the index by object pointer.
+
+ Returns a handle to the object.
+
+ @param aObj Pointer to the object to look up.
+
+ @return Handle to object (always >0);
+ KErrNotFound, if object not present in 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::At(DObject* aObj)
+ {
+ //Check preconditions(debug build only)
+ __ASSERT_CRITICAL;
+ __ASSERT_NO_FAST_MUTEX;
+
+ if (iCount)
+ {
+ SDObjectIxRec* pS=iObjects;
+ SDObjectIxRec* pE=pS+iCount;
+ TInt i=0;
+ while(pS<pE && pS->obj!=aObj)
+ pS++, i++;
+ if (pS<pE)
+ return(makeHandle(i,pS->str.instance));
+ }
+ return KErrNotFound;
+ }
+
+
+/** 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
+