libraries/memoryaccess/dobject.h
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // dobject.h
       
     2 // 
       
     3 // Copyright (c) 1998 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "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 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 /** 
       
    14 @file
       
    15 @internalTechnology
       
    16 */
       
    17 
       
    18 #ifndef __DOBJECT_H__
       
    19 #define __DOBJECT_H__
       
    20 
       
    21 #ifdef _DEBUG
       
    22 // In DEBUG builds use linear growth by 1 to aid kernel heap checking
       
    23 #else
       
    24 const TInt KObjectConMinSize=8;
       
    25 #endif
       
    26 const TInt KObjectIxGranularity=8;
       
    27 const TInt KObjectIndexMask=0x7fff;
       
    28 const TInt KObjectMaxIndex=0x7fff;
       
    29 const TInt KObjectInstanceShift=16;
       
    30 const TInt KObjectInstanceMask=0x3fff;
       
    31 const TInt KObjectIxMaxHandles=0x8000;
       
    32 
       
    33 inline TInt index(TInt aHandle)
       
    34 	{return(aHandle&KObjectIndexMask);}
       
    35 inline TInt instance(TInt aHandle)
       
    36 	{return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
       
    37 inline TInt instanceLimit(TInt& aCount)
       
    38 	{return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
       
    39 inline TInt makeHandle(TInt aIndex, TInt aInstance)
       
    40 	{return((TInt)((aInstance<<KObjectInstanceShift)|aIndex));}
       
    41 
       
    42 enum TDObjectPanic
       
    43 	{
       
    44 	EObjObjectStillReferenced,
       
    45 	EObjNegativeAccessCount,
       
    46 	EObjRemoveObjectNotFound,
       
    47 	EObjRemoveContainerNotFound,
       
    48 	EObjRemoveBadHandle,
       
    49 	EObjFindBadHandle,
       
    50 	EObjFindIndexOutOfRange,
       
    51 	EDObjectConDestroyed,
       
    52 	EArrayIndexOutOfRange,
       
    53 	EObjInconsistent,
       
    54 	};
       
    55 
       
    56 inline void Panic(TDObjectPanic aPanic)
       
    57 	{ Kern::Fault("DOBJECT",aPanic); }
       
    58 
       
    59 
       
    60 //BEGIN TOMSCI
       
    61 // This is needed because on 9.1 the DObjectIx header is defined as IMPORT_C
       
    62 #undef IMPORT_C
       
    63 #define IMPORT_C
       
    64 #define DObjectIx DObjectIxNinePointTwoHack // So that we're not redefining DObjectIx
       
    65 
       
    66 NONSHARABLE_CLASS(DObjectIx) : public DBase
       
    67 	{
       
    68 public:
       
    69 	enum {ENoClose=KHandleNoClose,ELocalHandle=0x40000000};
       
    70 public:
       
    71 	IMPORT_C static DObjectIx* New(TAny* aPtr);
       
    72 	IMPORT_C ~DObjectIx();
       
    73 	IMPORT_C TInt Add(DObject* aObj, TInt& aHandle);
       
    74 	IMPORT_C TInt Remove(TInt aHandle, DObject*& aObject, TAny*& aPtr);
       
    75 	IMPORT_C DObject* At(TInt aHandle,TInt aUniqueID);
       
    76 	IMPORT_C DObject* At(TInt aHandle);
       
    77 	IMPORT_C TInt At(DObject* aObject);
       
    78 	IMPORT_C TInt Count(DObject* aObject);
       
    79 	IMPORT_C DObject* operator[](TInt aIndex);
       
    80 	TInt LastHandle();
       
    81 	static void Wait();
       
    82 	static void Signal();
       
    83 	inline TInt Count();
       
    84 	inline TInt ActiveCount();
       
    85 protected:
       
    86 	IMPORT_C DObjectIx(TAny* aPtr);
       
    87 private:
       
    88 	void UpdateState();
       
    89 private:
       
    90 	TInt iNextInstance;
       
    91 	TInt iAllocated;		// Max entries before realloc needed
       
    92 	TInt iCount;			// Points to at least 1 above the highest active index
       
    93 	TInt iActiveCount;		// Number of actual entries in the index
       
    94 	SDObjectIxRec* iObjects;
       
    95 	TAny* iPtr;
       
    96 	TInt iFree;				// The index of the first free slot or -1.
       
    97 	TInt iUpdateDisabled;   // If >0, disables: iCount update, reorder of the free list and memory shrinking.
       
    98 public:
       
    99 	static DMutex* HandleMutex;
       
   100 public:
       
   101 	friend void PreprocessHandler();
       
   102 	friend class DThread;
       
   103 	friend class K;
       
   104 	friend class Monitor;
       
   105 	};
       
   106 
       
   107 inline TInt DObjectIx::Count()
       
   108 	{return iCount;}
       
   109 inline TInt DObjectIx::ActiveCount()
       
   110 	{return iActiveCount;}
       
   111 
       
   112 #undef DObjectIx
       
   113 	
       
   114 //
       
   115 // Include these in a header file
       
   116 //
       
   117 
       
   118 __ASSERT_COMPILE(sizeof(DObject) == 6*4 || sizeof(DObject) == 8*4); // We can't cope if the size changes again!
       
   119 #define DOBJECT_PADDING TUint64 _padding
       
   120 const TBool KCompiledUsingOldDefinition = sizeof(DObject) == 6*4;
       
   121 #define ADD_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr + sizeof(TUint64)))
       
   122 #define SUBTRACT_PADDING(type, variablePtr) (*reinterpret_cast<type*>((TUint8*)variablePtr - sizeof(TUint64)))
       
   123 
       
   124 
       
   125 template <class T>
       
   126 class TemplatedPadder
       
   127 	{
       
   128 public:
       
   129 	inline static T& AddPadding(T* aPtr)
       
   130 		{
       
   131 		return ADD_PADDING(T, aPtr);
       
   132 		}
       
   133 	inline static T& SubtractPadding(T* aPtr)
       
   134 		{
       
   135 		return SUBTRACT_PADDING(T, aPtr);
       
   136 		}
       
   137 	};
       
   138 
       
   139 template <class T>
       
   140 inline T& AddPadding(T* aPtr)
       
   141 	{
       
   142 	return TemplatedPadder<T>::AddPadding(aPtr);
       
   143 	}
       
   144 
       
   145 template <class T>
       
   146 inline T& SubtractPadding(T* aPtr)
       
   147 	{
       
   148 	return TemplatedPadder<T>::SubtractPadding(aPtr);
       
   149 	}
       
   150 
       
   151 TBool CalculateDObjectSize(); // returns false if unable to determine 
       
   152 extern TBool gRunningWithOldDefinition;
       
   153 
       
   154 /* The SAFE_MEMBER macro exists because DObject grew by 64 bits between 9.1 and 9.2, therefore to write a 
       
   155  * DObject-derived class (such as a DLogicalChannel in an LDD) that can be compiled on one but also works on the
       
   156  * other requires that you be very careful accessing member data of your DObject-derived objects, because the 
       
   157  * offsets are different on the two OS releases. This macro abstracts the differences away by calculating when
       
   158  * an 8 byte correction needs to be applied to where the compiler thinks the variable is versus where the runtime
       
   159  * knows it is. By necessity, it has a weird definition, that relies on the above helper macros and also on
       
   160  * CalculateDObjectSize being called at some point before the first time any code using SAFE_MACRO is run.
       
   161  * It is recommended that for an LDD, you call it from within your DECLARE_EXTENSION_LDD before doing anything
       
   162  * else.
       
   163  * 
       
   164  * SAFE_MEMBER can only be used to access member data of DObject-derived classes, and should be used in ALL 
       
   165  * places where the instance variables are used or set, this includes instance variables of the superclass and
       
   166  * instance variables in DObject-derived objects you define yourself. Accesses to instance variables of DObject
       
   167  * itself must NOT use this macro, since the DObject variable offsets do not change. In order to make sure your
       
   168  * class is large enough and that the macro can be used consistantly, you must include a DOBJECT_PADDING at 
       
   169  * the *end* of all of your DObject subclass definition. You won't get any warning if you forget to do this,
       
   170  * It will just crash. Likewise if you use SAFE_MEMBER to access the member data of the DObject itself.
       
   171  * 
       
   172  * In other words:
       
   173  * DO use SAFE_MEMBER to access the member data of DMyClassThatIsDerivedFromDObject
       
   174  * DO use SAFE_MEMBER to access the member data of DLogicalChannel/DLogicalDevice/DThread etc
       
   175  * DON'T use it to access the member data of DObject itself
       
   176  * ALWAYS include a DOBJECT_PADDING at the end of your DMyDObjectDerivedClass - ie after any other member data
       
   177  * 
       
   178  */
       
   179 
       
   180 #define SAFE_MEMBER(variable) ( \
       
   181 	(KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
       
   182 	(KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? AddPadding(&variable) : ( \
       
   183 	(!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SubtractPadding(&variable) : ( \
       
   184 	/* running and compiling with new-definition DObject */ variable ))))
       
   185 
       
   186 /* Old definition that doesn't require templating to work, (so is callable from non-C++). A consequence is you
       
   187  * have to explicitly give the type of the variable.
       
   188  */
       
   189 //#define SAFE_MEMBER(type, variable) ( \
       
   190 //	(KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? variable : ( \
       
   191 //	(KCompiledUsingOldDefinition && !gRunningWithOldDefinition) ? ADD_PADDING(type, &variable) : ( \
       
   192 //	(!KCompiledUsingOldDefinition && gRunningWithOldDefinition) ? SUBTRACT_PADDING(type, &variable) : ( \
       
   193 //	/* running and compiling with new-definition DObject */ variable ))))
       
   194 
       
   195 
       
   196 /* These macros are equivalent to _FOFF and _LOFF and should be used whenever
       
   197  * f refers to a member variable that you would need to use SAFE_MEMBER on
       
   198  */
       
   199 #define _SAFE_FOFF(c,f)			(((TInt)&  SAFE_MEMBER((((c *)0x1000)->f) )  )-0x1000)
       
   200 #define _SAFE_LOFF(p,T,f) ((T*)(((TUint8*)(p))-_SAFE_FOFF(T,f)))
       
   201 
       
   202 //END TOMSCI
       
   203 
       
   204 #endif