memspy/Driver/Kernel/Source/MemSpyDriverObjectIx.cpp
changeset 0 a03f92240627
child 20 ca8a1b6995f6
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyDriverObjectIx.h"
       
    19 
       
    20 // System includes
       
    21 #include <kern_priv.h>
       
    22 //#include <dobject.h>
       
    23 
       
    24 //const TInt KObjectIxGranularity=8;
       
    25 const TInt KObjectIndexMask=0x7fff;
       
    26 //const TInt KObjectMaxIndex=0x7fff;
       
    27 const TInt KObjectInstanceShift=16;
       
    28 const TInt KObjectInstanceMask=0x3fff;
       
    29 //const TInt KObjectIxMaxHandles=0x8000;
       
    30 
       
    31 inline TInt index(TInt aHandle)
       
    32 	{return(aHandle&KObjectIndexMask);}
       
    33 inline TInt instance(TInt aHandle)
       
    34 	{return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
       
    35 inline TInt instanceLimit(TInt& aCount)
       
    36 	{return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
       
    37 inline TInt makeHandle(TInt aIndex, TInt aInstance)
       
    38 	{return((TInt)((aInstance<<KObjectInstanceShift)|aIndex));}
       
    39 
       
    40 enum TDObjectPanic
       
    41 	{
       
    42 	EObjObjectStillReferenced,
       
    43 	EObjNegativeAccessCount,
       
    44 	EObjRemoveObjectNotFound,
       
    45 	EObjRemoveContainerNotFound,
       
    46 	EObjRemoveBadHandle,
       
    47 	EObjFindBadHandle,
       
    48 	EObjFindIndexOutOfRange,
       
    49 	EDObjectConDestroyed,
       
    50 	EArrayIndexOutOfRange,
       
    51 	EObjInconsistent,
       
    52 	};
       
    53 
       
    54 inline void Panic(TDObjectPanic aPanic)
       
    55 	{ Kern::Fault("DOBJECT",aPanic); }
       
    56 	
       
    57 
       
    58 #if MCL_ROBJECTIX_DUPLICATION
       
    59 
       
    60 #define asserta(x)	do { if (!(x)) { __crash(); } } while(0)
       
    61 
       
    62 RMemSpyObjectIx::RMemSpyObjectIx()
       
    63   : iRWL(TSpinLock::EOrderGenericIrqLow3)
       
    64     {
       
    65     }
       
    66 
       
    67 
       
    68 void RMemSpyObjectIx::Wait()
       
    69 	{
       
    70 //	Kern::MutexWait(*HandleMutex);
       
    71 	} // RObjectIx::Wait
       
    72 
       
    73 
       
    74 void RMemSpyObjectIx::Signal()
       
    75 	{
       
    76 //	Kern::MutexSignal(*HandleMutex);
       
    77 	} // RObjectIx::Signal
       
    78 
       
    79 
       
    80 DObject* RMemSpyObjectIx::operator[](TInt aIndex)
       
    81 	{
       
    82 	DObject* obj = 0;
       
    83 	AcquireReadLock();
       
    84 	asserta(TUint(aIndex)<TUint(iCount));
       
    85 	SSlot* slot = iSlots + aIndex;
       
    86 	obj = Occupant(slot);
       
    87 	ReleaseReadLock();
       
    88 	return obj;
       
    89 	} // RObjectIx::operator[]
       
    90 
       
    91 
       
    92 TInt RMemSpyObjectIx::At(DObject* aObj)
       
    93 	{
       
    94 	//Check preconditions(debug build only)
       
    95 	__ASSERT_CRITICAL;
       
    96 	__ASSERT_NO_FAST_MUTEX;
       
    97 	//__ASSERT_MUTEX(HandleMutex);
       
    98 
       
    99 	if (iState==ETerminated)
       
   100 		{
       
   101 		return KErrNotFound;
       
   102 		}
       
   103 
       
   104 	TInt h = KErrNotFound;
       
   105 	AcquireWriteLock();
       
   106 	iState = (TUint8)ESearching;		// enable monitoring of new handles
       
   107 	iModList.iMonitor.iObj = aObj;		// object to check for
       
   108 	iModList.iMonitor.iBoundary = 0;	// will change if aObj is added to a slot before this point
       
   109 	TInt pos = 0;
       
   110 	while (pos<iCount && iActiveCount)	// stop if index empty
       
   111 		{
       
   112 		TInt limit = pos + EMaxLockedIter;
       
   113 		if (limit>iCount)
       
   114 			{
       
   115 			limit = iCount;
       
   116 			}
       
   117 		while (pos<limit)
       
   118 			{
       
   119 			SSlot* slot = iSlots + pos;
       
   120 			if (Occupant(slot) == aObj)
       
   121 				{
       
   122 				// found it, finish
       
   123 				h = MakeHandle(pos, slot->iUsed.iAttr);
       
   124 				break;
       
   125 				}
       
   126 			pos++;
       
   127 			}
       
   128 		if (h>0)
       
   129 			{
       
   130 			break;	// found it, finish
       
   131 			}
       
   132 		iModList.iMonitor.iBoundary = pos;	// will change if aObj is added to a slot already checked
       
   133 		ReleaseWriteLock();	// let other threads in
       
   134 		AcquireWriteLock();
       
   135 		pos = iModList.iMonitor.iBoundary;	// next position to check
       
   136 		}
       
   137 	iState = (TUint8)ENormal;
       
   138 	ReleaseWriteLock();
       
   139 	return h;
       
   140 	} // RObjectIx::At
       
   141 
       
   142 
       
   143 
       
   144 
       
   145 
       
   146 
       
   147 #elif MCL_DOBJECTIX_DUPLICATION
       
   148 
       
   149 void DMemSpyObjectIx::Wait( DMemSpyObjectIx* /*aObjectIndex*/ )
       
   150 	{
       
   151 //	Kern::MutexWait(*aObjectIndex->HandleMutex);
       
   152 	}
       
   153 
       
   154 void DMemSpyObjectIx::Signal( DMemSpyObjectIx* /*aObjectIndex*/ )
       
   155 	{
       
   156 //	Kern::MutexSignal(*aObjectIndex->HandleMutex);
       
   157 	}
       
   158 
       
   159 
       
   160 /** Counts the number of times an object appears in this index.
       
   161 
       
   162 	@param	aObject	Object whose occurrences are to be counted.
       
   163 
       
   164 	@return	Number of times aObject appears in the index.
       
   165 
       
   166     @pre    Calling thread must be in a critical section.
       
   167     @pre    No fast mutex can be held.
       
   168 	@pre	Call in a thread context.
       
   169 	@pre	DObject::HandleMutex held
       
   170  */
       
   171 TInt DMemSpyObjectIx::Count(DObject* aObject)
       
   172 	{
       
   173 	//Check preconditions(debug build only)
       
   174 	__ASSERT_CRITICAL;
       
   175 	__ASSERT_NO_FAST_MUTEX;
       
   176 
       
   177 	TInt c=0;
       
   178 	if (iCount)
       
   179 		{
       
   180 		SDObjectIxRec* pS=iObjects;
       
   181 		SDObjectIxRec* pE=pS+iCount;
       
   182 		do
       
   183 			{
       
   184 			if (pS->obj==aObject)
       
   185 				c++;
       
   186 			} while (++pS<pE);
       
   187 		}
       
   188 	return c;
       
   189 	}
       
   190 
       
   191 
       
   192 /**	Looks up an object in the index by handle.
       
   193 	
       
   194 	The object must be of a specified type (specified by container ID)
       
   195 
       
   196 	@param	aHandle		Handle to look up.
       
   197 	@param	aUniqueID	Unique ID (container ID) that object should have.
       
   198 	
       
   199 	@return	Pointer to object or NULL if handle invalid.
       
   200 
       
   201 	@pre	Call in a thread context.
       
   202 	@pre    System lock must be held.
       
   203  */
       
   204 DObject* DMemSpyObjectIx::At(TInt aHandle, TInt aUniqueID)
       
   205 	{
       
   206 	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
       
   207 	TInt i=index(aHandle);
       
   208 	if (i>=iCount)
       
   209 		return(NULL);
       
   210 	SDObjectIxRec *pS=iObjects+i;
       
   211 	if (pS->str.instance!=instance(aHandle) || pS->str.uniqueID!=aUniqueID)
       
   212 		return(NULL);
       
   213 	return(pS->obj);
       
   214 	}
       
   215 
       
   216 
       
   217 /**	Looks up an object in the index by handle.
       
   218 
       
   219 	The object may be of any type.
       
   220 
       
   221 	@param	aHandle		Handle to look up.
       
   222 	
       
   223 	@return	Pointer to object or NULL if handle invalid.
       
   224 
       
   225 	@pre	Call in a thread context.
       
   226 	@pre    System lock must be held.
       
   227  */
       
   228 DObject* DMemSpyObjectIx::At(TInt aHandle)
       
   229 	{
       
   230 	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
       
   231 	TInt i=index(aHandle);
       
   232 	if (i>=iCount)
       
   233 		return NULL;
       
   234 	SDObjectIxRec *pS=iObjects+i;
       
   235 	if (pS->str.instance!=instance(aHandle))
       
   236 		return NULL;
       
   237 	return pS->obj;
       
   238 	}
       
   239 
       
   240 
       
   241 
       
   242 /**	Looks up an object in the index by object pointer.
       
   243 
       
   244 	Returns a handle to the object.
       
   245 
       
   246 	@param	aObj	Pointer to the object to look up.
       
   247 	
       
   248 	@return	Handle to object (always >0);
       
   249 	        KErrNotFound, if object not present in index.
       
   250 
       
   251     @pre    Calling thread must be in a critical section.
       
   252     @pre    No fast mutex can be held.
       
   253 	@pre	Call in a thread context.
       
   254 	@pre	DObject::HandleMutex held.
       
   255  */
       
   256 TInt DMemSpyObjectIx::At(DObject* aObj)
       
   257 	{
       
   258 	//Check preconditions(debug build only)
       
   259 	__ASSERT_CRITICAL;
       
   260 	__ASSERT_NO_FAST_MUTEX;
       
   261 
       
   262 	if (iCount)
       
   263 		{
       
   264 		SDObjectIxRec* pS=iObjects;
       
   265 		SDObjectIxRec* pE=pS+iCount;
       
   266 		TInt i=0;
       
   267 		while(pS<pE && pS->obj!=aObj)
       
   268 			pS++, i++;
       
   269 		if (pS<pE)
       
   270 			return(makeHandle(i,pS->str.instance));
       
   271 		}
       
   272 	return KErrNotFound;
       
   273 	}
       
   274 
       
   275 
       
   276 /** Finds the object at a specific position in the index array.
       
   277 
       
   278 	@param	aIndex	Index into array.
       
   279 	
       
   280 	@return	Pointer to the object at that position (could be NULL).
       
   281 
       
   282 	@pre	Call in a thread context. 
       
   283     @pre    System lock must be held.
       
   284  */
       
   285 DObject* DMemSpyObjectIx::operator[](TInt aIndex)
       
   286 	{
       
   287 	__ASSERT_SYSTEM_LOCK; //Check preconditions (debug build only)
       
   288 	__ASSERT_ALWAYS(aIndex>=0 && aIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   289 	return iObjects[aIndex].obj;
       
   290 	}
       
   291 
       
   292 #endif
       
   293