--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Kernel/Include/MemSpyDriverObjectIx.h Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,234 @@
+/*
+* 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:
+*
+*/
+
+#ifndef MEMSPYDRIVEROBJECTIX_H
+#define MEMSPYDRIVEROBJECTIX_H
+
+// System includes
+#include <kernel.h>
+#include <kern_priv.h>
+
+#if MCL_ROBJECTIX_DUPLICATION
+
+class RMemSpyObjectIx
+ {
+public:
+ enum {ENoClose=KHandleNoClose,ELocalHandle=0x40000000};
+ enum {EReserved=0x80000000u, EAttributeMask=0xfffu};
+ enum {EMinSlots=8, EMaxSlots=32768};
+public:
+ enum {ENumFreeQ=6, EModCount=4, EBitMapSize=128, EMaxLockedIter=8};
+private:
+ // queue numbers
+ enum {EQFree=-6, EQAltFree=-5, EQTempFree=-4, EQRsvd=-3, EQAltRsvd=-2, EQTempRsvd=-1};
+ // iObjR, iRsvd fields
+ enum {EObjROccupied=4u, EObjRObjMask=0xfffffffcu, EObjRRsvd=1u};
+ // states
+ enum {ENormal=0u, ETidying=1u, EFindingLast=2u, ECounting=3u, ESearching=4u, ETerminated=5u};
+ struct SSlotQLink
+ {
+ TInt16 iNext; // pointer to next free slot, -n if no next
+ TInt16 iPrev; // pointer to previous free slot, -n if no previous
+ };
+ struct SFreeSlot : public SSlotQLink
+ {
+ TUint32 iRsvd; // 0 for normal, 1 for reserved slot
+ };
+ struct SUsedSlot
+ {
+ TUint32 iAttr; // bits 0-13 = instance (nonzero), bits 14-19 = object type, bits 20-31 = handle attributes
+ TUint32 iObjR; // pointer to object (nonzero), bit 0=1 if reserved slot
+ };
+ union SSlot
+ {
+ SFreeSlot iFree;
+ SUsedSlot iUsed;
+ };
+ struct SMonitorObj
+ {
+ DObject* iObj;
+ TInt iBoundary;
+ TInt iResult;
+ };
+ union SModList
+ {
+ TInt16 iIndex[EModCount];
+ TUint32 iBitMap[EBitMapSize/32];
+ SMonitorObj iMonitor;
+ };
+private:
+#ifdef __HANDLES_USE_RW_SPIN_LOCK__
+// Beginning of support for spinlock-only protection (i.e. not requiring the system lock)
+// for access to handles. Requires changes everywhere objects returned from handles are
+// used, and some additional work in the handle lookup code in cutils.cia.
+#error "spinlocks for handle lookup not supported"
+ inline void AcquireReadLock()
+ { __SPIN_LOCK_IRQ_R(iRWL); }
+ inline void ReleaseReadLock()
+ { __SPIN_UNLOCK_IRQ_R(iRWL); }
+ inline void AcquireWriteLock()
+ { __SPIN_LOCK_IRQ_W(iRWL); }
+ inline void ReleaseWriteLock()
+ { __SPIN_UNLOCK_IRQ_W(iRWL); }
+#else
+ /* Places which use a read lock would already have the system lock held */
+ inline void AcquireReadLock()
+ { __ASSERT_SYSTEM_LOCK; }
+ inline void ReleaseReadLock()
+ { }
+ inline void AcquireWriteLock()
+ { NKern::LockSystem(); }
+ inline void ReleaseWriteLock()
+ { NKern::UnlockSystem(); }
+#endif
+private:
+ static inline DObject* Occupant(SSlot* aS)
+ { return (DObject*)(aS->iUsed.iObjR & EObjRObjMask); }
+ static inline TBool IsReserved(SSlot* aS)
+ { return aS->iUsed.iObjR & EObjRRsvd; }
+ static inline TBool IsFreeReserved(SSlot* aS)
+ { return (aS->iUsed.iObjR & EObjRRsvd) && (aS->iUsed.iObjR<EObjROccupied); }
+ /*
+ void Empty(TInt aQueue);
+ SSlot* Dequeue(TInt aSlotIndex);
+ void AddHead(TInt aQueue, TInt aSlotIndex);
+ void AddTail(TInt aQueue, TInt aSlotIndex);
+ void AddBefore(TInt aBase, TInt aSlotIndex);
+ void AddAfter(TInt aBase, TInt aSlotIndex);
+ void AppendList(TInt aSrcQ, TInt aDestQ);
+ void PrependList(TInt aSrcQ, TInt aDestQ);
+ TInt DoAdd(DObject* aObj, TUint32 aAttr, SSlot* aSlot); // add aObj using an existing slot (don't grow)
+ TInt DoRemove(TInt aHandle, DObject*& aObject, TUint32& aAttr); // remove a handle (don't shrink)
+ void MarkModified(TInt aSlotIndex);
+ static TUint32 GetNextInstanceValue();
+ TInt UnReserveSlots(TInt aCount, TBool aAmortize);
+ TInt ReserveSlots(TInt aCount);
+ TInt Grow(TInt aReserve, SSlot* aSlotData);
+ void TidyAndCompact();
+ inline SSlotQLink* Link(TInt aIndex)
+ { return (aIndex<0) ? (iFreeQ+ENumFreeQ+aIndex) : &(iSlots+aIndex)->iFree; }
+ */
+public:
+ // common operations
+ RMemSpyObjectIx();
+
+ static void Wait();
+ static void Signal();
+
+ inline TInt Count()
+ { return iCount; }
+ inline TInt ActiveCount()
+ { return iActiveCount; }
+
+public:
+ // uncommon operations
+ DObject* operator[](TInt aIndex);
+ TInt At(DObject* aObject);
+
+private:
+ TRWSpinLock iRWL;
+ TInt iAllocated; // Max entries before realloc needed
+ volatile TInt iCount; // Points to at least 1 above the highest occupied slot or unoccupied reserved slot
+ volatile TInt iActiveCount; // Number of occupied entries in the index (reserved or normal)
+ volatile TInt iReservedFree; // Number of unoccupied reserved slots
+ volatile TInt iReservedTotal; // Number of reserved slots (occupied or unoccupied)
+ volatile TInt iReservedFreeHWM; // Points to at least 1 above the last unoccupied reserved slot
+ SSlotQLink iFreeQ[ENumFreeQ]; // queues of free slots
+ SSlot* iSlots; // array of handle slots
+ TInt iAmortize; // Number of handle removals before we see if we can shrink
+ TUint8 iState;
+ TUint8 iModCount; // 255=not in use, 0...EModCount->use iModList.iIndex[], EModCount+1->use iModList.iBitMap
+ TUint8 iModListShift;
+ TUint8 iSpare1;
+ SModList iModList; // Entries modified while array moving
+
+public:
+ static volatile TUint32 NextInstance;
+ static DMutex* HandleMutex;
+ };
+
+#elif MCL_DOBJECTIX_DUPLICATION
+
+class DMemSpyObjectIx : public DBase
+ {
+public:
+ inline DMemSpyObjectIx() { }
+
+public:
+ DObject* At(TInt aHandle,TInt aUniqueID);
+ DObject* At(TInt aHandle);
+ TInt At(DObject* aObject);
+ TInt Count(DObject* aObject);
+ DObject* operator[](TInt aIndex);
+ static void Wait( DMemSpyObjectIx* aObjectIndex );
+ static void Signal( DMemSpyObjectIx* aObjectIndex );
+ inline TInt Count();
+ inline TInt ActiveCount();
+
+private:
+ TInt iNextInstance;
+ TInt iAllocated; // Max entries before realloc needed
+ TInt iCount; // Points to at least 1 above the highest active index
+ TInt iActiveCount; // Number of actual entries in the index
+ SDObjectIxRec* iObjects;
+ TAny* iPtr;
+ TInt iFree; // The index of the first free slot or -1.
+ TInt iUpdateDisabled; // If >0, disables: iCount update, reorder of the free list and memory shrinking.
+
+public:
+ static DMutex* HandleMutex;
+ };
+
+inline TInt DMemSpyObjectIx::Count()
+ {return iCount;}
+
+inline TInt DMemSpyObjectIx::ActiveCount()
+ {return iActiveCount;}
+
+#endif
+
+
+
+#if MCL_ROBJECTIX_DUPLICATION
+
+ #define MemSpyObjectIx RMemSpyObjectIx
+ #define MemSpyObjectIx_Wait( IX ) RMemSpyObjectIx::Wait()
+ #define MemSpyObjectIx_Signal( IX ) RMemSpyObjectIx::Signal()
+ #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( &DTHREAD.iHandles )
+ #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( &DPROCESS.iHandles )
+
+#elif MCL_DOBJECTIX_DUPLICATION
+
+ #define MemSpyObjectIx DMemSpyObjectIx
+ #define MemSpyObjectIx_Wait( IX ) DMemSpyObjectIx::Wait( IX )
+ #define MemSpyObjectIx_Signal( IX ) DMemSpyObjectIx::Signal( IX )
+ #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
+ #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles )
+
+#else
+
+ #define MemSpyObjectIx DObjectIx
+ #define MemSpyObjectIx_Wait( IX )
+ #define MemSpyObjectIx_Signal( IX )
+ #define MemSpyObjectIx_IsValid_Thread( DTHREAD ) ( DTHREAD.iHandles != NULL )
+ #define MemSpyObjectIx_IsValid_Process( DPROCESS ) ( DPROCESS.iHandles != NULL )
+ #define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
+ #define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles )
+
+#endif
+
+#endif