--- /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
+