kernel/eka/include/kernel/kern_priv.h
changeset 43 96e5fb8b040d
child 47 46fffbe7b5a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/kern_priv.h	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,3003 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// e32\include\kernel\kern_priv.h
+// 
+// WARNING: This file contains some APIs which are internal and are subject
+//          to change without notice. Such APIs should therefore not be used
+//          outside the Kernel and Hardware Services package.
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef __K32KERN_H__
+#define __K32KERN_H__
+#include <kernel/kernel.h>
+#include <nk_priv.h>
+#include <kernel/kpower.h>
+#include <platform.h>
+#include <e32uid.h>
+#include <kernel/kernboot.h>
+#include <e32def_private.h>
+#include <e32const_private.h>
+#include <e32des8_private.h>
+#include <e32event_private.h>
+
+
+#ifndef __MINIMUM_MACHINE_CODE__
+#ifdef __MARM__
+#ifndef __BIG_ENDIAN__
+
+#ifdef __SMP__
+	#define __FASTEXEC_MACHINE_CODED__
+ 	#define __TBMA_MACHINE_CODED__
+#else
+// These macros are intended for Symbian use only.
+// It may not be possible to build the kernel if particular combinations 
+// of these macros are undefined
+	#define __FASTEXEC_MACHINE_CODED__
+	#define __MMU_MACHINE_CODED__
+	#define __PROCESS_MACHINE_CODED__
+ 	#define __TBMA_MACHINE_CODED__
+	#define __MESSAGE_MACHINE_CODED_2__
+	#define	__HANDLES_MACHINE_CODED__
+	#define __REQUEST_COMPLETE_MACHINE_CODED__
+	#define __MESSAGE_MACHINE_CODED__
+#endif
+
+#endif
+#endif
+#endif
+
+const TInt KKernelServerDefaultPriority=16;
+const TInt KDefaultExitPriority=KKernelServerDefaultPriority;
+
+// counter to ensure that priority inheritance has bounded execution time
+const TInt KMaxPriorityInheritanceNesting=10;
+
+
+const TInt KArgIndex = 16;	//number of slots in DProcess for passing info to child process on creation
+
+const TInt KDefaultMaxMemCopyInOneGo = 512;
+
+// Forward declare Shareable data buffer classes
+class DShPool;
+class TShPoolCreateInfo;
+
+//Forward declare Debug namespace for StopMode API
+namespace Debug { class StopModeDebug; }
+
+/***************************************************
+ * Kernel-side trap harness for catching exceptions
+ * Not nestable, one per thread only
+ ***************************************************/
+class TExcTrap;
+typedef void (*TExcTrapHandler)(TExcTrap*,DThread*,TAny*);
+
+class TExcTrap
+	{
+public:
+	IMPORT_C TInt Trap();	// use default exception handler
+	IMPORT_C TInt Trap(TExcTrapHandler aHandler);
+	inline void UnTrap();
+	IMPORT_C void Exception(TInt aResult);
+public:
+	TUint32 iState[EXC_TRAP_CTX_SZ];
+	TExcTrapHandler iHandler;
+	DThread* iThread;
+	};
+
+class TPagingExcTrap
+	{
+public:
+	TInt Trap();
+	inline void UnTrap();
+	void Exception(TInt aResult);
+public:
+	TUint32 iState[EXC_TRAP_CTX_SZ];
+	DThread* iThread;
+	};
+
+#define XT_DEFAULT
+#define XTRAP(_r,_h,_s)	{							\
+						TExcTrap __t;				\
+						if (((_r)=__t.Trap(_h))==0)	\
+							{						\
+							_s;						\
+							__t.UnTrap();			\
+							}						\
+						}
+
+#define XTRAPD(_r,_h,_s) TInt _r;					\
+						{							\
+						TExcTrap __t;				\
+						if (((_r)=__t.Trap(_h))==0)	\
+							{						\
+							_s;						\
+							__t.UnTrap();			\
+							}						\
+						}
+
+#ifdef __DEMAND_PAGING__
+
+#define CHECK_PAGING_SAFE				__NK_ASSERT_DEBUG(M::CheckPagingSafe(EFalse))
+
+#define CHECK_PAGING_SAFE_RANGE(s, l)	__NK_ASSERT_DEBUG(M::CheckPagingSafe(EFalse, (s), (l)))
+
+#define CHECK_DATA_PAGING_SAFE				__NK_ASSERT_DEBUG(M::CheckPagingSafe(ETrue))
+
+#define CHECK_DATA_PAGING_SAFE_RANGE(s, l)	__NK_ASSERT_DEBUG(M::CheckPagingSafe(ETrue, (s), (l)))
+
+//
+// Important - Do not use XTRAP inside an XTRAP_PAGING
+// I.e.
+//		XTRAP(XTRAP_PAGING(foo))
+// is OK, but
+//		XTRAP_PAGING(XTRAP(foo))
+// will put the system into a bad state when a paging exception happens
+// because TExcTrap::UnTrap won't get called.
+//
+
+#define XTRAP_PAGING(_r,_s)	{								\
+							TPagingExcTrap __t;				\
+							if (((_r)=__t.Trap())==0)		\
+								{							\
+								_s;							\
+								__t.UnTrap();				\
+								}							\
+							}
+
+#define XTRAP_PAGING_START(_r)	{								\
+								TPagingExcTrap __t;				\
+								if (((_r)=__t.Trap())==0)		\
+									{
+
+#define XTRAP_PAGING_END			__t.UnTrap();				\
+									}							\
+								}
+
+#define XTRAP_PAGING_RETRY(_s)	{											\
+								_retry:										\
+									TInt _exc;								\
+									XTRAP_PAGING_START(_exc);				\
+									_s;										\
+									XTRAP_PAGING_END;						\
+									if(_exc) goto _retry;					\
+								}
+
+#else
+
+#define XTRAP_PAGING(_r,_s)		{ _s }
+#define XTRAP_PAGING_START(_r)	{_r=0;{ 
+#define XTRAP_PAGING_END			  }} 
+#define CHECK_PAGING_SAFE
+#define CHECK_PAGING_SAFE_RANGE(s, l)
+#define CHECK_DATA_PAGING_SAFE
+#define CHECK_DATA_PAGING_SAFE_RANGE(s, l)
+#define XTRAP_PAGING_RETRY(_s)  { _s }
+
+#endif
+
+class TIpcExcTrap : public TExcTrap
+	{
+public:
+	TInt Trap(DThread* aClientThread); 	// use default ipc exception handler
+	inline void UnTrap();
+	enum TExcLocation { EExcUnknown, EExcLocal, EExcRemote };
+	TExcLocation ExcLocation(DThread* aThread, TAny* aContext);
+	TBool IsTIpcExcTrap();
+public:
+	TLinAddr iLocalBase;
+	TLinAddr iRemoteBase;
+	TUint32 iSize;
+	TInt iDir;		// 0=read, 1=write
+	};
+
+
+
+/**************************************************
+ * Structure used for miscellaneous notifications
+ **************************************************/
+class TMiscNotifier : public TClientRequest
+	{
+public:
+	SDblQueLink		iThreadLink;
+	SDblQueLink		iObjLink;
+	DThread*		iThread;		// doesn't need to be reference counted since all notifiers are removed when thread terminates
+private:
+	~TMiscNotifier();				// call Close(), don't delete
+	};
+
+struct SMiscNotifierQ : public SDblQue
+	{
+	};
+
+class TMiscNotifierMgr
+	{
+public:
+	TMiscNotifierMgr();
+	void Init2();
+	void CompleteNotifications(SDblQue& aQ);
+	static void CompletionDfcFn(TAny* aMgr);
+	static void IdleDfcFn(TAny* aMgr);
+	inline void Lock()
+		{NKern::FMWait(&iLock);}
+	inline void Unlock()
+		{NKern::FMSignal(&iLock);}
+	TInt NewMiscNotifier(TRequestStatus* aStatus, TBool aObj, TAny* aPtr, TMiscNotifier*& aN, SMiscNotifierQ*& aQ);
+public:
+	SDblQue			iCompleted;
+	TDfc			iCompletionDfc;
+	SMiscNotifierQ*	iIdleNotifierQ;
+	TDfc			iIdleDfc;
+	NFastMutex		iLock;
+	};
+
+
+
+/********************************************
+ * Kernel object index (handles array)
+ ********************************************/
+class DMutex;
+
+/** Handle analysis and synthesis
+@internalComponent
+*/
+inline TBool HandleIsSpecial(TInt aHandle)
+	{ return aHandle<0; }
+inline TBool HandleIsThreadLocal(TInt aHandle)
+	{ return aHandle&0x40000000; }
+inline TBool HandleNoClose(TInt aHandle)
+	{ return aHandle&0x00008000; }
+inline TInt HandleIndex(TInt aHandle)
+	{ return aHandle&0x00007FFF; }
+inline TInt HandleInstance(TInt aHandle)
+	{ return (aHandle&0x3FFF0000)>>16; }
+inline TInt MakeHandle(TInt aIndex, TInt aInstance)
+	{ return ((aInstance&0x3FFF)<<16)|(aIndex&0x7FFF); }
+
+
+/**
+@internalComponent
+*/
+class RObjectIx
+	{
+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);
+	inline void AddHead(TInt aQueue, TInt aSlotIndex);
+	inline 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
+	RObjectIx();
+	TInt Close(TAny* aPtr);
+
+	TInt Add(DObject* aObj, TUint32 aAttr);
+	TInt Remove(TInt aHandle, DObject*& aObject, TUint32& aAttr);
+	TInt Reserve(TInt aCount);
+	DObject* At(TInt aHandle, TInt aUniqueID, TUint32 aRequiredAttr);
+	DObject* At(TInt aHandle, TInt aUniqueID, TUint32* aAttr);
+	DObject* At(TInt aHandle, TInt aUniqueID);
+	DObject* At(TInt aHandle);
+	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);
+	TInt Count(DObject* aObject);
+	TInt LastHandle();
+#ifdef DOBJECT_TEST_CODE
+	typedef void (*TValidateEntry)(TInt, TInt, TInt, TInt, TUint, DObject*);
+	void Check(TValidateEntry aV);
+#endif
+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;
+public:
+	friend void PreprocessHandler();
+	friend class DThread;
+	friend class K;
+	friend class Monitor;
+	};
+//
+// These are the same as their e32base.h versions
+/*inline TBool IsLocalHandle(TInt aHandle)
+	{return(aHandle&RObjectIx::ELocalHandle);}
+inline void SetLocalHandle(TInt &aHandle)
+	{aHandle|=RObjectIx::ELocalHandle;}
+inline void UnSetLocalHandle(TInt &aHandle)
+	{aHandle&=(~RObjectIx::ELocalHandle);}
+*/
+/********************************************
+ * Kernel object container
+ ********************************************/
+class DObjectCon : public DBase
+	{
+protected:
+	enum {ENotOwnerID};
+public:
+	~DObjectCon();
+	static DObjectCon* New(TInt aUniqueID);
+	IMPORT_C void Remove(DObject* aObj);
+	IMPORT_C TInt Add(DObject* aObj);
+	IMPORT_C DObject* operator[](TInt aIndex);
+	IMPORT_C DObject* At(const TFindHandle& aFindHandle);
+	IMPORT_C TInt CheckUniqueFullName(DObject* aOwner, const TDesC& aName);
+	IMPORT_C TInt CheckUniqueFullName(DObject* aObject);
+	IMPORT_C TInt FindByName(TFindHandle& aFindHandle, const TDesC& aMatch, TKName& aName);
+	IMPORT_C TInt FindByFullName(TFindHandle& aFindHandle, const TDesC& aMatch, TFullName& aFullName);
+	IMPORT_C TInt OpenByFullName(DObject*& aObject, const TDesC& aMatch);
+	inline TInt UniqueID() {return iUniqueID;}
+	inline TInt Count() {return iCount;}
+	inline void Wait() {Kern::MutexWait(*iMutex);}
+	inline void Signal() {Kern::MutexSignal(*iMutex);}
+	inline DMutex* Lock() {return iMutex;}
+protected:
+	DObjectCon(TInt aUniqueID);
+	TBool NamesMatch(DObject* aObject, const TDesC& aObjectName, DObject* aCurrentObject);
+public:
+	TInt iUniqueID;
+private:
+	TInt iAllocated;
+	TInt iCount;
+	DObject** iObjects;
+	DMutex* iMutex;
+public:
+	friend class Monitor;
+	friend class Debugger;
+	friend class SCMonitor;
+	friend class Debug::StopModeDebug;
+	};
+
+/********************************************
+ * Process and process-relative thread priorities
+ ********************************************/
+enum TThrdPriority
+	{
+	EThrdPriorityIdle=-8,
+	EThrdPriorityMuchLess=-7,
+	EThrdPriorityLess=-6,
+	EThrdPriorityNormal=-5,
+	EThrdPriorityMore=-4,
+	EThrdPriorityMuchMore=-3,
+	EThrdPriorityRealTime=-2,
+
+	EThrdPriorityNull=0,
+	EThrdPriorityAbsoluteVeryLow=1,
+	EThrdPriorityAbsoluteLowNormal=3,
+	EThrdPriorityAbsoluteLow=5,
+	EThrdPriorityAbsoluteBackgroundNormal=7,
+	EThrdPriorityAbsoluteBackground=10,
+	EThrdPriorityAbsoluteForegroundNormal=12,
+	EThrdPriorityAbsoluteForeground=15,
+	EThrdPriorityAbsoluteHighNormal=19,
+	EThrdPriorityAbsoluteHigh=23,
+	EThrdPriorityAbsoluteRealTime1=24,
+	EThrdPriorityAbsoluteRealTime2=25,
+	EThrdPriorityAbsoluteRealTime3=26,
+	EThrdPriorityAbsoluteRealTime4=27,
+	EThrdPriorityAbsoluteRealTime5=28,
+	EThrdPriorityAbsoluteRealTime6=29,
+	EThrdPriorityAbsoluteRealTime7=30,
+	EThrdPriorityAbsoluteRealTime8=31
+	};
+
+enum TProcPriority
+	{
+	EProcPriorityLow=0,
+	EProcPriorityBackground=1,
+	EProcPriorityForeground=2,
+	EProcPriorityHigh=3,
+	EProcPrioritySystemServer1=4,
+	EProcPrioritySystemServer2=5,
+	EProcPrioritySystemServer3=6,
+	EProcPriorityRealTimeServer=7,
+	};
+
+/********************************************
+ * Multipurpose timer
+ ********************************************/
+#ifndef MAX
+#define MAX(a,b)		((a)<(b)?(b):(a))
+#endif
+#ifndef MAX3
+#define MAX3(a,b,c)		MAX(MAX(a,b),c)
+#endif
+#ifndef MAX4
+#define MAX4(a,b,c,d)	MAX(MAX(a,b),MAX(c,d))
+#endif
+#define TIMER_SIZE		MAX4(sizeof(TTickLink),sizeof(TSecondLink),sizeof(NTimer),sizeof(TInactivityLink))
+
+class TTimer
+	{
+public:
+	enum TTimerType {ERelative=1,EAbsolute=2,ELocked=4,EHighRes=8,EInactivity=16};
+	enum TTimerState {EIdle,EWaiting,EWaitHighRes};
+public:
+	TInt Create();
+	inline TTimer();
+	~TTimer();
+	TInt After(TInt aInterval, TTickCallBack aFunction, TRequestStatus& aStatus);
+	TInt At(const TTimeK& aTime, TSecondCallBack aFunction, TRequestStatus& aStatus);
+	TInt AfterHighRes(TInt aInterval, NTimerFn aFunction, TRequestStatus& aStatus);
+	TInt Inactivity(TInt aSeconds, TInactivityCallBack aFunction, TRequestStatus& aStatus);
+	void Cancel(DThread* aThread);
+	void Abort(DThread* aThread, TInt aTypeMask);
+	void SetType(TTimerType aType);
+public:
+	inline TTickLink& TickLink()
+		{ return *(TTickLink*)iUnion; }
+	inline TSecondLink& SecondLink()
+		{ return *(TSecondLink*)iUnion; }
+	inline NTimer& Ms()
+		{ return *(NTimer*)iUnion; }
+	inline TInactivityLink& Inact()
+		{ return *(TInactivityLink*)iUnion; }
+	inline TTimerType Type()
+		{ return (TTimerType)iType; }
+public:
+	TUint32 iUnion[TIMER_SIZE/sizeof(TUint32)];	// this field must always be 8-byte aligned
+	TClientRequest* iRequest;
+	TUint8 iState;
+	TUint8 iType;
+	};
+
+inline TTimer::TTimer()
+	: iState(EIdle)
+	{}
+
+/********************************************
+ * Timer control block
+ ********************************************/
+class DTimer : public DObject
+	{
+public:
+	TInt Create(DThread* aThread);
+public:
+	DTimer();
+	~DTimer();
+public:
+	void Cancel();
+	TInt After(TRequestStatus& aStatus, TInt aInterval);
+	TInt At(TRequestStatus& aStatus, const TTimeK& aTime);
+	TInt Lock(TRequestStatus& aStatus, TTimerLockSpec aLock);
+	void HighRes(TRequestStatus& aStatus, TInt aInterval);
+	TInt Inactivity(TRequestStatus& aStatus, TInt aSeconds);
+	void Abort(TBool aAbortAbsolute);
+	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
+private:
+	inline DThread* Owner();
+	static void TimerComplete(TAny* aPtr);
+	static void SecondComplete(TAny* aPtr);
+	static void LockComplete(TAny* aPtr);
+	static void LockSynchronize(TAny* aPtr);
+	static void MsComplete(TAny* aTimer);
+	inline static DTimer* FromPtr(TAny* aPtr);
+public:
+//	TAny* __padding;	// for alignment
+	TTimer iTimer;
+public:
+	friend class Monitor;
+	};
+
+__ASSERT_COMPILE((_FOFF(DTimer,iTimer.iUnion) & 7)==0);
+
+inline DTimer* DTimer::FromPtr(TAny* aPtr)
+	{ return _LOFF(aPtr,DTimer,iTimer); }
+inline DThread* DTimer::Owner()
+	{return (DThread*)DObject::Owner();}
+
+
+/********************************************
+ * Thread cleanup entries
+ ********************************************/
+class DThread;
+class TThreadCleanup : public TPriListLink
+	{
+public:
+	IMPORT_C TThreadCleanup();
+	void ChangePriority(TInt aNewPriority);
+	IMPORT_C void Remove();
+	virtual void Cleanup()=0;
+public:
+	DThread* iThread;
+public:
+	friend class Monitor;
+	};
+
+class TThreadMutexCleanup : public TThreadCleanup
+	{
+public:
+	inline TThreadMutexCleanup(DMutex* aMutex);
+	virtual void Cleanup();
+	DMutex *iMutex;
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Deterministic thread wait queue
+ ********************************************/
+class TThreadWaitList
+	{
+private:
+	enum { EEmpty=0u, EFlagList=1u, EInitValue=3u, ENonEmptyMask=0xfffffffcu };
+private:
+	class TList : public TPriListBase
+		{
+	private:
+		TList() : TPriListBase(KNumPriorities) {}
+		inline TList*& Next()
+			{ return *(TList**)this; }
+	private:
+		SDblQueLink* iExtraQueues[KNumPriorities-1];
+
+		friend class TThreadWaitList;
+		friend class Monitor;
+		};
+public:
+	inline TThreadWaitList()
+		{ iWaitPtr=EInitValue; }
+	~TThreadWaitList();
+	TInt Construct();
+	inline TBool NonEmpty() const
+		{ return (iWaitPtr & ENonEmptyMask); }
+	DThread* First() const;
+	TInt HighestPriority() const;
+	void Add(DThread* aThread);
+	void Remove(DThread* aThread);
+	void ChangePriority(DThread* aThread, TInt aNewPriority);
+	static TInt ThreadCreated();
+	static void ThreadDestroyed();
+private:
+	static TInt Up(TBool aThread);
+	static void Down(TBool aThread);
+#ifdef _DEBUG
+	void Check() const;
+#endif
+private:
+	TLinAddr	iWaitPtr;
+
+	static TList* FirstFree;	// first free list
+	static TInt NLists;			// number of TLists in existence
+	static TInt NWaitObj;		// number of wait objects in existence which use TThreadWaitList
+	static TInt NThrd;			// number of DThreads in existence
+	};
+
+
+/********************************************
+ * Semaphore control block
+ ********************************************/
+class DSemaphore : public DObject
+	{
+public:
+	TInt Create(DObject* aOwner, const TDesC* aName, TInt aInitialCount, TBool aVisible=ETrue);
+public:
+	~DSemaphore();
+	void WaitCancel(DThread* aThread);
+	void WaitCancelSuspended(DThread* aThread);
+	void SuspendWaitingThread(DThread* aThread);
+	void ResumeWaitingThread(DThread* aThread);
+	void ChangeWaitingThreadPriority(DThread* aThread, TInt aNewPriority);
+public:
+	TInt Wait(TInt aNTicks);
+	void Signal();
+	void SignalN(TInt aCount);
+	void Reset();
+public:
+	TInt iCount;
+	TUint8 iResetting;
+	TUint8 iPad1;
+	TUint8 iPad2;
+	TUint8 iPad3;
+	SDblQue iSuspendedQ;
+	TThreadWaitList iWaitQ;
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Mutex control block
+ ********************************************/
+class DMutex : public DObject
+	{
+public:
+	TInt Create(DObject* aOwner, const TDesC* aName, TBool aVisible, TUint aOrder);
+public:
+	DMutex();
+	~DMutex();
+	TInt HighestWaitingPriority();
+	void WaitCancel(DThread* aThread);
+	void WaitCancelSuspended(DThread* aThread);
+	void SuspendWaitingThread(DThread* aThread);
+	void ResumeWaitingThread(DThread* aThread);
+	void ChangeWaitingThreadPriority(DThread* aThread, TInt aNewPriority);
+	void SuspendPendingThread(DThread* aThread);
+	void RemovePendingThread(DThread* aThread);
+	void ChangePendingThreadPriority(DThread* aThread, TInt aNewPriority);
+	void WakeUpNextThread();
+public:
+	TInt Wait();
+	void Signal();
+	void Reset();
+public:
+	TInt iHoldCount;			// number of times held by current thread
+	TInt iWaitCount;			// number of waiting threads
+	TUint8 iResetting;
+	TUint8 iOrder;
+	TUint8 iPad1;
+	TUint8 iPad2;
+	TThreadMutexCleanup iCleanup;
+	SDblQue iSuspendedQ;
+	SDblQue iPendingQ;
+	TThreadWaitList iWaitQ;
+#ifdef _DEBUG
+	SDblQueLink iOrderLink;		// used for acquisition order checking
+#endif
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Condition variable control block
+ ********************************************/
+class DCondVar : public DObject
+	{
+public:
+	TInt Create(DObject* aOwner, const TDesC* aName, TBool aVisible);
+public:
+	DCondVar();
+	~DCondVar();
+	void WaitCancel(DThread* aThread);
+	void WaitCancelSuspended(DThread* aThread);
+	void SuspendWaitingThread(DThread* aThread);
+	void ResumeWaitingThread(DThread* aThread);
+	void ChangeWaitingThreadPriority(DThread* aThread, TInt aNewPriority);
+public:
+	TInt Wait(DMutex* aMutex, TInt aTimeout);
+	void Signal();
+	void Broadcast(DMutex* aMutex);
+	void Reset();
+	void UnBlockThread(DThread* aThread, TBool aUnlock);
+public:
+	TUint8 iResetting;
+	TUint8 iPad1;
+	TUint8 iPad2;
+	TUint8 iPad3;
+	DMutex* iMutex;
+	TInt iWaitCount;
+	SDblQue iSuspendedQ;
+	TThreadWaitList iWaitQ;
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Kernel representation of session message
+ ********************************************/
+
+class DSession;
+class RMessageK : public TClientRequest
+	{
+public:
+	inline TInt Arg(TInt aParam) const;
+	inline TAny* Ptr(TInt aParam) const;
+	inline TInt ArgType(TInt aParam) const;
+	inline TUint IsDescriptor(TInt aParam) const;
+	inline const TDesHeader& Descriptor(TInt aParam) const;
+	inline TDesHeader& Descriptor(TInt aParam);
+	inline TInt DesLength(TInt aParam) const;
+	inline TInt DesMaxLength(TInt aParam) const;
+	IMPORT_C DThread* Thread() const;
+	IMPORT_C static RMessageK* MessageK(TInt aHandle);
+	static RMessageK* MessageK(TInt aHandle, DThread* aThread);
+	void OpenRef();
+	void CloseRef();
+
+public:
+	// message is always in one of the following message states,
+	// a change of state requires the system lock.
+	inline TBool IsFree() const;
+	inline TBool IsInitialising() const;
+	inline TBool IsDelivered() const;
+	inline TBool IsAccepted() const;
+	inline TBool IsCompleting() const;
+	inline void SetFree();
+	inline void SetInitialising();
+	inline void SetDelivered(SDblQue& aDeliveredQ);
+	inline void SetAccepted(DProcess* aServerProcess);
+	inline void SetCompleting();
+
+	// WARNING: Some ARM assembler code makes assumptions about the *ordering* of these enum values!
+	enum TMsgType {EDisc=32, ESync, ESession, EGlobal};
+	static RMessageK* GetNextFreeMessage(DSession* aSession);
+	static RMessageK* ClaimMessagePool(enum TMsgType aType, TInt aCount, DSession* aSession);
+	void ReleaseMessagePool(enum TMsgType aType, TInt aMax);
+
+private:
+	friend class DSession;
+	friend class ExecHandler;
+	class TMsgArgs
+		{
+		friend class RMessageK;
+		friend class DSession;
+		friend class ExecHandler;
+		friend class TServerMessage;
+		void ReadDesHeaders(const TInt aArgsPtr[KMaxMessageArguments+1]);
+		inline TInt ArgType(TInt aParam) const;
+		inline TUint IsDescriptor(TInt aParam) const;
+		inline TUint AllDescriptorFlags() const;
+		inline TUint AllPinFlags() const;
+		inline TUint AllDesWritten() const;
+		inline void SetArgUndefined(TInt aParam);
+		inline void SetDesWritten(TInt aParam);
+
+		inline TBool IsDesWritten(TInt aParam) const;
+
+		TUint		iArgFlags;						// describes which arguments are descriptors/handles etc.
+		TInt		iArgs[KMaxMessageArguments];	// the arguments themselves
+		TDesHeader	iDesInfo[KMaxMessageArguments];	// info for any descriptor args
+
+		// The iArgFlags words has a strange layout. The bottom 16 bits have to match those
+		// TIpcArgs::iFlags, which -- from LSB upwards -- is KMaxMessageArguments (4) fields
+		// of KBitsPerType (3) each, describing arguments 0-3, followed by 4 bits requesting
+		// pinning of the corresponding (descriptor) argument.  We then use the next 4 bits
+		// to record whether each (descriptor) argument has been written.
+
+		enum
+			{
+			KArgFlagMask		= (1 << TIpcArgs::KBitsPerType) - 1,
+			KAllArgTypesMask	= (1 << (TIpcArgs::KBitsPerType*KMaxMessageArguments)) - 1,
+			KAllIpcFlagsMask	= (KAllArgTypesMask | TIpcArgs::KPinMask),
+			KAllDesArgMask		= (TIpcArgs::EFlagDes << (0 * TIpcArgs::KBitsPerType)) |
+								  (TIpcArgs::EFlagDes << (1 * TIpcArgs::KBitsPerType)) |
+								  (TIpcArgs::EFlagDes << (2 * TIpcArgs::KBitsPerType)) |
+								  (TIpcArgs::EFlagDes << (3 * TIpcArgs::KBitsPerType)),
+
+			KDesWrittenShift	= (TIpcArgs::KBitsPerType*KMaxMessageArguments + TIpcArgs::KPinArgShift),
+			KDesWrittenMask		= ((1 << KMaxMessageArguments) - 1) << KDesWrittenShift
+			};
+		};
+
+private:
+	RMessageK();						// call GetNextFreeMessage() or ClaimMessagePool() instead
+	~RMessageK();						// Don't delete, call CloseRef()
+	void Free();						// only called from last CloseRef()
+	static TInt ExpandMessagePool();
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+	TInt PinDescriptors(DSession* aSession, TBool aPinningServer);
+
+public:
+	TUint8			iMsgType;			// where this message belongs - one of the TMsgType values above
+	TUint8			iAccessCount;
+	DSession*		iSession;			// pointer to session
+	SDblQueLink		iSessionLink;		// attaches message to session or freelist
+	// WARNING: Some ARM assembler code makes assumptions about the layout of this structure!
+	SDblQueLink		iServerLink;		// Also represents message state!
+	TInt			iFunction;	
+	TMsgArgs		iMsgArgs;
+	DThread*		iClient;			// pointer to client thread (not reference counted, see below)
+
+	// An encapsulated array of pointers to pin objects associated with any descriptor arguments.
+	struct TPinArray
+		{
+		TVirtualPinObject* iPinPtrs[KMaxMessageArguments];
+		}			*iPinArray;			// Pointer to (heap-allocated) array of pointers to pin objects
+
+public:
+	enum { KMessageSize = 128 };		// sizeof(RMessageK) rounded up to a power of 2
+	};
+
+inline TInt RMessageK::TMsgArgs::ArgType(TInt aParam) const
+	{
+	return (iArgFlags >> (aParam * TIpcArgs::KBitsPerType)) & KArgFlagMask;
+	}
+inline TUint RMessageK::TMsgArgs::IsDescriptor(TInt aParam) const
+	{
+	return (iArgFlags >> (aParam * TIpcArgs::KBitsPerType)) & TIpcArgs::EFlagDes;
+	}
+inline TUint RMessageK::TMsgArgs::AllDescriptorFlags() const
+	{
+	return iArgFlags & KAllDesArgMask;
+	}
+inline TUint RMessageK::TMsgArgs::AllPinFlags() const
+	{
+	return (iArgFlags & TIpcArgs::KPinMask) >> TIpcArgs::KPinArgShift;
+	}
+inline TUint RMessageK::TMsgArgs::AllDesWritten() const
+	{
+	return (iArgFlags & KDesWrittenMask) >> KDesWrittenShift;
+	}
+inline void RMessageK::TMsgArgs::SetArgUndefined(TInt aParam)
+	{
+	iArgFlags &= ~(KArgFlagMask << (aParam * TIpcArgs::KBitsPerType));
+	iArgFlags |= TIpcArgs::EUnspecified << (aParam * TIpcArgs::KBitsPerType);
+	}
+inline void RMessageK::TMsgArgs::SetDesWritten(TInt aParam)
+	{
+	iArgFlags |= 1 << (aParam + KDesWrittenShift);
+	}
+
+inline TInt RMessageK::Arg(TInt aParam) const
+	{
+	return iMsgArgs.iArgs[aParam];
+	}
+inline TAny* RMessageK::Ptr(TInt aParam) const
+	{
+	return (TAny*)Arg(aParam);
+	}
+inline TInt RMessageK::ArgType(TInt aParam) const
+	{
+	return iMsgArgs.ArgType(aParam);
+	}
+inline TUint RMessageK::IsDescriptor(TInt aParam) const
+	{
+	return iMsgArgs.IsDescriptor(aParam);
+	}
+inline const TDesHeader& RMessageK::Descriptor(TInt aParam) const
+	{
+	return iMsgArgs.iDesInfo[aParam];
+	}
+inline TDesHeader& RMessageK::Descriptor(TInt aParam)
+	{
+	return iMsgArgs.iDesInfo[aParam];
+	}
+inline TInt RMessageK::DesLength(TInt aParam) const
+	{
+	return Descriptor(aParam).Length();
+	}
+inline TInt RMessageK::DesMaxLength(TInt aParam) const
+	{
+	return Descriptor(aParam).MaxLength();
+	}
+inline TBool RMessageK::IsFree() const
+	{
+	__ASSERT_SYSTEM_LOCK;
+	return !iServerLink.iNext;
+	}
+inline TBool RMessageK::IsInitialising() const
+	{
+	__ASSERT_SYSTEM_LOCK;
+	return iServerLink.iNext == (TAny*)2;
+	}
+inline TBool RMessageK::IsDelivered() const
+	{
+	__ASSERT_SYSTEM_LOCK;
+	return iServerLink.iNext != 0 && (TLinAddr(iServerLink.iNext) & 3) == 0;
+	}
+inline TBool RMessageK::IsAccepted() const
+	{
+	__ASSERT_SYSTEM_LOCK;
+	return ((TLinAddr)iServerLink.iNext & 3) == 3;
+	}
+inline TBool RMessageK::IsCompleting() const
+	{
+	__ASSERT_SYSTEM_LOCK;
+	return iServerLink.iNext == (TAny*)1;
+	}
+inline void RMessageK::SetFree()
+	{
+	__ASSERT_SYSTEM_LOCK;
+	iServerLink.iNext = 0;
+	}
+inline void RMessageK::SetInitialising()
+	{
+	__ASSERT_SYSTEM_LOCK;
+	iServerLink.iNext = (SDblQueLink*)2;
+	}
+inline void RMessageK::SetDelivered(SDblQue& aDeliveredQ)
+	{
+	__ASSERT_SYSTEM_LOCK;
+	aDeliveredQ.Add(&iServerLink);
+	}
+inline void RMessageK::SetAccepted(DProcess* aServerProcess)
+	{
+	__ASSERT_SYSTEM_LOCK;
+	iServerLink.iNext = (SDblQueLink*)~TUint32(this);
+	iServerLink.iPrev = (SDblQueLink*)~TUint32(aServerProcess);
+	}
+inline void RMessageK::SetCompleting()
+	{
+	__ASSERT_SYSTEM_LOCK;
+	iServerLink.iNext = (SDblQueLink*)1;
+	}
+
+/********************************************
+ * Thread control block
+ ********************************************/
+class DChunk;
+class DProcess;
+class TTrap;
+
+const TInt KMaxThreadContext=256;
+typedef void (*TUnknownStateHandler)(DThread*,TInt,TInt);
+
+class DThread : public DObject
+	{
+public:
+	enum {EDefaultUserTimeSliceMs = 20};
+
+	enum TThreadState
+		{
+		ECreated,
+		EDead,
+		EReady,
+		EWaitSemaphore,
+		EWaitSemaphoreSuspended,
+		EWaitMutex,
+		EWaitMutexSuspended,
+		EHoldMutexPending,
+		EWaitCondVar,
+		EWaitCondVarSuspended,
+		};
+
+	enum TOperation
+		{
+		ESuspend=0,
+		EResume=1,
+		EForceResume=2,
+		EReleaseWait=3,
+		EChangePriority=4,
+		};
+
+	enum TUserThreadState
+		{
+		EUserThreadNone,
+		EUserThreadCreated,
+		EUserThreadRunning,
+		EUserThreadExiting,
+		};
+	   
+public:
+	DThread();
+	void Destruct();
+	TInt Create(SThreadCreateInfo& aInfo);
+	TInt SetPriority(TThreadPriority aPriority);
+	TInt MakeHandle(TOwnerType aType, DObject* aObject, TInt& aHandle);
+	TInt MakeHandle(TOwnerType aType, DObject* aObject, TInt& aHandle, TUint aAttr);
+	TInt MakeHandleAndOpen(TOwnerType aType, DObject* aObject, TInt& aHandle);
+	TInt MakeHandleAndOpen(TOwnerType aType, DObject* aObject, TInt& aHandle, TUint aAttr);
+	TInt HandleClose(TInt aHandle);
+	TInt OpenFindHandle(TOwnerType aType, const TFindHandle& aFindHandle, TInt& aHandle);
+	TInt OpenObject(TOwnerType aType, const TDesC& aName, TInt& aHandle, DObject*& aObj, TInt aObjType);
+	IMPORT_C DObject* ObjectFromHandle(TInt aHandle);
+	IMPORT_C DObject* ObjectFromHandle(TInt aHandle, TInt aObjType);
+	IMPORT_C DObject* ObjectFromHandle(TInt aHandle, TInt aObjType, TUint& aAttr);
+	void RequestComplete(TRequestStatus*& aStatus, TInt aReason);
+	TInt SetTls(TInt aHandle, TInt aDllUid, TAny* aPtr);
+	TAny* Tls(TInt aHandle, TInt aDllUid);
+	void FreeTls(TInt aHandle);
+	TInt Rename(const TDesC& aName);
+	TBool IsExceptionHandled(TExcType aType);
+	TInt RaiseException(TExcType aType);
+	void SetExitInfo(TExitType aType, TInt aReason, const TDesC& aCategory);
+	void CloseCreatedHeap();
+	void RemoveClosingLibs();
+	inline TBool HasCapability(/*TInt aCapability*/);
+	TBool IsRealtime();
+	void SetRealtimeState(TThreadRealtimeState aNewState);
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	inline TBool HasCapability(TCapability aCapability, const char* aDiagnosticText=0);
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// Only available to NULL arguments
+	inline TBool HasCapability(TCapability aCapability, OnlyCreateWithNull aDiagnostic=NULL);
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+private:
+	IMPORT_C TBool DoHasCapability(TCapability aCapability, const char* aDiagnosticText);
+	IMPORT_C TBool DoHasCapability(TCapability aCapability);
+public:
+	// not memory model dependent
+	virtual TInt Context(TDes8& aDes)=0;
+public:
+	inline void Stillborn();
+	void Release();
+	TInt CalcDefaultThreadPriority();
+	IMPORT_C void AddCleanup(TThreadCleanup* aCleanup);
+	void SetRequiredPriority();
+	void SetActualPriority(TInt aActualPriority);
+	void RevertPriority();
+	void SvKill();
+	IMPORT_C TInt ReleaseWait(TInt aReturnCode);
+	IMPORT_C void CancelTimer();
+	void ExtractMiscNotifiers(SDblQue& aQ, TRequestStatus* aStatus);
+	void KillMiscNotifiers();
+public:
+	// not memory model dependent
+	TInt DoCreate(SThreadCreateInfo& aInfo);
+	IMPORT_C void SetThreadPriority(TInt aThreadPriority);
+	void SetDefaultPriority(TInt aDefaultPriority);
+	void AbortTimer(TBool aAbortAbsolute);
+	void Suspend(TInt aCount);
+	void Resume();
+	void ForceResume();
+	void Exit();
+	void Die(TExitType aType, TInt aReason, const TDesC& aCategory);
+	TInt Logon(TRequestStatus* aStatus, TBool aRendezvous);
+	void Rendezvous(TInt aReason);
+	void CleanupLeave(TInt aDepth = 1);
+#ifdef __SMP__
+	static void SMPSafeCallback(TAny* aThisPtr, TUserModeCallbackReason aReasonCode);
+#endif
+public:
+	// memory model dependent
+	TInt AllocateSupervisorStack();
+	void FreeSupervisorStack();
+	void FreeUserStack();
+	TInt AllocateUserStack(TInt aSize, TBool aPaged);
+	DChunk* OpenSharedChunk(const TAny* aAddress, TBool aWrite, TInt& aOffset);
+	DChunk* OpenSharedChunk(TInt aHandle,TBool aWrite);
+	TInt PrepareMemoryForDMA(const TAny* aAddress, TInt aSize, TPhysAddr* aPageList);
+	TInt ReleaseMemoryFromDMA(const TAny* aAddress, TInt aSize, TPhysAddr* aPageList);
+
+	static void IpcExcHandler(TExcTrap* aTrap, DThread* aThread, TAny* aContext);
+	virtual void DoExit1();
+public:
+	// pure virtual
+	virtual TInt SetupContext(SThreadCreateInfo& aInfo)=0;
+	virtual void DoExit2()=0;
+protected:
+	virtual void SetPaging(TUint& aCreateFlags);
+public:
+	inline void UnknownState(TInt aOperation, TInt aParameter);
+	inline static DThread* FromTimer(TAny* aPtr);
+	static void ExitCurrentThread();
+	static void DefaultUnknownStateHandler(DThread* aThread, TInt aOperation, TInt aParameter);
+	static void EpocThreadFunction(TAny* aPtr);
+	static TDfc* EpocThreadExitHandler(NThread* aThread);
+	static void EpocThreadTimeoutHandler(NThread* aThread, TInt aOp);
+public:
+ 	virtual void BTracePrime(TInt aCategory);
+
+private:
+	// Functions that access user-side memory
+	TInt GetDesInfo(const TAny* aDes, TInt& aLength, TInt& aMaxLength, TUint8*& aPtr, TBool aWriteable);
+	TInt GetDesLength(const TAny* aPtr);
+	TInt GetDesMaxLength(const TAny* aPtr);
+	TInt DesRead(const TAny* aPtr, TUint8* aDes, TInt aMax, TInt aOffset, TInt aMode);
+	TInt DesWrite(const TAny* aPtr, const TUint8* aDes, TInt aLength, TInt aOffset, TInt aMode, DThread* aOriginatingThread);
+	TInt DoDesRead(const TDesHeader& aDesInfo, TUint8* aDes, TInt aMax, TInt aOffset, TInt aMode);
+	TInt DoDesWrite(const TAny* aPtr, TDesHeader& aDesInfo, const TUint8* aDes, TInt aLength, TInt aOffset, TInt aMode, DThread* aOriginatingThread);
+	// (the following are memory model dependent)
+	TInt RawRead(const TAny* aSrc, TAny* aDest, TInt aLength, TInt aFlags, TIpcExcTrap* aExcTrap);
+	TInt RawWrite(const TAny* aDest, const TAny* aSrc, TInt aLength, TInt aFlags, DThread* aOriginatingThread, TIpcExcTrap* aExcTrap);
+	TInt ReadAndParseDesHeader(const TAny* aSrc, TDesHeader& aDest);
+
+public:
+	TUint32 iIpcCount;
+	TLinAddr iUserStackRunAddress;
+	TInt iUserStackSize;
+	TUint32 iFlags;
+	DProcess* iOwningProcess;
+	SDblQueLink iProcessLink;
+	TInt iThreadPriority;
+	RObjectIx iHandles;
+	TUint iId;
+	RAllocator* iAllocator;
+	RAllocator* iCreatedAllocator;
+	TTrap* iFrame;
+	TTrapHandler* iTrapHandler;
+	RArray<STls> iTls;
+	CActiveScheduler* iScheduler;
+	TExceptionHandler iExceptionHandler;
+	TUint iExceptionMask;
+	TExcTrap* iExcTrap;
+	TInt iDebugMask;
+	TThreadMessage iKernMsg;
+	DObject* iTempObj;
+	DObject* iExtTempObj;
+	TAny* iTempAlloc;
+	SDblQue iOwnedLogons;
+	SDblQue iTargetLogons;
+	RMessageK* iSyncMsgPtr;
+	TDfc iKillDfc;
+	SDblQue iClosingLibs;
+	TPriListLink iWaitLink;
+//	TUint8 iMState;							// use iSpare1 for iMState
+//	TUint8 iExiting;						// use iSpare2 for iExiting
+//	TUint8 iWaitListReserved;				// use iSpare3 for iWaitListReserved
+	TInt iDefaultPriority;					// default scheduling priority
+	TAny* iWaitObj;							// object on which this thread is waiting
+	TUnknownStateHandler iUnknownStateHandler;	// handler for extra thread states - used by RTOS personality layers
+	TAny* iExtras;							// pointer to extra data used by RTOS personality layers
+	TAny* iSupervisorStack;					// thread's supervisor mode stack
+	TInt iSupervisorStackSize;
+	TUint8 iSupervisorStackAllocated;
+	TUint8 iThreadType;
+	TUint8 iExitType;
+	TUint8 iEmiFlags;
+	TInt iExitReason;
+	TBufC<KMaxExitCategoryName> iExitCategory;
+	SDblQue iMutexList;						// list of held mutexes, used only for acquisition order checking
+	TPriList<TThreadCleanup,KNumPriorities> iCleanupQ;	// things to clean up when we die
+	TTimer iTimer;
+	TInt iLeaveDepth;						// recursive depth of User::Leave() calls
+	TAny* iEmiStartMonitor;
+	NThread iNThread;
+	TPagingExcTrap* iPagingExcTrap;
+	TUserThreadState iUserThreadState;
+	SDblQue iMiscNotifiers;					// miscellaneous notifiers owned by this thread
+	DThread* iIpcClient;					// client thread when doing IPC, used if realtime therad takes fault
+#ifdef __SMP__
+	TUserModeCallback iSMPSafeCallback;
+#endif
+	RMessageK* iTempMsg;
+
+public:
+#ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
+#ifdef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// This exported Kern:: function takes diagnostic strings that
+	// should still work by calling the DoHasCapability function here even
+	// though we have removed diagnostic strings from ekern proper
+	friend TBool Kern::DoCurrentThreadHasCapability(TCapability aCapability, const char* aContextText);
+#endif //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+#endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
+
+	friend class Monitor;
+	friend class Kern;
+	friend class ExecHandler;
+	friend class TClientBuffer;
+	};
+
+__ASSERT_COMPILE((_FOFF(DThread,iTimer.iUnion) & 7)==0);
+
+inline DThread* DThread::FromTimer(TAny* aPtr)
+	{ return _LOFF(aPtr,DThread,iTimer); }
+inline void DThread::UnknownState(TInt aOperation, TInt aParameter)
+	{ (*iUnknownStateHandler)(this,aOperation,aParameter); }
+inline void DThread::Stillborn()
+	{iNThread.Stillborn();Release();}
+
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+inline TBool DThread::HasCapability(TCapability aCapability, const char* aDiagnosticText)
+	{
+	return DoHasCapability(aCapability, aDiagnosticText);
+	}
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+// Only available to NULL arguments
+inline TBool DThread::HasCapability(TCapability aCapability, OnlyCreateWithNull /*aDiagnostic*/)
+	{
+	return DoHasCapability(aCapability);
+	}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+#define TheCurrentThread	_LOFF(NCurrentThread(),DThread,iNThread)
+
+class TLogon : public TClientRequest
+	{
+public:
+	enum TType
+		{
+		ETargetThread=0,
+		ETargetProcess=1,
+		ERendezvous=0x80,
+		};
+	TInt Attach(SDblQue& aList, DThread* aOwner, DObject* aTarget, TRequestStatus* aStatus, TUint32 aType);
+	static TInt Cancel(SDblQue& aList, DObject* aTarget, TRequestStatus* aStatus, TUint32 aType);
+
+	enum TComplete { ETargetRendezvous, ETarget, EOwned };
+	static void CompleteAll(SDblQue& aList, TComplete aAction, TInt aReason);
+
+	static NFastMutex LogonLock;
+
+private:
+	inline static void Lock()
+		{ NKern::FMWait(&LogonLock); }
+	inline static void Unlock()
+		{ NKern::FMSignal(&LogonLock); }
+
+	TUint32 iType;
+	inline TBool IsRendezvous()
+		{ return (iType & ERendezvous); }
+
+	DThread* iOwningThread;
+	DObject* iTarget;
+	SDblQueLink iOwningThreadLink;
+	SDblQueLink iTargetLink;
+private:
+	~TLogon();					// call Close(), don't delete
+	};
+
+/********************************************
+ * Platform-independent chunk type abstraction
+ ********************************************/
+enum TChunkType
+	{
+	// these never change or move or anything
+	EKernelData = 0,	// Supervisor,Rw,Cacheable
+	EKernelStack = 1,	// Supervisor,Rw,Cacheable
+	EKernelCode = 2,	// Supervisor,Rw,Cacheable
+	EDll = 3,			// User,Ro,Cacheable
+	EUserCode = 4,
+
+	// This changes on a PDE basis when the file server runs
+	ERamDrive = 5,		// Supervisor,Rw,Cacheable
+
+	// these change on PDE basis when run
+	EUserData = 6,
+	EDllData = 7,
+	EUserSelfModCode = 8,
+
+	ESharedKernelSingle = 9,		// Must be same value as TChunkCreateInfo::ESharedKernelSingle
+	ESharedKernelMultiple = 10,		// Must be same value as TChunkCreateInfo::ESharedKernelMultiple
+
+	ESharedIo = 11,
+	ESharedKernelMirror = 12,
+
+	EKernelMessage = 13,			// Dedicated chunk for RMessageK objects
+
+	ENumChunkTypes	// Keep as last value
+	};
+
+/********************************************
+ * Chunk creation info block
+ ********************************************/
+struct SChunkCreateInfo
+	{
+	enum {EAdjust=1, EAdd=2};	// iOperations
+
+	TBool iGlobal;
+	TInt iAtt;				// Set with values from TChunkCreate::TChunkCreateAtt NOT DChunk::TChunkAttributes
+	TBool iForceFixed;
+	TUint iOperations;
+	TLinAddr iRunAddress;
+	TChunkType iType;
+	TInt iMaxSize;
+	TInt iInitialBottom;
+	TInt iInitialTop;
+	TInt iPreallocated;
+	TPtrC iName;
+	DObject* iOwner;
+	TUint32 iMapAttr;
+	TDfc* iDestroyedDfc;
+	TUint8 iClearByte;
+public:
+	SChunkCreateInfo();
+	};
+
+/** The different types of pages that the allocator should consider
+*/
+enum TZonePageType
+	{
+	EPageUnknown = 0, /**<Pages that are at physical addresses the kernel has no knowledge of*/ 
+	EPageFixed,		/**<Pages that shouldn't be physically moved*/
+	EPageMovable,	/**<Pages that may be physically moved*/
+	EPageDiscard,	/**<Pages that may be removed*/
+	EPageTypes		/**<The no of different page types*/
+	};
+
+/********************************************
+ * Chunk control block
+ ********************************************/
+class DChunk : public DObject
+	{
+public:
+	/**
+	@see DMemModelChunk::TMemModelChunkAttributes for memory model specific attribute flags
+	*/	
+	enum TChunkAttributes
+		{
+		ENormal			=0x00,
+		EDoubleEnded	=0x01,
+		EDisconnected	=0x02,
+		EConstructed	=0x04,
+		EMemoryNotOwned	=0x08,
+		ETrustedChunk	=0x10,
+		EDataPaged		=0x20,		// Set when the chunk is data paged.
+		ECache			=0x40,
+		EReadOnly		=0x80,
+		EChunkAttributesMask = 0xff,
+		};
+
+	enum TCommitType
+		{
+		ECommitDiscontiguous			= 0,
+		ECommitContiguous				= 1,
+		ECommitPhysicalMask				= 2,
+		ECommitDiscontiguousPhysical	= ECommitDiscontiguous|ECommitPhysicalMask,
+		ECommitContiguousPhysical		= ECommitContiguous|ECommitPhysicalMask,
+		ECommitVirtual					= 4,  // only supported by moving and multiple memory models on arm
+		};
+
+	enum TDecommitType
+		{
+		EDecommitNormal					= 0,
+		EDecommitVirtual				= 1,
+		};
+	
+	DChunk();
+	~DChunk();
+	TInt Create(SChunkCreateInfo& aInfo);
+	inline TInt Size() const {return iSize;}
+	inline TInt MaxSize() const {return iMaxSize;}
+#ifndef __MEMMODEL_FLEXIBLE__
+	inline TUint8 *Base() const {return iBase;}
+#endif
+	inline TInt Bottom() const {return iStartPos;}
+	inline TInt Top() const {return iStartPos+iSize;}
+	inline DProcess* OwningProcess() const {return iOwningProcess;}
+protected:
+	virtual void SetPaging(TUint aCreateAtt);
+public:
+	virtual TInt AddToProcess(DProcess* aProcess);
+	virtual TInt DoCreate(SChunkCreateInfo& aInfo)=0;
+	virtual TInt Adjust(TInt aNewSize)=0;
+	virtual TInt AdjustDoubleEnded(TInt aBottom, TInt aTop)=0;
+	virtual TInt CheckAccess()=0;
+	virtual TInt Commit(TInt aOffset, TInt aSize, TCommitType aCommitType=DChunk::ECommitDiscontiguous, TUint32* aExtraArg=0)=0;
+	virtual TInt Allocate(TInt aSize, TInt aGuard=0, TInt aAlign=0)=0;
+	virtual TInt Decommit(TInt aOffset, TInt aSize)=0;
+	virtual TInt Lock(TInt aOffset, TInt aSize)=0;
+	virtual TInt Unlock(TInt aOffset, TInt aSize)=0;
+	virtual TInt Address(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress)=0;
+	virtual TInt PhysicalAddress(TInt aOffset, TInt aSize, TLinAddr& aKernelAddress, TUint32& aPhysicalAddress, TUint32* aPhysicalPageList=NULL)=0;
+ 	virtual void BTracePrime(TInt aCategory);
+	virtual void Substitute(TInt aOffset, TPhysAddr aOldAddr, TPhysAddr aNewAddr)=0;
+	virtual TUint8* Base(DProcess* aProcess)=0;
+public:
+	DProcess* iOwningProcess;	// NULL for global chunks
+	TInt iSize;					// always the committed size (i.e. gaps not included)
+	TInt iMaxSize;
+#ifndef __MEMMODEL_FLEXIBLE__
+	TUint8* iBase;
+#else
+	TLinAddr iFixedBase;
+#endif
+	TInt iAttributes;
+	TInt iStartPos;				// start of committed area for double-ended chunks
+	TUint iControllingOwner;	// ProcessID of process which set protection
+	TUint iRestrictions;
+	TUint iMapAttr;				// only for shared kernel chunks
+	TDfc* iDestroyedDfc;
+	TChunkType iChunkType;
+	TUint8 iClearByte;			// The byte value to clear all memory committed to the chunk to.
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Platform security
+ ********************************************/
+
+/**
+@deprecated
+*/
+#define __SECURE_KERNEL(p) { p; };
+
+/**
+@deprecated
+*/
+#define __KERNEL_CAPABILITY_CHECK(p) { p; };
+
+/** TCompiledSecurityPolicy uses the upper two bits in iCaps to store a reduced
+version of TSecurityPolicy's iType.  This constant is the number of free bits.
+@internalTechnology
+*/
+const TUint32 KCSPBitsFree = 30;
+
+/** TCompiledSecurityPolicy can only represent capabilities less than
+KCSPBitsFree-1 
+*/
+__ASSERT_COMPILE(ECapability_Limit <= KCSPBitsFree);
+
+/** A precompiled security policy useful for fast checking of policies.
+@internalComponent
+*/
+class TCompiledSecurityPolicy
+	{
+public:
+	enum TType
+		{
+		ETypeFail = 0,
+		ETypeCapsOnly = 1,
+		ETypeSecureId= 2,
+		ETypeVendorId= 3,
+		};
+	enum TMask
+		{
+		EMaskFail = ETypeFail << KCSPBitsFree, 
+		EMaskCapsOnly = ETypeCapsOnly << KCSPBitsFree,
+		EMaskSecureId = ETypeSecureId << KCSPBitsFree,
+		EMaskVendorId = ETypeVendorId << KCSPBitsFree,
+		};
+	TInt Set(const TSecurityPolicy& aPolicy);
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	inline TBool CheckPolicy(DProcess* aProcess, const char* aDiagnostic=0) const
+		{
+		return DoCheckPolicy(aProcess, aDiagnostic);
+		}
+
+	inline TBool CheckPolicy(DThread* aThread, const char* aDiagnostic=0) const
+		{
+		return DoCheckPolicy(aThread, aDiagnostic);
+		}
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// Only available to NULL arguments
+	inline TBool CheckPolicy(DProcess* aProcess, OnlyCreateWithNull /*aDiagnostic*/=NULL) const
+		{
+		return DoCheckPolicy(aProcess);
+		}
+
+	inline TBool CheckPolicy(DThread* aThread, OnlyCreateWithNull /*aDiagnostic*/=NULL) const
+		{
+		return DoCheckPolicy(aThread);
+		}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+private:
+#ifndef __REMOVE_PLATSEC_DIAGNOSTICS__
+	TBool DoCheckPolicy(DProcess* aProcess, const char* aDiagnostic) const;
+	TBool DoCheckPolicy(DThread* aThread, const char* aDiagnostic) const;
+#endif // !__REMOVE_PLATSEC_DIAGNOSTICS__
+	TBool DoCheckPolicy(DProcess* aProcess) const;
+	TBool DoCheckPolicy(DThread* aThread) const;
+
+	TBool CheckPolicy(const SSecurityInfo& aSecInfo, SSecurityInfo& aMissing) const;
+	void AddCapability(TCapability aCap);
+
+	inline void SetETypeFail() { /* Yes, it's a NOP */iCaps |= EMaskFail; }
+	inline void SetETypePass() { iCaps |= EMaskCapsOnly; }
+	inline void SetETypeCapsOnly() { iCaps |= EMaskCapsOnly; }
+	inline void SetETypeSecureId() { iCaps |= (TUint32)EMaskSecureId; }
+	inline void SetETypeVendorId() { iCaps |= (TUint32)EMaskVendorId; }
+
+	inline TUint32 Caps() const { return iCaps & ~EMaskVendorId; }
+	inline TUint32 Type() const { return iCaps >> KCSPBitsFree; }
+	union
+		{
+		TUint32 iSecureId;
+		TUint32 iVendorId;
+		};
+	TUint32 iCaps;
+	};
+
+ /********************************************
+ * Process control block
+ ********************************************/
+struct SCodeSegEntry
+	{
+	DCodeSeg* iSeg;		// code segment in use
+	DLibrary* iLib;		// client representation object (DLibrary or DxxDevice)
+	};
+
+class DProcess : public DObject
+	{
+public:
+	/** Possible values for bitmask specifying how to iterate dependency graph.
+		@see TraverseCodeSegs
+		@publishedPartner
+		@released
+	 */
+	enum TTraverseFlags 
+		{
+		/** Add code segment to queue if set, remove it if cleared */
+		ETraverseFlagAdd=1,  	
+		/** Restrict iteration to dynamic dependencies in ELoaded state if set, 
+		    iterate everything if cleared */
+		ETraverseFlagRestrict=2	
+		};
+public:
+	DProcess();
+	~DProcess();
+	TInt Create(TBool aKernelProcess, TProcessCreateInfo& aInfo, HBuf* aCommandLine);
+	TInt SetPriority(TProcessPriority aPriority);
+	TInt ConvertPriority(TProcessPriority aPriority);
+	void Destruct();
+	TInt Rename(const TDesC& aName);
+	TInt Logon(TRequestStatus* aStatus, TBool aRendezvous);
+	void Rendezvous(TInt aReason);
+	IMPORT_C TInt TraverseCodeSegs(SDblQue* aQ, DCodeSeg* aExclude, TUint32 aMark, TUint32 aFlags);
+	TInt OpenDeps();
+	TInt AddCodeSeg(DCodeSeg* aSeg, DLibrary* aLib, SDblQue& aQ);
+	void RemoveCodeSeg(DCodeSeg* aCodeSeg, SDblQue* aQ);
+	TInt CallList(SDblQue& aQ, DCodeSeg* aSeg, TUint32 aFlag);
+	DCodeSeg* CodeSeg();
+	TBool HasCapabilityNoDiagnostic(TCapability aCapability);
+	inline TBool HasCapability(/*TInt aCapability*/);
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	inline TBool HasCapability(TCapability aCapability, const char* aDiagnosticText=0);
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// Only available to NULL arguments
+	inline TBool HasCapability(TCapability aCapability, OnlyCreateWithNull aDiagnostic=NULL);
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+private:
+	IMPORT_C TBool DoHasCapability(TCapability aCapability, const char* aDiagnostic);
+	IMPORT_C TBool DoHasCapability(TCapability aCapability);
+protected:
+	virtual TInt SetPaging(const TProcessCreateInfo& aInfo);
+public:
+	virtual void DoAppendName(TDes& aName);
+	virtual TInt NewChunk(DChunk*& aChunk, SChunkCreateInfo& aInfo, TLinAddr& aRunAddr)=0;
+	virtual TInt AddChunk(DChunk* aChunk,TBool isReadOnly)=0;
+	virtual TInt NewShPool(DShPool*& aPool, TShPoolCreateInfo& aInfo)=0;
+	virtual TInt DoCreate(TBool aKernelProcess, TProcessCreateInfo& aInfo)=0;
+	virtual TInt AttachExistingCodeSeg(TProcessCreateInfo& aInfo)=0;
+	virtual TInt Loaded(TProcessCreateInfo& aInfo);
+	virtual void FinalRelease()=0;
+public:
+	TInt NewThread(DThread*& aThread, SThreadCreateInfo& aInfo, TInt* aHandle, TOwnerType aType);
+	virtual void Resume();
+	void Die(TExitType aType,TInt aReason,const TDesC &aCategory);
+	virtual void Release();
+	TBool KillAllThreads(TExitType aType, TInt aReason, const TDesC &aCategory);
+
+public:
+	virtual TInt GetNewThread(DThread*& aThread, SThreadCreateInfo& aInfo)=0;
+	virtual TInt CreateDataBssStackArea(TProcessCreateInfo& aInfo)=0;
+	virtual TInt MapCodeSeg(DCodeSeg* aCodeSeg)=0;
+	virtual void UnmapCodeSeg(DCodeSeg* aCodeSeg)=0;
+	virtual void RemoveDllData()=0;
+	virtual void BTracePrime(TInt aCategory);
+public:
+	TInt WaitProcessLock();
+	TInt SignalProcessLock();
+	TInt WaitDllLock();
+	void SignalDllLock();
+	void AddThread(DThread &aThread);
+#ifdef __SMP__
+	TInt UpdateSMPSafe();
+#endif
+	inline DThread* FirstThread()
+		{ return _LOFF(iThreadQ.First(),DThread,iProcessLink); }
+public:
+	TInt iPriority;
+	SDblQue iThreadQ;
+	TUint8 iExitType;
+	TUint8 iFinalReleaseFlag;
+	TUint8 iPad2;
+	TUint8 iDebugAttributes;
+	TInt iExitReason;
+	TBufC<KMaxExitCategoryName> iExitCategory;
+	RObjectIx iHandles;
+	TUidType iUids;
+	TInt iGeneration;
+	TUint iId;
+	TUint32 iFlags;
+	HBuf* iCommandLine;
+	DProcess* iOwningProcess;
+	SDblQue iTargetLogons;
+	RArray<SCodeSegEntry> iDynamicCode;
+//	RPointerArray<DLibrary> iDynamicCode;
+	SSecurityInfo iS;
+	SSecurityInfo iCreatorInfo;
+	TUint iCreatorId;
+	TUint iSecurityZone;
+	TInt iEnvironmentData[KArgIndex];
+
+public:
+	enum TProcessAttributes	{
+							EPrivate		= 0x00000002,
+							ESupervisor		= (TInt)0x80000000,
+							EBeingLoaded	= 0x08000000,
+							EResumed		= 0x00010000,
+							EDataPaged 		= 0x00000004,	// Set when the process is data paged
+							};
+	TInt iAttributes;
+	TLinAddr iDataBssRunAddress;
+	DChunk* iDataBssStackChunk;
+	DCodeSeg* iCodeSeg;
+	DCodeSeg* iTempCodeSeg;
+	DMutex* iProcessLock;
+	DMutex* iDllLock; // can be held while in user mode 
+	TLinAddr iReentryPoint;	// user address to jump to for new threads, exceptions
+	SDblQue iGarbageList;	// list of DLibrary containing code which will be unmapped later
+	TInt iThreadsLeaving; // count of threads currently leaving [only w/C++ exceptions]
+	TInt iUserThreadsRunning; // count of running user threads that have not yet called User::Exit
+	volatile TInt iSMPUnsafeCount;   // count of top level codesegs that are SMP unsafe
+							         // i.e. the exe itself or things RLibrary::Load'ed - not deps
+#ifdef __SMP__
+	NThreadGroup* iSMPUnsafeGroup;	// group used to keep unsafe threads scheduled together
+#endif
+public:
+	friend class Monitor;
+
+	};
+
+inline TBool DProcess::HasCapabilityNoDiagnostic(TCapability aCapability)
+	{
+	if(aCapability==ECapability_None)
+		return ETrue;
+	if((TUint32)aCapability<(TUint32)ECapability_Limit)
+		return (iS.iCaps[aCapability>>5]>>(aCapability&31))&1;
+	return EFalse;
+	}
+
+inline TBool DProcess::HasCapability(/*TInt aCapability*/)
+	{ return iS.iCaps[0]!=~1u; } // Always return true for now
+
+inline TBool DThread::HasCapability(/*TInt aCapability*/)
+	{ return iOwningProcess->HasCapability(/*aCapability*/); }
+ 
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+inline TBool DProcess::HasCapability(TCapability aCapability, const char* aDiagnosticText)
+	{
+	return DoHasCapability(aCapability, aDiagnosticText);
+	}
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+// Only available to NULL arguments
+inline TBool DProcess::HasCapability(TCapability aCapability, OnlyCreateWithNull /*aDiagnostic*/)
+	{
+	return DoHasCapability(aCapability);
+	}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+
+/********************************************
+ * Session control block
+ ********************************************/
+class DServer;
+class DSession : public DObject
+	{
+public:
+	DSession();
+	virtual ~DSession();
+	TInt Add(DServer* aSvr, const TSecurityPolicy* aSecurityPolicy);
+	void Transfer(DServer* aServer, RMessageK* aMsg);
+	TInt MakeHandle();
+	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
+	virtual TInt Close(TAny*);
+	void Detach(TInt aReason);
+	void CloseFromDisconnect();
+	inline TBool IsClosing();
+	inline void TotalAccessInc()
+		{__ASSERT_SYSTEM_LOCK; iTotalAccessCount++;};
+	TInt TotalAccessDec();
+	TInt TotalAccessDecRel();
+	void BTracePrime(TInt aCategory);
+
+public:
+	// Static methods called from exec handlers
+	static TInt New(DSession*& aS, TInt aMsgSlots, TInt aMode);
+	static TInt Send(TInt aHandle, TInt aFunction, const TInt* aPtr, TRequestStatus* aStatus);
+	static TInt SendSync(TInt aHandle, TInt aFunction, const TInt* aPtr, TRequestStatus* aStatus);
+
+private:
+	TInt Send(RMessageK* aMsg, TInt aFunction, const RMessageK::TMsgArgs* aArgs, TRequestStatus* aStatus);
+	RMessageK* GetNextFreeMessage();
+
+public:
+	DServer* 		iServer;				// pointer to kernel-side server object
+	SDblQueLink 	iServerLink;			// link to attach session to server
+	const TAny* 	iSessionCookie;			// pointer to server-side CSession2 (user cookie)
+	TUint8 			iSessionType;			// TIpcSessionType
+	TUint8 			iSvrSessionType;		// TIpcSessionType
+	TUint8 			iHasSessionPool;		// TIpcSessionType
+	TUint8	 		iTotalAccessCount;		// all client accesses together contribute 1, modify with system locked
+	TInt 			iPoolSize;				// number of messages in private pool
+	TInt 			iMsgCount;				// total number of outstanding messages on this session
+	TInt 			iMsgLimit;				// maximum number of outstanding messages on this session
+	SDblQue 		iMsgQ;					// queue of all outstanding messages on this session (by iSessionLink)
+	RMessageK*		iDisconnectMsgPtr;		// preallocated disconnect message
+	RMessageK* volatile	iConnectMsgPtr;		// pointer to connect message, if any
+	RMessageK* volatile	iNextFreeMessage;	// pointer to next free message in per-session message pool, if any
+	};
+
+inline TBool DSession::IsClosing()
+	{ return !AccessCount(); }
+
+/********************************************
+ * Server control block
+ ********************************************/
+
+class TServerMessage : public TClientRequest
+	{
+public:
+	TServerMessage();
+private:
+	static void CallbackFunc(TAny* aData, TUserModeCallbackReason aReason);
+private:
+	TAny* iMessagePtr;					// where to deliver messages
+	RMessageK* iMessageData;			// message to deliver
+	friend class DServer;
+private:
+	~TServerMessage();					// call Close(), don't delete
+	};
+
+class DServer : public DObject
+	{
+public:
+	DServer();
+	TInt Create();
+	virtual ~DServer();
+	virtual TInt Close(TAny*);
+	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
+	void Receive(TRequestStatus& aStatus, TAny* aMessage);	// aMessage bit 0 = 0 -> RMessage, bit 0 = 1 -> RMessage2
+	void Cancel();
+	void Accept(RMessageK* aMsg);
+	void Deliver(RMessageK* aMsg);
+	void BTracePrime(TInt aCategory);
+public:
+	inline TBool IsClosing();
+public:
+	DThread*		iOwningThread;		// thread which receives messages
+	TServerMessage*	iMessage;
+	SDblQue			iSessionQ;			// list of sessions
+	SDblQue			iDeliveredQ;		// list of messages delivered but not yet accepted
+	TUint8			iSessionType;		// TIpcSessionType
+	TUint8 			iPinClientDescriptors;	// Set to 1 to make the server pin client descriptor 
+										// arguments it receives, 0 otherwise.
+	TUint8 			iServerRole;		// TIpcServerRole: Standalone, Master, or Slave?
+	TUint8 			iPadding;
+	};
+
+inline TBool DServer::IsClosing()
+	{ return !AccessCount(); }
+
+
+struct TCodeSegLoaderCookieList
+	{
+	TCodeSegLoaderCookieList* iNext;
+	TCodeSegLoaderCookie iCookie;
+	};
+
+/********************************************
+ * Code segment
+ ********************************************/
+
+/** Code segment
+
+	Low-level abstraction describing an executable or DLL used by one or more
+	processes.  Higher-level abstraction (DLibrary, DPhysicalDevice,
+	DLogicalDevice and DProcess) use code segments internally.
+
+	Each code segment maintains a table of all code segments it directly
+	depends on, thus forming a dependency graph.
+
+	Note that dependency information about ROM-based DLLs without static 
+	data is lost during the ROM building process.  Therefore These DLLs are not
+	included in the dependency graph.
+
+	@internalTechnology
+ */
+
+class DCodeSeg : public DBase
+	{
+public:
+	/** Possible values for DCodeSeg::iMark bitmask.
+		All values except explicitly specified are reserved for internal 
+		kernel use.
+	 */
+	enum TMark
+		{
+		EMarkListDeps=0x01,
+		EMarkUnListDeps=0x02,
+		EMarkLdr=0x04,
+		EMarkProfilerTAG=0x08,			// used by profiler tool to mark processed non-XIP objects.
+		EMarkLoaded=0x10,				// this code segment is reloadable
+		EMarkRecursiveFlagsValid=0x20,	// the recursively computed bits are valid
+		EMarkRecursiveFlagsCheck=0x40,	// the recursively computed bits are being checked or are valid
+		EMarkData=0x04000000u,			// image has data and is not extension or variant (=KRomImageFlagData)
+		EMarkDataInit=0x02000000u,		// graph below and including image requires user init (=KRomImageFlagDataInit)
+		EMarkDataPresent=0x01000000u,	// graph below and including image has data (=KRomImageFlagDataPresent)
+		EMarkDebug=0x08000000u,			// reserved for debug agents
+		};
+public:
+	DCodeSeg();
+	void Destruct();
+	inline void Open() {++iAccessCount;}
+	void Close();
+	void CheckedClose();
+	void CheckedOpen();
+	void WaitCheckedOpen();
+	TInt Create(TCodeSegCreateInfo& aInfo, DProcess* aProcess);
+	TInt ListDeps(SDblQue* aQ, TUint32 aMark);
+	TInt UnListDeps(TUint32 aMark);
+	TInt MarkAndOpenDeps(TUint32 aMark);
+	void FinaliseRecursiveFlags();
+	void CalcRecursiveFlags();
+	void SetAttachProcess(DProcess* aProcess);
+public:
+// virtual
+	virtual void Info(TCodeSegCreateInfo& aInfo);
+	virtual TInt Loaded(TCodeSegCreateInfo& aInfo);
+	virtual TInt AddDependency(DCodeSeg* aExporter);
+	virtual void BTracePrime(TInt aCategory);
+// Pure virtual
+	virtual TLibraryFunction Lookup(TInt aOrdinal) =0;
+	virtual TInt GetMemoryInfo(TModuleMemoryInfo& aInfo, DProcess* aProcess) =0;
+	virtual TInt DoCreate(TCodeSegCreateInfo& aInfo, DProcess* aProcess)=0;
+	virtual void InitData()=0;
+	virtual void ReadExportDir(TUint32* aDest)=0;
+	virtual TBool FindCheck(DProcess* aProcess)=0;
+	virtual TBool OpenCheck(DProcess* aProcess)=0;
+public:
+	static void Wait();
+	static void Signal();
+	IMPORT_C static DCodeSeg* VerifyHandle(TAny* aHandle);
+	static DCodeSeg* VerifyHandleP(TAny* aHandle);
+	static DCodeSeg* VerifyCallerAndHandle(TAny* aHandle);
+	static DCodeSeg* FindCodeSeg(const TFindCodeSeg& aFind);
+	static DCodeSeg* FindRomCode(const TAny* aRomImgHdr);
+	IMPORT_C static void UnmarkAll(TUint32 aMask);
+	static void UnmarkAndCloseAll(TUint32 aMask);
+	static TInt ListMarked(SDblQue& aQ, TUint32 aMask);
+	IMPORT_C static void EmptyQueue(SDblQue& aQ, TUint32 aMask);
+	static void EmptyGarbageList();
+	static void DeferDeletes();
+	static void EndDeferDeletes();
+	static TInt WriteCallList(SDblQue& aList, TLinAddr* aEpList, TBool aInitData);
+	IMPORT_C static DCodeSeg* CodeSegFromEntryPoint(TInt aEntryPoint);
+	static void DoKernelCleanup(TAny*);
+	void ScheduleKernelCleanup(TBool aImmed);
+	static void QueueKernelCleanup();
+	static void DeferKernelCleanup();
+	static void EndDeferKernelCleanup();
+	void AppendFullRootName(TDes& aDes);
+	void AppendFullFileName(TDes& aDes);
+	void AppendVerExt(TDes& aDes);
+	void TraceAppendFullName(TDes& aDes);
+	TLinAddr ExceptionDescriptor();
+public:
+	inline TBool IsDll() const
+		{return iUids.iUid[0].iUid==KDynamicLibraryUidValue;}
+	inline TBool IsExe() const
+		{return iUids.iUid[0].iUid==KExecutableImageUidValue;}
+public:
+	SDblQueLink iLink;		// link to global list
+	SDblQueLink iTempLink;	// temporary link for computing lists
+	SDblQueLink iGbgLink;	// link to garbage list
+	TUint32 iGbgIdleGenerationCount;
+	TInt iAccessCount;
+	TLinAddr iEntryPtVeneer;	// address of first instruction to be called
+	TLinAddr iFileEntryPoint;	// address of entry point within this code segment
+	HBuf* iFileName;		// Full path name
+	TPtrC iRootName;		// Filename.Ext - points into iFileName
+	TInt iExtOffset;		// Offset of extension in iFileName
+	TUidType iUids;
+	DCodeSeg** iDeps;		// code segments on which this one depends (not reference counted)
+	TInt iDepCount;			// number of dependencies
+	TInt iNextDep;
+	TUint32 iMark;
+	TUint32 iAttr;
+	DCodeSeg* iExeCodeSeg;		// EXE code segment with which this can be used
+	DProcess* iAttachProcess;	// Process with which this can be used (NULL if several)
+	TUint32 iModuleVersion;
+	SSecurityInfo iS;
+	TLinAddr iRunAddress;
+	TUint32 iSize;
+	
+public:
+	static SDblQue GlobalList;			// list of all existing DCodeSeg
+	static SDblQue GarbageList;			// list of DCodeSeg whose deletion is pending due to DeferDeletes()
+	static SDblQue KernelGarbageList;   // list of DCodeSeg containing kernel code which will be unmapped when the system goes idle
+	static SDblQue DeferredKernelGarbageList;
+	static TDfc KernelCleanupDfc;
+	static TInt KernelCleanupLock;
+	static DMutex* CodeSegLock;
+	static TInt DeleteLock;
+	static RPointerArray<DCodeSeg> CodeSegsByName;		// list of code segments in name order
+
+	class RCodeSegsByAddress
+		{
+	public:
+		RCodeSegsByAddress(TInt aMinGrowBy, TInt aFactor);
+		TInt Add(DCodeSeg* aCodeSeg);
+		TInt Remove(DCodeSeg* aCodeseg);
+		DCodeSeg* Find(TLinAddr aAddress);
+	private:
+		static TInt Compare(const DCodeSeg& aA, const DCodeSeg& aB);
+	private:
+		TInt iActive;
+		RPointerArray<DCodeSeg> iArray[2];
+		};
+	static RCodeSegsByAddress CodeSegsByAddress;	// list of code segments in run address order
+	static TClientRequest* DestructNotifyRequest;	// Used to complete NotifyIfCodeSegDestroyed
+	static DThread* DestructNotifyThread;			// Used to complete NotifyIfCodeSegDestroyed
+	static TCodeSegLoaderCookieList* DestructNotifyList; //Used to hold the list of cookie for destroyed codsegs.
+	};
+
+/********************************************
+ * Library control block
+ ********************************************/
+class DLibrary : public DObject
+	{
+public:
+	enum TState
+		{
+		ECreated=0,			// initial state
+		ELoaded=1,			// code segment loaded
+		EAttaching=2,		// calling constructors
+		EAttached=3,		// all constructors done
+		EDetachPending=4,	// about to call destructors
+		EDetaching=5,		// calling destructors
+		};
+public:
+	static TInt New(DLibrary*& aLib, DProcess* aProcess, DCodeSeg* aSeg);
+	DLibrary();
+	void RemoveFromProcess();
+	void ReallyRemoveFromProcess();
+    virtual ~DLibrary();
+	virtual TInt Close(TAny* aPtr);
+	virtual TInt AddToProcess(DProcess* aProcess);
+	virtual void DoAppendName(TDes& aName);
+public:
+	TInt iMapCount;
+	TUint8 iState;
+	SDblQueLink iThreadLink;	// attaches to opening or closing thread
+	DCodeSeg* iCodeSeg;
+	SDblQueLink iGbgLink;
+	};
+
+/********************************************
+ * Change notifier control block
+ ********************************************/
+class DChangeNotifier : public DObject
+	{
+public:
+	DChangeNotifier();
+	~DChangeNotifier();
+	TInt Create();
+	void Notify(TUint aChanges);
+	TInt Logon(TRequestStatus& aStatus, DThread* aThread);
+	TInt LogonCancel(DThread* aThread);
+	void Complete(TInt aResult);
+public:
+	TUint iChanges;
+	TClientRequest* iRequest;	
+	DThread* iThread;
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Undertaker control block
+ ********************************************/
+
+class DUndertaker : public DObject
+	{
+public:
+	TInt Create();
+	~DUndertaker();
+	void Notify(DThread* aDeadThread);
+	TInt Logon(TRequestStatus *aStatus, TInt* aDeadThreadHandle);
+	TInt LogonCancel();
+	void Complete(TInt aValue, DThread* aDeadThread);
+public:
+	TClientDataRequest<TInt>* iRequest;
+	DThread* iOwningThread;
+public:
+	friend class Monitor;
+	};
+
+/********************************************
+ * Shared Io Buffers
+ ********************************************/
+
+/**
+@publishedPartner
+@released
+
+	A kernel object for sharing memory between kernel code and user space code.
+	
+	It is used to avoid an extra copy when handling large amounts of data between
+	kernel and user space code. Used in device drivers that will handle instances
+	of this class and pass pointers to the buffer to user space clients.
+	Each buffer can be mapped into a single process.
+	The lifetime of this object is maintained by the device driver.
+	These objects are intended for use where speed is essential, such as for
+	streaming media data.
+*/
+class DSharedIoBuffer : public DBase
+	{
+public:
+    /**
+    @internalComponent
+    */
+	enum TPanic
+		{
+		EAlreadyCreated=1,
+		EAlreadyMapped
+		};
+	IMPORT_C ~DSharedIoBuffer();
+	IMPORT_C static TInt New(DSharedIoBuffer*& aBuffer, TUint32 aSize, TUint aAttribs);
+#if defined(__EPOC32__)
+	IMPORT_C static TInt New(DSharedIoBuffer*& aBuffer, TPhysAddr aPhysAddr, TUint32 aSize, TUint aAttribs);
+#endif
+	IMPORT_C TInt UserMap(DProcess* aUserProcess);
+	IMPORT_C TInt UserUnmap();
+	IMPORT_C TLinAddr UserToKernel(TLinAddr aUserAddress, TUint32 aSize);
+	IMPORT_C TLinAddr KernelToUser(TLinAddr aKernelAddress);
+public:
+  	/**
+	The address of the shared buffer that code running on the kernel side uses
+	to access the buffer.
+	
+	@see DSharedIoBuffer::UserToKernel()
+    @see DSharedIoBuffer::KernelToUser()
+	*/
+	TLinAddr iAddress;
+	
+	/**
+    The size of the shared buffer.
+    
+    After mapping the buffer into the user-side address space via a call
+    to DSharedIoBuffer::UserMap(), this value must be returned to
+    the user-side via normal logical channel operations so that user
+    code can start using the buffer. 
+    
+    @see DSharedIoBuffer::UserMap()
+	*/
+	TUint32 iSize;
+	
+	/**
+	The address of the shared buffer that code running in the user process
+	will use to access that buffer.
+    
+    After mapping the buffer into the user-side address space via a call
+    to DSharedIoBuffer::UserMap(), this value must be returned to
+    the user-side via normal logical channel operations so that user
+    code can start using the buffer.
+    
+    @see DSharedIoBuffer::UserMap() 
+    @see DSharedIoBuffer::UserToKernel()
+    @see DSharedIoBuffer::KernelToUser()
+	*/
+	TLinAddr iUserAddress;
+
+    /**
+    @internalComponent
+    */
+	DProcess* iUserProcess;
+private:
+    /**
+    @internalComponent
+    */
+	DChunk* iChunk;
+private:
+	TInt DoCreate(TUint32 aSize, TUint aAttribs);	/**< @internalComponent */
+	TInt DoCreate(TUint32 aPhysAddr, TUint32 aSize, TUint aAttribs);	/**< @internalComponent */
+private:
+	DSharedIoBuffer();	/**< @internalComponent */
+	};
+
+/********************************************
+ * System tick-based timer queues
+ ********************************************/
+/********************************************
+ * Timers based on the system tick
+ * Platform layer code
+ ********************************************/
+class TTickQ : public SDeltaQue
+	{
+public:
+	TTickQ();
+	void Tick();
+	static TInt Init();
+	static void Wait();
+	static void Signal();
+public:
+	// In platform layer
+	void Add(TTickLink* aLink, TInt aPeriod);
+	void StartTimer();
+	void Update();
+	void Synchronise();				// update everything as if a tick has just occurred
+	void Check();
+public:
+	TInt iLastDelta;				// delta ticks at next ms timer expiry
+	TUint32 iLastTicks;				// tick count at last expiry
+	Int64 iRtc;						// tick count acting as RTC (ticks from 00:00:00 01-01-0000 UTC)
+	TInt iTickPeriod;				// tick period in microseconds
+	TInt iTicksPerSecond;			// ticks per second, rounded up
+	TInt iNominalTickPeriod;		// nominal tick period in microseconds
+	TBool iInTick;
+	static DMutex* Mutex;
+public:
+	TInt iRounding;					// rounding applied to current ms timer in us
+	TInt iPrevRounding;				// rounding applied to last ms timer in us
+	TUint32 iLastMs;				// ms count at last expiry
+	TInt iMsTickPeriod;				// in microseconds
+	TDfc iTickDfc;
+	NTimer iMsTimer;
+	};
+
+class TSecondQ : public SDblQue
+	{
+public:
+	TSecondQ();
+	void Tick();
+	void WakeUp();
+	static void TickCallBack(TAny* aPtr);
+	static void WakeUpDfc(TAny* aPtr);
+public:
+	void Add(TSecondLink* aLink);
+	void StartTimer();
+	TInt FirstDelta();
+	TTimeK WakeupTime();
+public:
+	TBool iInTick;
+	Int64 iNextTrigger;				// next trigger time in ticks from 00:00:00 01-01-0000 UTC
+	Int64 iMidnight;				// next midnight (home time) in ticks from 00:00:00 01-01-0000 UTC 
+	TInt iTicksPerDay;
+	TTickLink iTimer;
+	TDfc iWakeUpDfc;
+	};
+
+class TInactivityQ : public SDblQue
+	{
+public:
+	TInactivityQ();
+	void Reset();
+	TInt InactiveTime();
+public:
+	void Expired(TBool aTicksUpdated);
+	void EventDfc();
+	static void TimerCallBack(TAny* aPtr);
+	static void EventDfcFn(TAny* aPtr);
+public:
+	SDblQue iPending;
+	TUint32 iLastEventTime;
+	TBool iInTick;
+	TTickLink iTimer;
+	TDfc iEventDfc;
+	};
+
+
+/********************************************
+ * Kernel heap
+ ********************************************/
+class RHeapK : public RHeap
+	{
+public:
+	static RHeapK* FixedHeap(TAny* aBase, TInt aMaxLength);
+	TInt CreateMutex();
+	void Mutate(TInt aOffset, TInt aMaxLength);
+public:
+	RHeapK(TInt aInitialSize);
+	virtual TInt Compress();
+	virtual void Reset();
+	virtual TInt AllocSize(TInt& aTotalAllocSize) const;
+	virtual TInt Available(TInt& aBiggestBlock) const;
+public:
+	inline TInt TotalAllocSize() const
+		{ return iTotalAllocSize; }
+	static void CheckThreadState();
+	static void Fault(TInt aFault);
+	inline TBool CheckForSimulatedAllocFail()
+		{ return RHeap::CheckForSimulatedAllocFail(); }
+	inline DMutex* Mutex() const; /**< @internalComponent */
+public:
+	friend class Monitor;
+	};
+
+inline void RHeap::Lock() const
+	{
+	DMutex* m = *(DMutex**)&iLock;
+	if (m)
+		Kern::MutexWait(*m);
+	}
+
+inline void RHeap::Unlock() const
+	{
+	DMutex* m = *(DMutex**)&iLock;
+	if (m)
+		Kern::MutexSignal(*m);
+	}
+
+/**
+@internalComponent
+*/
+inline DMutex* RHeapK::Mutex() const
+	{ return *(DMutex**)&iLock;	}
+
+inline TInt RHeap::SetBrk(TInt aBrk)
+	{
+	return ((DChunk*)iChunkHandle)->Adjust(aBrk);
+	}
+
+enum TSecureClockStatusFlags 
+	{
+	ESecureClockPresent = 1,		// signals a trusted time source has been found 
+	ESecureClockOffsetPresent = 2,	// signals nonsecure offset was read from HAL
+	ESecureClockOk = ESecureClockPresent | ESecureClockOffsetPresent
+	};
+
+/**
+An unparsed descriptor header.
+
+@see TDesHeader.
+
+@prototype
+@internalTechnology
+*/
+class TRawDesHeader
+	{
+public:
+	const TUint32& operator[](TInt aIndex) const { return iData[aIndex]; }
+	TUint32& operator[](TInt aIndex) { return iData[aIndex]; }
+private:
+	TUint32 iData[3];
+	};
+
+/********************************************
+ * Functions defined in kernel layer 1
+ ********************************************/
+
+extern "C" {
+extern TLinAddr SuperPageAddress;
+}
+
+class DObjectCon;
+struct SExtInit1EntryPoint;
+class K
+	{
+public:
+	enum TFault
+		{
+		EBadPriListPriority=0,
+		EKillWhileCSLocked=1,
+		ESvrStraySignal=2,
+		ESvrBadMessage=3,
+		ESystemThreadPanic=4,
+		EThreadDiedInCS=5,
+		ECodeDependenciesInconsistent=6,
+		EUnTrapWithoutTrap=7,
+		EThrdEventHookDied=8,
+		ECreateEventQueueFailed=9,
+		EInvalidDfcPriority=10,
+		EMessageBadWriteAddress=11,
+		EMessageAlreadyPending=12,
+		EKernelMsgNotFree=13,
+		EKernelMsgNotAccepted=14,
+		EPanicWhileKernelLocked=15,
+		EPoweredChannelNoDfcQ=16,
+		EKernelHeapCorrupted=17,
+		EBadObjectType=18,
+		ESessionDestruct=19,
+		EMessageNotFree=20,
+		ESessionCreateBadServerTAC=21,
+		ESessionDestructMsgCount=22,
+		EServerDestructMsgCount=23,
+		EServerDestructSessionsRemain=24,
+		EServerDestructMessagesRemain=25,
+		EServerCloseLeftoverMsg=26,
+		EInvalidSessionAccessCount=27,
+		EMsgFreeBadPool=28,
+		ESessionDestructMsgQ=29,
+		EKHeapBadCellAddress=30,
+		EKHeapBadAllocatedCellSize=31,
+		EKHeapBadAllocatedCellAddress=32,
+		EKHeapBadFreeCellAddress=33,
+		EKHeapFreeBadNextCell=34,
+		EKHeapFreeBadPrevCell=35,
+		EKHeapReAllocBadNextCell=36,
+		EKHeapAllocSizeNegative=37,
+		EKHeapReAllocSizeNegative=38,
+		EKHeapDebugUnmatchedCallToCheckHeap=39,
+		EKHeapAllocCheckFailed=40,
+		ETickQNotLocked=41,
+		ELogicalChannelMsgUncompleted=42,
+		ESessionDestructStillRef=43,
+		ETHeapMaxLengthNegative=44,
+		ETHeapMutateNotSame=45,
+		EKernLeaveNoTrap=46,
+		EProcResumeNotLoaded=47,
+		EMachineConfigMutexCreateFailed=48,
+		ERamDriveChunkCreateFailed=49,
+		EInitMicrokernelFailed=50,
+		EInit3Failed=51,
+		EStartExtensionsFailed=52,
+		ETBmaFreeNotAllocated=53,
+		ETBmaBlockAllocNotFree=54,
+		ETBmaBlockFreeNotAllocated=55,
+		ETBmaAllocConsecBadLength=56,
+		ERamDriveInitFailed=57,
+		EKernelHeapOperationWithKernelLocked=58,
+		EKernelHeapOperationNotCritical=59,
+		EWaitMsTimerNotIdle=60,
+		EThreadDieWhileExit=61,
+		EThreadSvKillNotDead=62,
+		EDeadThreadRunning=63,
+		EBadTimerType=64,
+		ESynchroniseMsDeltaTooBig=65,
+		EBadThreadPriority=66,
+		EMutexSignalWrongThread=67,
+		EMutexSignalBadState=68,
+		EMutexWaitBadState=69,
+		EMutexWaitBadWaitObj=70,
+		ESemSignalBadState=71,
+		ESemWaitBadState=72,
+		ESemWaitBadWaitObj=73,
+		EInvalidKernHeapCPtr=74,
+		ELibDestructBadMapCount=75,
+		ECodeStillMapped=76,
+		EProcessDataAddressInvalid=77,
+		ECodeSegBadExeCodeSeg=78,
+		ECodeSegAttachProcess=79,
+		EPermanentThreadExit=80,
+		EJitCrashHandlerCreation=81,
+		EMsqQueueLengthInvalid=82,
+		EProcessFromIdNoLock=83,
+		EThreadFromIdNoLock=84,
+		EMutexWaitNotInCs=85,
+		EMutexSignalNotInCs=86,
+		EDebugEventHandlerBadCallBack=87, 
+		EMutexOrderingViolation=88,
+		ECondVarWaitBadState1=89,
+		ECondVarWaitBadState2=90,
+		ECondVarWaitBadState3=91,
+		ECondVarUnBlockBadState=92,
+		ESharedIoBufferBadInternalState=93,
+		ENonUserThreadKilled=94,
+		EOutOfIds=95,
+		EBadLogSize=96,
+		EAlreadyCalled=97,
+		EMutexWaitNotDThread=98,
+		EBadKernelHookType=99,
+		EKernelHookAlreadySet=100,
+		EMsgCompleteDiscNotSent=101,
+		ESystemProcessPanic=102,
+		EPermanentProcessExit=103,
+		ECodeSegBadFixupAddress=104,
+		ECodeSegBadFixupTables=105,
+		EAPInitialThreadCreateFailed=106,
+		EInit2APTimeout=107,
+		EChunkCommitBadType = 108,
+		EBadSetRamZoneConfig = 109, /**< SetRamZoneConfig can only be invoked during boot*/
+		ETooManyExtensions = 110,
+		EExtensionArrayAllocationFailed = 111,
+		EInsertExtensionFailed = 112,
+		EExtensionArrayOverflowed = 113,
+		EThreadWaitListDestroy = 114,
+		EThreadWaitListCheck = 115,
+		EThreadWaitListUp = 116,
+		EThreadWaitListChangePriority = 117,
+		EThreadWaitListRemove = 118,
+		EThreadWaitListRemove2 = 119,
+		EClientRequestDeletedNotClosed=120,
+		EClientRequestSetStatusInWrongState=121,
+		EClientRequestCompleteInWrongState=122,
+		EClientRequestResetInWrongState=123,
+		EClientRequestCallbackInWrongState=124,
+		EClientRequestCloseInWrongState=126,
+		EMessageInUse=127,
+		EVirtualPinObjectBad=128,
+		EIpcClientNotNull=129,
+		EBufferRequestAddInWrongState=130,
+		EBufferRequestEndSetupInWrongState=131,
+		EBufferRequestResetInWrongState=132,
+		EThreadBufReadWithNullPointer=133,
+		EThreadBufWriteWithNullPointer=134,
+		ECodeSegRemoveAbsent=135,
+		EPhysicalPinObjectBad=136,
+		EShBufVirtualNotDefined=137,	//< A required virtual method is not present in a shared buffer derived class (internal error)
+		
+		ESystemException=0x10000000,
+		ESoftwareWarmReset=0x10000001
+		};
+
+	static void Fault(TFault aFault);
+public:
+	static TMachineConfig* MachineConfig;
+	static RAllocator* Allocator;
+	static struct SHeapInfo
+		{
+		DChunk* iChunk;
+		TUint8* iBase;
+		TUint iMaxSize;
+		} HeapInfo;
+	static struct SMsgInfo
+		{
+		DChunk* iChunk;
+		TUint8* iBase;
+		TUint iMaxSize;
+		TUint iCurrSize;
+		DMutex* iMsgChunkLock;
+		RMessageK* iNextMessage;
+		TInt iFreeMessageCount;
+		} MsgInfo;
+	static DThread* TheKernelThread;
+	static DProcess* TheKernelProcess;
+	static DThread* TheNullThread;
+	static DThread* SvThread;
+	static TDfcQue* SvMsgQ;
+	static TMessageQue SvBarrierQ;
+	static NFastMutex EventQueueMutex;
+	static TRawEvent *EventHeadPtr;
+	static TRawEvent *EventTailPtr;
+	static TRawEvent *EventBufferStart;
+	static TRawEvent *EventBufferEnd;
+	static TClientDataRequest<TRawEvent>* EventRequest;
+	static DThread *EventThread;
+	static TDfcQue* DfcQ0;
+	static TDfcQue* DfcQ1;
+	static TDfcQue* TimerDfcQ;
+	static TTickQ* TickQ;
+	static TSecondQ* SecondQ;
+	static TInactivityQ* InactivityQ;
+	static TInt HomeTimeOffsetSeconds;
+	static TInt NonSecureOffsetSeconds;
+	static TInt SecureClockStatus;
+	static TInt64 Year2000InSeconds;
+	static DPowerModel* PowerModel;
+	static TBool PowerGood;
+	static TInt MaxMemCopyInOneGo;
+	static TInt MaxFreeRam;
+public:
+	static DObjectCon* Containers[ENumObjectTypes];
+public:
+	static TInt NextId;
+	static TInt DfcQId;
+	static volatile TUint DynamicDfcQId;
+	static SHalEntry2* HalEntryArray;
+	static DMutex* MachineConfigMutex;
+	static TAny* volatile AsyncFreeHead;
+	static DBase* volatile AsyncDeleteHead;
+	static TDfc AsyncFreeDfc;
+	static TInt MemoryLowThreshold;
+	static TInt MemoryGoodThreshold;
+	static TUint AsyncChanges;
+	static TDfc AsyncChangeNotifierDfc;
+public:
+	static TBool Initialising;
+	static TBool ColdStart;
+	static TInt ExtensionCount;
+	static RArray<SExtInit1EntryPoint>* ExtensionArray;
+	static DProcess* TheFileServerProcess;
+	static DProcess* TheWindowServerProcess;
+	static TInt PINestLevel;
+	static TInt SupervisorThreadStackSize;
+	static TUint32 MemModelAttributes;
+	static TKernelHookFn KernelHooks[ENumKernelHooks];
+	static TMiscNotifierMgr TheMiscNotifierMgr;
+	static TAny* VariantData[31];
+public:
+	static TInt InitialiseMicrokernel();
+#ifdef __SMP__
+	static void InitAP(TInt aCpu, volatile SAPBootInfo* aInfo, TInt aTimeout);
+#endif
+	static TInt Init3();
+	static void InitNvRam();
+	static void InitLocaleData();
+	static void	SetDefaultLocaleData1();
+	static void	SetDefaultLocaleData2();
+	static void InitHalEntryArray();
+	static TInt CreateObjectContainers();
+	static DObjectCon* ContainerFromFindHandle(const TFindHandle& aFindHandle);
+	static void LockContainer(TInt aObjType);
+	static void UnlockContainer(TInt aObjType);
+	static TInt AddObject(DObject* aObj, TInt aObjType);
+	static TInt StartTickQueue();
+	static void PanicKernExec(TInt aReason);
+	static void PanicCurrentThread(TInt aReason);
+	static void UnmarkAllLibraries();
+	static void CreateEventQueue(TInt aSize);
+	static void TryDeliverEvent();
+	static DObject* ObjectFromHandle(TInt aHandle);
+	static DObject* ObjectFromHandle(TInt aHandle, TInt aObjType);
+	static DObject* ObjectFromHandle(TInt aHandle, TInt aObjType, TUint& aAttr);
+	static TInt OpenObjectFromHandle(TInt aHandle, DObject*& aObject);
+	static TInt MakeHandle(TOwnerType aType, DObject* aObject);
+	static TInt MakeHandle(TOwnerType aType, DObject* aObject, TUint aAttr);
+	static TInt MakeHandleAndOpen(TOwnerType aType, DObject* aObject, TInt& aHandle);
+	static TInt MakeHandleAndOpen(TOwnerType aType, DObject* aObject, TInt& aHandle, TUint aAttr);
+	static TInt HandleClose(TInt aHandle);
+	static void ObjDelete(DObject* aObj);
+	static TInt SecondsFrom2000(const TTimeK& aTime, TInt& aSeconds);
+	static TInt SetSystemTime(TInt aSecondsFrom2000, TInt aUTCOffset, TUint& aChanges, TUint aMode);
+	static TInt SetSystemTimeAndOffset(const TTimeK& aTime, TInt aOffset, TUint aTimeSetMode, TUint& aChanges, TUint aMode);
+	static void StartKernelServer();
+	static TInt MutexCreate(DMutex*& aMutex, const TDesC& aName, DObject* aOwner, TBool aVisible, TUint aOrder);
+	static void Randomize();
+	static void DoAsyncFree(TAny*);
+	static void DoAsyncNotify(TAny*);
+	static TUint CheckFreeMemoryLevel(TInt aInitial, TInt aFinal, TBool aFailed);
+	static TBool CheckForSimulatedAllocFail();
+	static void DoSvBarrier(TAny*);
+
+//
+	static void CheckKernelUnlocked();
+	static TInt KernelHal(TInt aFunction, TAny* a1, TAny* a2);
+	static void SetMachineConfiguration(const TDesC8& aConfig);
+
+	static DThread* ThreadEnterCS();
+	static DThread* ThreadLeaveCS();
+	static DObject* ThreadEnterCS(TInt aHandle, TInt aObjType);
+	static void CheckFileServerAccess();
+
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	inline static void ProcessIsolationFailure(const char* aContextText);
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	// Only available to NULL arguments
+	inline static void ProcessIsolationFailure(OnlyCreateWithNull aContextText);
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+	static void LockedPlatformSecurityPanic();
+	static void UnlockedPlatformSecurityPanic();
+	static TBool IsInKernelHeap(const TAny* aPtr, TInt aSize);
+	static TUint32 CompressKHeapPtr(const TAny* aPtr);
+	static const TAny* RestoreKHeapPtr(TUint32 aCPtr);
+	static TBool CheckUids(const TUidType& aUids, const TUidType& aRequestedUids);
+	static TUint NewId();
+	inline static TTraceHandler TraceHandler();
+	inline static TNanoWaitHandler NanoWaitHandler();
+	static TInt FloatingPointTypes(TUint32& aTypes);
+	static TInt FloatingPointSystemId(TUint32& aSysId);
+	inline static TInitialTimeHandler InitialTimeHandler();
+
+	static void TextTrace(const TDesC8& aText, TTraceSource aTraceSource, TBool aNewLine=ETrue);
+	static TUint TextTraceMode;
+
+	static void CheckThreadNotRealtime(const char* aTraceMessage=NULL);
+	static TBool IllegalFunctionForRealtimeThread(DThread* aThread,const char* aTraceMessage=NULL);
+	static TAny* USafeRead(const TAny* aSrc, TAny* aDest, TInt aSize);
+	static TAny* USafeWrite(TAny* aDest, const TAny* aSrc, TInt aSize);
+	static TInt ParseDesHeader(const TAny* aDesPtr, const TRawDesHeader& aIn, TDesHeader& aOut);
+	static TInt USafeReadAndParseDesHeader(TAny* aDesPtr, TDesHeader& aOut);
+	static TUint32 KernelConfigFlags();
+
+	static void DoFault(const TAny* a0, TInt a1);
+
+	static TInt ShPoolCreate(DShPool*& aPool, TShPoolCreateInfo& aInfo);
+
+private:
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	static void DoProcessIsolationFailure(const char* aContextText);
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+	static void DoProcessIsolationFailure();
+	static void DoNanoWait(TUint32 aInterval);
+	};
+
+#ifndef __REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+inline void K::ProcessIsolationFailure(const char* aContextText)
+	{
+	DoProcessIsolationFailure(aContextText);
+	}
+#else //__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+// Only available to NULL arguments
+inline void K::ProcessIsolationFailure(OnlyCreateWithNull /*aContextText*/)
+	{
+	DoProcessIsolationFailure();
+	}
+#endif // !__REMOVE_PLATSEC_DIAGNOSTIC_STRINGS__
+
+inline TTraceHandler K::TraceHandler()
+	{
+	return (TTraceHandler)KernelHooks[EHookTrace];
+	}
+
+inline TNanoWaitHandler K::NanoWaitHandler()
+	{
+	return (TNanoWaitHandler)KernelHooks[EHookNanoWait];
+	}
+
+inline TInitialTimeHandler K::InitialTimeHandler()
+	{
+	return (TInitialTimeHandler)KernelHooks[EHookInitialTime];
+	}
+
+#ifdef __DEBUGGER_SUPPORT__
+#define __DEBUG_EVENT(aEvent, a1) DKernelEventHandler::Dispatch((aEvent),(a1),NULL)
+#define __DEBUG_EVENT2(aEvent, a1, a2) DKernelEventHandler::Dispatch((aEvent),(a1),(a2))
+#define __COND_DEBUG_EVENT(aCond, aEvent, a1) {if (aCond) DKernelEventHandler::Dispatch((aEvent),(a1),NULL);}
+
+#ifdef __EPOC32__ 
+//Setting breakpoints is only available on target and if kernel is built with __DEBUGGER_SUPPORT__ option
+#define __REMOVE_CODESEG_FROM_CODEMODIFIER(segment, process) CodeModifier::CodeSegRemoved((segment),(process))
+#else
+#define __REMOVE_CODESEG_FROM_CODEMODIFIER(segment, process)
+#endif
+
+#else
+#define __DEBUG_EVENT(aEvent, a1)
+#define __DEBUG_EVENT2(aEvent, a1, a2)
+#define __COND_DEBUG_EVENT(aCond, aEvent, a1)
+#define __REMOVE_CODESEG_FROM_CODEMODIFIER(segment, process)
+#endif
+
+/********************************************
+ * Functions defined in layer 1M or below of
+ * the kernel and available to layer 1.
+ ********************************************/
+class P
+	{
+public:
+	static TInt InitSystemTime();
+	static TInt DefaultInitialTime();
+	static void CreateVariant();
+	static void StartExtensions();
+	static void KernelInfo(TProcessCreateInfo& aInfo, TAny*& aStack, TAny*& aHeap);
+	static void NormalizeExecutableFileName(TDes& aFileName);
+	static void SetSuperPageSignature();
+	static TBool CheckSuperPageSignature(); 
+//
+	static DProcess* NewProcess();
+	};
+
+
+	struct SCacheInfo;
+ 
+	/*
+ 	Symbian OS currently supports 5 memory models one for the WIN32 platform (the emulator model)
+ 	and three for the EPOC platform (moving, multiple, direct and flexible).
+ 
+ 	Model layer is the third layer in EKA2 software layer which consist of 6 layers, 
+ 	There are two static interfaces to the memory model, the first to be in Class Epoc and the second in Class M.
+   
+	
+ 	Class M consists of functions provided by the memory model to the independent layer which is
+ 	the first layer in EKA2 software layer, M denotes the API exposed by the model layer
+	*/
+ 
+
+struct SCacheInfo;
+struct SPageInfo;
+struct SZone;
+class M
+	{
+public:
+	static void Init1();
+	static void Init2();
+#ifdef __SMP__
+	static void GetAPBootInfo(TInt aCpu, volatile SAPBootInfo* aInfo);
+	static void Init2AP();
+#endif
+	static void Init3();
+	static TInt InitSvHeapChunk(DChunk* aChunk, TInt aSize);
+	static TInt InitSvStackChunk();
+	static TBool IsRomAddress(const TAny* aPtr);
+	static TInt PageSizeInBytes();
+	static TInt PageShift();
+	static void SetupCacheFlushPtr(TInt aCache, SCacheInfo& c);
+	static void FsRegisterThread();
+	static DCodeSeg* NewCodeSeg(TCodeSegCreateInfo& aInfo);
+	static void DemandPagingInit();
+	static TInt DemandPagingFault(TAny* aExceptionInfo);
+	static TBool CheckPagingSafe(TBool aDataPaging, TLinAddr aStartAddr=0, TUint aLength=KMaxTUint);
+	static TInt LockRegion(TLinAddr aStart,TInt aSize);
+	static TInt UnlockRegion(TLinAddr aStart,TInt aSize);
+	static void BTracePrime(TUint aCategory);
+	static void LockUserMemory();
+	static void UnlockUserMemory();
+	static TInt CreateVirtualPinObject(TVirtualPinObject*& aPinObject);
+	static TInt PinVirtualMemory(TVirtualPinObject* aPinObject, TLinAddr aStart, TUint aSize, DThread* DThread);
+	static TInt CreateAndPinVirtualMemory(TVirtualPinObject*& aPinObject, TLinAddr aStart, TUint aSize);
+	static void UnpinVirtualMemory(TVirtualPinObject* aPinObject);	
+	static void DestroyVirtualPinObject(TVirtualPinObject*& aPinObject);
+
+	static TInt CreatePhysicalPinObject(TPhysicalPinObject*& aPinObject);
+	static TInt PinPhysicalMemory(TPhysicalPinObject* aPinObject, TLinAddr aStart, TUint aSize, TBool aReadOnly, TPhysAddr& aAddress, TPhysAddr* aPages, TUint32& aMapAttr, TUint& aColour, DThread* aThread);
+	static void UnpinPhysicalMemory(TPhysicalPinObject* aPinObject);
+	static void DestroyPhysicalPinObject(TPhysicalPinObject*& aPinObject);
+
+	// RAM allocator and defrag interfaces.
+	static void RamAllocLock();
+	static void RamAllocUnlock();
+	static void RamAllocIsLocked();
+	static TUint NumberOfFreeDpPages();
+	static TUint NumberOfDirtyDpPages();
+	static TInt MovePage(TPhysAddr aOld, TPhysAddr& aNew, TUint aBlockZoneId, TBool aBlockRest);
+	static TInt DiscardPage(TPhysAddr aAddr, TUint aBlockZoneId, TBool aBlockRest);
+	static void RamZoneClaimed(SZone* aZone);
+	static TInt RamDefragFault(TAny* aExceptionInfo);
+	};
+
+#ifdef __USER_MEMORY_GUARDS_ENABLED__
+#define	LOCK_USER_MEMORY()			M::LockUserMemory()
+#define	UNLOCK_USER_MEMORY()		M::UnlockUserMemory()
+#define	COND_LOCK_USER_MEMORY(c)	((void)((c)&&(M::LockUserMemory(),0)))
+#define	COND_UNLOCK_USER_MEMORY(c)	((void)((c)&&(M::UnlockUserMemory(),0)))
+#else
+#define	LOCK_USER_MEMORY()
+#define	UNLOCK_USER_MEMORY()
+#define	COND_LOCK_USER_MEMORY(c)
+#define	COND_UNLOCK_USER_MEMORY(c)
+#endif
+
+/********************************************
+ * Functions defined in layer 3 or below and
+ * available to layer 2
+ ********************************************/
+class DPlatChunkHw;
+class A
+	{
+public:
+	static void Init1();
+	static void Init2();
+#ifdef __SMP__
+	static void InitAPs();
+	static void Init2AP();
+#endif
+	static void Init3();
+	static void DebugPrint(const TText* aPtr, TInt aLen, TBool aNewLine=ETrue);
+	static TInt CreateVariant(const TAny* aFile, TInt aMode);
+	static DPlatChunkHw* NewHwChunk();
+	static TPtr8 MachineConfiguration();
+	static void StartCrashDebugger(const TAny* a0, TInt a1);
+	static TInt CallSupervisorFunction(TSupervisorFunction aFunction, TAny* aParameter);
+	static TInt VariantHal(TInt aFunction, TAny* a1, TAny* a2);
+	static TInt SystemTimeInSecondsFrom2000(TInt& aTime);
+	static TInt SetSystemTimeInSecondsFrom2000(TInt aTime);
+	};
+
+class Exc
+	{
+public:
+	static void Dispatch(TAny* aPtr, NThread*);
+	IMPORT_C static void Fault(TAny* aPtr);
+	static TBool IsMagic(TLinAddr aAddress);
+#ifdef __ATOMIC64_USE_SLOW_EXEC__
+	static TBool IsMagicAtomic64(TLinAddr aAddress);
+#endif //__ATOMIC64_USE_SLOW_EXEC__
+	};
+
+/********************************************
+ * Super page definition
+ ********************************************/
+class DDebuggerInfo;
+class TSuperPage : public SSuperPageBase
+	{
+public:
+	TInt iDebugMask[KNumTraceMaskWords];	// kernel trace mask
+	TInt iKernelExcId;
+	TExcInfo iKernelExcInfo;
+	TUint32 iSignature[2];
+	TMachineStartupType iStartupReason;
+	DDebuggerInfo* iDebuggerInfo;
+	TUint32 iDisabledCapabilities[(((TInt)ECapability_HardLimit + 7)>>3) / sizeof(TUint32)];
+	TUint32 iInitialBTraceFilter[8];
+	TInt iInitialBTraceBuffer;
+	TInt iInitialBTraceMode;
+
+private:
+	TUint32 iKernelConfigFlags;
+
+public:
+	/*
+	 * Unless __PLATSEC_UNLOCKED__ is defined, __PLATSEC_FORCED_FLAGS__ is set to a
+	 * bitmask of platsec flags which must always be considered to be set, even if
+	 * they are not really set in iKernelConfigFlags.  Therefore, use this function
+	 * to access iKernelConfigFlags.
+	 *
+	 * __PLATSEC_UNLOCKED__, if set, is set by the base port.
+	 *
+	 * __PLATSEC_FORCED_FLAGS__ is defined in u32std.h near the TKernelConfigFlags enumeration.
+	 */
+	inline TUint32 KernelConfigFlags() 
+		{ 
+#ifdef __PLATSEC_UNLOCKED__
+		return (iKernelConfigFlags | __PLATSEC_FORCED_FLAGS__) & ~EKernelConfigPlatSecLocked;
+#else
+		return (iKernelConfigFlags | __PLATSEC_FORCED_FLAGS__ | EKernelConfigPlatSecLocked);
+#endif
+		} 
+
+	inline void SetKernelConfigFlags(TUint32 aKernelConfigFlags)
+		{
+		iKernelConfigFlags = aKernelConfigFlags;
+		}
+	};
+
+inline TSuperPage& TheSuperPage() {return *(TSuperPage*)SuperPageAddress;}
+inline TMachineConfig& TheMachineConfig() {return *(TMachineConfig*)K::MachineConfig; }
+
+#define TEST_DEBUG_MASK_BIT(n) ( TheSuperPage().iDebugMask[(n)>>5] & (1<<((n)&31)) )
+
+/********************************************
+ * Miscellaneous stuff
+ ********************************************/
+
+inline void TExcTrap::UnTrap()
+	{iThread->iExcTrap=NULL;}
+inline void TIpcExcTrap::UnTrap()
+	{iThread->iExcTrap=NULL;iThread->iIpcClient=NULL;}
+inline void TPagingExcTrap::UnTrap()
+	{iThread->iPagingExcTrap=NULL;}
+
+GLREF_D const TUint32 EpocFastExecTable[];
+GLREF_D const TUint32 EpocSlowExecTable[];
+
+inline SMiscNotifierQ* DObject::NotifierQ() const
+	{
+	TUint32 cptr = ((TUint32(iObjectId)<<14)>>6) | iNotQLow;
+	return cptr ? (SMiscNotifierQ*)K::RestoreKHeapPtr(cptr) : (SMiscNotifierQ*)0;
+	}
+
+inline void DObject::SetNotifierQ(SMiscNotifierQ* aQ)
+	{
+	TUint32 cptr = aQ ? K::CompressKHeapPtr(aQ) : 0;
+	iNotQLow = (TUint8)cptr;
+	volatile TUint32& x = (volatile TUint32&)iObjectId;
+	x = ((x>>18)<<18) | (cptr>>8);
+	}
+
+inline TBool DObject::HasNotifierQ() const
+	{
+	return (TUint32(iObjectId)<<14) | iNotQLow;
+	}
+
+#ifdef _DEBUG
+
+/**
+@publishedPartner
+@released
+*/
+#define __ASSERT_CRITICAL	{	\
+							DThread& t=Kern::CurrentThread(); \
+							__NK_ASSERT_DEBUG(t.iThreadType!=EThreadUser || t.iNThread.iCsCount>0);	\
+							}
+
+/**
+@publishedPartner
+@released
+*/
+#define __ASSERT_MUTEX(m)		{	\
+								DThread& t=Kern::CurrentThread(); \
+								__NK_ASSERT_DEBUG((m)->iCleanup.iThread==&t);	\
+								}
+#else
+/**
+@publishedPartner
+@released
+*/
+#define __ASSERT_CRITICAL
+
+/**
+@publishedPartner
+@released
+*/
+#define __ASSERT_MUTEX(m)
+#endif
+
+
+#define LOGICAL_XOR(a,b) (((a)==0)^((b)==0))
+
+
+#if defined(__GCC32__)
+#define __RETURN_ADDRESS() __builtin_return_address(0)
+#elif defined (__ARMCC__)
+#define __RETURN_ADDRESS() ((TAny*)__return_address())
+#else
+#define __RETURN_ADDRESS() 0	// not supported
+#endif
+
+#ifdef _DEBUG
+#if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
+#define __ASSERT_WITH_MESSAGE_MUTEX(m,message,function ) 
+
+#else
+/**
+@internalComponent
+*/
+#define __ASSERT_WITH_MESSAGE_MUTEX(m,message,function ) \
+			{	\
+			DThread& t=Kern::CurrentThread(); \
+			__ASSERT_WITH_MESSAGE_DEBUG((NKern::Crashed() || ((m)->iCleanup.iThread==&t)),message,function);	\
+			}			
+
+#endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
+
+#else//if !DEBUG
+
+#define __ASSERT_WITH_MESSAGE_MUTEX(m,message,function )
+
+#endif//_DEBUG
+
+// Implementation constants for TClientRequest
+const T_UintPtr KClientRequestFlagClosing = 1 << 0;
+const T_UintPtr KClientRequestFlagInUse   = 1 << 1;
+const T_UintPtr KClientRequestFlagMask    = KClientRequestFlagClosing | KClientRequestFlagInUse;
+const T_UintPtr KClientRequestNullStatus = 0x00000004;  // must be non-zero but never a valid TRequestStatus pointer
+
+#endif