51
|
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 |
#ifndef MEMSPYDRIVEROBJECTIX_H
|
|
19 |
#define MEMSPYDRIVEROBJECTIX_H
|
|
20 |
|
|
21 |
// System includes
|
|
22 |
#include <kernel.h>
|
|
23 |
#include <kern_priv.h>
|
|
24 |
|
|
25 |
#if MCL_ROBJECTIX_DUPLICATION
|
|
26 |
|
|
27 |
class RMemSpyObjectIx
|
|
28 |
{
|
|
29 |
public:
|
|
30 |
enum {ENoClose=KHandleNoClose,ELocalHandle=0x40000000};
|
|
31 |
enum {EReserved=0x80000000u, EAttributeMask=0xfffu};
|
|
32 |
enum {EMinSlots=8, EMaxSlots=32768};
|
|
33 |
public:
|
|
34 |
enum {ENumFreeQ=6, EModCount=4, EBitMapSize=128, EMaxLockedIter=8};
|
|
35 |
private:
|
|
36 |
// queue numbers
|
|
37 |
enum {EQFree=-6, EQAltFree=-5, EQTempFree=-4, EQRsvd=-3, EQAltRsvd=-2, EQTempRsvd=-1};
|
|
38 |
// iObjR, iRsvd fields
|
|
39 |
enum {EObjROccupied=4u, EObjRObjMask=0xfffffffcu, EObjRRsvd=1u};
|
|
40 |
// states
|
|
41 |
enum {ENormal=0u, ETidying=1u, EFindingLast=2u, ECounting=3u, ESearching=4u, ETerminated=5u};
|
|
42 |
struct SSlotQLink
|
|
43 |
{
|
|
44 |
TInt16 iNext; // pointer to next free slot, -n if no next
|
|
45 |
TInt16 iPrev; // pointer to previous free slot, -n if no previous
|
|
46 |
};
|
|
47 |
struct SFreeSlot : public SSlotQLink
|
|
48 |
{
|
|
49 |
TUint32 iRsvd; // 0 for normal, 1 for reserved slot
|
|
50 |
};
|
|
51 |
struct SUsedSlot
|
|
52 |
{
|
|
53 |
TUint32 iAttr; // bits 0-13 = instance (nonzero), bits 14-19 = object type, bits 20-31 = handle attributes
|
|
54 |
TUint32 iObjR; // pointer to object (nonzero), bit 0=1 if reserved slot
|
|
55 |
};
|
|
56 |
union SSlot
|
|
57 |
{
|
|
58 |
SFreeSlot iFree;
|
|
59 |
SUsedSlot iUsed;
|
|
60 |
};
|
|
61 |
struct SMonitorObj
|
|
62 |
{
|
|
63 |
DObject* iObj;
|
|
64 |
TInt iBoundary;
|
|
65 |
TInt iResult;
|
|
66 |
};
|
|
67 |
union SModList
|
|
68 |
{
|
|
69 |
TInt16 iIndex[EModCount];
|
|
70 |
TUint32 iBitMap[EBitMapSize/32];
|
|
71 |
SMonitorObj iMonitor;
|
|
72 |
};
|
|
73 |
private:
|
|
74 |
#ifdef __HANDLES_USE_RW_SPIN_LOCK__
|
|
75 |
// Beginning of support for spinlock-only protection (i.e. not requiring the system lock)
|
|
76 |
// for access to handles. Requires changes everywhere objects returned from handles are
|
|
77 |
// used, and some additional work in the handle lookup code in cutils.cia.
|
|
78 |
#error "spinlocks for handle lookup not supported"
|
|
79 |
inline void AcquireReadLock()
|
|
80 |
{ __SPIN_LOCK_IRQ_R(iRWL); }
|
|
81 |
inline void ReleaseReadLock()
|
|
82 |
{ __SPIN_UNLOCK_IRQ_R(iRWL); }
|
|
83 |
inline void AcquireWriteLock()
|
|
84 |
{ __SPIN_LOCK_IRQ_W(iRWL); }
|
|
85 |
inline void ReleaseWriteLock()
|
|
86 |
{ __SPIN_UNLOCK_IRQ_W(iRWL); }
|
|
87 |
#else
|
|
88 |
/* Places which use a read lock would already have the system lock held */
|
|
89 |
inline void AcquireReadLock()
|
|
90 |
{ __ASSERT_SYSTEM_LOCK; }
|
|
91 |
inline void ReleaseReadLock()
|
|
92 |
{ }
|
|
93 |
inline void AcquireWriteLock()
|
|
94 |
{ NKern::LockSystem(); }
|
|
95 |
inline void ReleaseWriteLock()
|
|
96 |
{ NKern::UnlockSystem(); }
|
|
97 |
#endif
|
|
98 |
private:
|
|
99 |
static inline DObject* Occupant(SSlot* aS)
|
|
100 |
{ return (DObject*)(aS->iUsed.iObjR & EObjRObjMask); }
|
|
101 |
static inline TBool IsReserved(SSlot* aS)
|
|
102 |
{ return aS->iUsed.iObjR & EObjRRsvd; }
|
|
103 |
static inline TBool IsFreeReserved(SSlot* aS)
|
|
104 |
{ return (aS->iUsed.iObjR & EObjRRsvd) && (aS->iUsed.iObjR<EObjROccupied); }
|
|
105 |
/*
|
|
106 |
void Empty(TInt aQueue);
|
|
107 |
SSlot* Dequeue(TInt aSlotIndex);
|
|
108 |
void AddHead(TInt aQueue, TInt aSlotIndex);
|
|
109 |
void AddTail(TInt aQueue, TInt aSlotIndex);
|
|
110 |
void AddBefore(TInt aBase, TInt aSlotIndex);
|
|
111 |
void AddAfter(TInt aBase, TInt aSlotIndex);
|
|
112 |
void AppendList(TInt aSrcQ, TInt aDestQ);
|
|
113 |
void PrependList(TInt aSrcQ, TInt aDestQ);
|
|
114 |
TInt DoAdd(DObject* aObj, TUint32 aAttr, SSlot* aSlot); // add aObj using an existing slot (don't grow)
|
|
115 |
TInt DoRemove(TInt aHandle, DObject*& aObject, TUint32& aAttr); // remove a handle (don't shrink)
|
|
116 |
void MarkModified(TInt aSlotIndex);
|
|
117 |
static TUint32 GetNextInstanceValue();
|
|
118 |
TInt UnReserveSlots(TInt aCount, TBool aAmortize);
|
|
119 |
TInt ReserveSlots(TInt aCount);
|
|
120 |
TInt Grow(TInt aReserve, SSlot* aSlotData);
|
|
121 |
void TidyAndCompact();
|
|
122 |
inline SSlotQLink* Link(TInt aIndex)
|
|
123 |
{ return (aIndex<0) ? (iFreeQ+ENumFreeQ+aIndex) : &(iSlots+aIndex)->iFree; }
|
|
124 |
*/
|
|
125 |
public:
|
|
126 |
// common operations
|
|
127 |
RMemSpyObjectIx();
|
|
128 |
|
|
129 |
//static void Wait();
|
|
130 |
//static void Signal();
|
|
131 |
|
|
132 |
inline TInt Count()
|
|
133 |
{ return iCount; }
|
|
134 |
inline TInt ActiveCount()
|
|
135 |
{ return iActiveCount; }
|
|
136 |
|
|
137 |
public:
|
|
138 |
// uncommon operations
|
|
139 |
DObject* operator[](TInt aIndex);
|
|
140 |
TBool Find(DObject* aObject);
|
|
141 |
|
|
142 |
private:
|
|
143 |
TRWSpinLock iRWL;
|
|
144 |
TInt iAllocated; // Max entries before realloc needed
|
|
145 |
volatile TInt iCount; // Points to at least 1 above the highest occupied slot or unoccupied reserved slot
|
|
146 |
volatile TInt iActiveCount; // Number of occupied entries in the index (reserved or normal)
|
|
147 |
volatile TInt iReservedFree; // Number of unoccupied reserved slots
|
|
148 |
volatile TInt iReservedTotal; // Number of reserved slots (occupied or unoccupied)
|
|
149 |
volatile TInt iReservedFreeHWM; // Points to at least 1 above the last unoccupied reserved slot
|
|
150 |
SSlotQLink iFreeQ[ENumFreeQ]; // queues of free slots
|
|
151 |
SSlot* iSlots; // array of handle slots
|
|
152 |
TInt iAmortize; // Number of handle removals before we see if we can shrink
|
|
153 |
TUint8 iState;
|
|
154 |
TUint8 iModCount; // 255=not in use, 0...EModCount->use iModList.iIndex[], EModCount+1->use iModList.iBitMap
|
|
155 |
TUint8 iModListShift;
|
|
156 |
TUint8 iSpare1;
|
|
157 |
SModList iModList; // Entries modified while array moving
|
|
158 |
|
|
159 |
public:
|
|
160 |
static volatile TUint32 NextInstance;
|
|
161 |
static DMutex* HandleMutex;
|
|
162 |
};
|
|
163 |
|
|
164 |
#elif MCL_DOBJECTIX_DUPLICATION
|
|
165 |
|
|
166 |
class DMemSpyObjectIx : public DBase
|
|
167 |
{
|
|
168 |
public:
|
|
169 |
inline DMemSpyObjectIx() { }
|
|
170 |
|
|
171 |
public:
|
|
172 |
DObject* At(TInt aHandle,TInt aUniqueID);
|
|
173 |
DObject* At(TInt aHandle);
|
|
174 |
TBool Find(DObject* aObject);
|
|
175 |
TInt Count(DObject* aObject);
|
|
176 |
DObject* operator[](TInt aIndex);
|
|
177 |
//static void Wait( DMemSpyObjectIx* aObjectIndex );
|
|
178 |
//static void Signal( DMemSpyObjectIx* aObjectIndex );
|
|
179 |
inline TInt Count();
|
|
180 |
inline TInt ActiveCount();
|
|
181 |
|
|
182 |
private:
|
|
183 |
TInt iNextInstance;
|
|
184 |
TInt iAllocated; // Max entries before realloc needed
|
|
185 |
TInt iCount; // Points to at least 1 above the highest active index
|
|
186 |
TInt iActiveCount; // Number of actual entries in the index
|
|
187 |
SDObjectIxRec* iObjects;
|
|
188 |
TAny* iPtr;
|
|
189 |
TInt iFree; // The index of the first free slot or -1.
|
|
190 |
TInt iUpdateDisabled; // If >0, disables: iCount update, reorder of the free list and memory shrinking.
|
|
191 |
|
|
192 |
public:
|
|
193 |
static DMutex* HandleMutex;
|
|
194 |
};
|
|
195 |
|
|
196 |
inline TInt DMemSpyObjectIx::Count()
|
|
197 |
{return iCount;}
|
|
198 |
|
|
199 |
inline TInt DMemSpyObjectIx::ActiveCount()
|
|
200 |
{return iActiveCount;}
|
|
201 |
|
|
202 |
#endif
|
|
203 |
|
|
204 |
|
|
205 |
|
|
206 |
#if MCL_ROBJECTIX_DUPLICATION
|
|
207 |
|
|
208 |
#define MemSpyObjectIx RMemSpyObjectIx
|
|
209 |
//#define MemSpyObjectIx_Wait( IX ) RMemSpyObjectIx::Wait()
|
|
210 |
//#define MemSpyObjectIx_Signal( IX ) RMemSpyObjectIx::Signal()
|
|
211 |
#define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( &DTHREAD.iHandles )
|
|
212 |
#define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( &DPROCESS.iHandles )
|
|
213 |
|
|
214 |
#elif MCL_DOBJECTIX_DUPLICATION
|
|
215 |
|
|
216 |
#define MemSpyObjectIx DMemSpyObjectIx
|
|
217 |
//#define MemSpyObjectIx_Wait( IX ) DMemSpyObjectIx::Wait( IX )
|
|
218 |
//#define MemSpyObjectIx_Signal( IX ) DMemSpyObjectIx::Signal( IX )
|
|
219 |
#define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
|
|
220 |
#define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles )
|
|
221 |
|
|
222 |
#else
|
|
223 |
|
|
224 |
#define MemSpyObjectIx DObjectIx
|
|
225 |
//#define MemSpyObjectIx_Wait( IX )
|
|
226 |
//#define MemSpyObjectIx_Signal( IX )
|
|
227 |
#define MemSpyObjectIx_IsValid_Thread( DTHREAD ) ( DTHREAD.iHandles != NULL )
|
|
228 |
#define MemSpyObjectIx_IsValid_Process( DPROCESS ) ( DPROCESS.iHandles != NULL )
|
|
229 |
#define MemSpyObjectIx_GetHandlePointer_Thread( DTHREAD ) reinterpret_cast< MemSpyObjectIx* >( DTHREAD.iHandles )
|
|
230 |
#define MemSpyObjectIx_GetHandlePointer_Process( DPROCESS ) reinterpret_cast< MemSpyObjectIx* >( DPROCESS.iHandles )
|
|
231 |
|
|
232 |
#endif
|
|
233 |
|
|
234 |
#define MemSpyObjectIx_HandleLookupLock() NKern::LockSystem()
|
|
235 |
#define MemSpyObjectIx_HandleLookupUnlock() NKern::UnlockSystem()
|
|
236 |
|
|
237 |
#endif
|