sl@0: // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\include\nkern\nklib.h sl@0: // sl@0: // WARNING: This file contains some APIs which are internal and are subject sl@0: // to change without notice. Such APIs should therefore not be used sl@0: // outside the Kernel and Hardware Services package. sl@0: // sl@0: sl@0: #ifndef __NKLIB_H__ sl@0: #define __NKLIB_H__ sl@0: #include sl@0: #include sl@0: sl@0: #ifndef __KERNEL_MODE__ sl@0: #error Including kernel header in user code sl@0: #endif sl@0: sl@0: #if defined(__GCC32__) sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: 64-bit signed integer type. sl@0: */ sl@0: typedef long long Int64; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: 64-bit unsigned integer type. sl@0: */ sl@0: typedef unsigned long long Uint64; sl@0: sl@0: sl@0: sl@0: sl@0: #elif defined(__VC32__) sl@0: typedef __int64 Int64; sl@0: typedef unsigned __int64 Uint64; sl@0: #elif defined(__CW32__) sl@0: #pragma longlong on sl@0: typedef long long Int64; sl@0: typedef unsigned long long Uint64; sl@0: #endif sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Defines a 64-bit time value. sl@0: */ sl@0: typedef Int64 TTimeK; sl@0: sl@0: sl@0: sl@0: sl@0: #if defined(__VC32__) || defined(__CW32__) sl@0: extern "C" sl@0: /** @internalComponent */ sl@0: __NORETURN__ void abort(); sl@0: #endif sl@0: sl@0: #ifndef __PLACEMENT_NEW_INLINE sl@0: #define __PLACEMENT_NEW_INLINE sl@0: // Global placement operator new sl@0: /** @internalComponent */ sl@0: inline TAny* operator new(TUint /*aSize*/, TAny* aBase) __NO_THROW sl@0: {return aBase;} sl@0: sl@0: // Global placement operator delete sl@0: /** @internalComponent */ sl@0: inline void operator delete(TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW sl@0: {} sl@0: #endif //__PLACEMENT_NEW_INLINE sl@0: sl@0: #ifndef __PLACEMENT_VEC_NEW_INLINE sl@0: #define __PLACEMENT_VEC_NEW_INLINE sl@0: // Global placement operator new[] sl@0: /** @internalComponent */ sl@0: inline TAny* operator new[](TUint /*aSize*/, TAny* aBase) __NO_THROW sl@0: {return aBase;} sl@0: sl@0: // Global placement operator delete[] sl@0: /** @internalComponent */ sl@0: inline void operator delete[](TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW sl@0: {} sl@0: #endif //__PLACEMENT_VEC_NEW_INLINE sl@0: sl@0: /** sl@0: Macro to offset a SDblQueLink pointer back to the base of a class containing it sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: #define _LOFF(p,T,f) ((T*)(((TUint8*)(p))-_FOFF(T,f))) sl@0: sl@0: #ifdef _DEBUG sl@0: sl@0: /** @internalComponent */ sl@0: #define KILL_LINK_VALUE (SDblQueLink*)0xdfdfdfdf sl@0: sl@0: /** @internalComponent */ sl@0: #define KILL_LINK(l) (l)->iNext=(l)->iPrev=KILL_LINK_VALUE sl@0: sl@0: #else sl@0: sl@0: #define KILL_LINK(l) sl@0: sl@0: #endif sl@0: sl@0: sl@0: #ifdef __ARMCC__ sl@0: #define FORCE_INLINE __forceinline sl@0: #else sl@0: #define FORCE_INLINE inline sl@0: #endif sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: An object that forms part of a doubly linked list. sl@0: sl@0: SDblQueLink can also be embedded within another object so that that object sl@0: can form part of the doubly linked list. sl@0: sl@0: @see SDblQue sl@0: */ sl@0: struct SDblQueLink sl@0: { sl@0: sl@0: #ifdef _DEBUG sl@0: /** sl@0: Default constructor; only defined for debug builds. sl@0: sl@0: It initialises the link pointers. sl@0: */ sl@0: FORCE_INLINE SDblQueLink() {iNext=iPrev=NULL;} sl@0: #endif sl@0: sl@0: sl@0: /** sl@0: Removes this link item from the doubly linked list. sl@0: sl@0: @return A pointer to this link item. sl@0: */ sl@0: FORCE_INLINE SDblQueLink* Deque() sl@0: { sl@0: SDblQueLink* next = iNext; sl@0: SDblQueLink* prev = iPrev; sl@0: next->iPrev=prev; sl@0: prev->iNext=next; sl@0: KILL_LINK(this); sl@0: return this; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Inserts this link item into the list so that it precedes the specified link item. sl@0: sl@0: @param aL A pointer to the link item which is to follow this link item. sl@0: */ sl@0: FORCE_INLINE void InsertBefore(SDblQueLink* aL) sl@0: { sl@0: SDblQueLink* prev = aL->iPrev; sl@0: iNext=aL; sl@0: iPrev=prev; sl@0: prev->iNext=this; sl@0: aL->iPrev=this; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Inserts this link item into the list so that it follows the specified link item. sl@0: sl@0: @param aL A pointer to the link item which is to precede this link item. sl@0: */ sl@0: FORCE_INLINE void InsertAfter(SDblQueLink* aL) sl@0: { sl@0: SDblQueLink* next = aL->iNext; sl@0: iPrev=aL; sl@0: iNext=next; sl@0: next->iPrev=this; sl@0: aL->iNext=this; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Tests whether this is the only link item in the list. sl@0: sl@0: @return True, if this is the only link item in the list; false, otherwise. sl@0: */ sl@0: inline TBool Alone() const sl@0: { return (iNext==iPrev); } sl@0: sl@0: sl@0: /** sl@0: Pointer to the next link item in the list. sl@0: */ sl@0: SDblQueLink* iNext; sl@0: sl@0: /** sl@0: Pointer to the previous link item in the list. sl@0: */ sl@0: SDblQueLink* iPrev; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Anchor for a doubly linked list of SDblQueLink items. sl@0: sl@0: @see SDblQueLink sl@0: */ sl@0: struct SDblQue sl@0: { sl@0: sl@0: sl@0: /** sl@0: Default constructor. sl@0: */ sl@0: FORCE_INLINE SDblQue() sl@0: { iA.iNext=iA.iPrev=&iA; } sl@0: sl@0: sl@0: /** sl@0: Moves link items from the specified list onto this list, and clears the specified list sl@0: sl@0: @param aQ The source linked list. This list must not be empty. sl@0: */ sl@0: inline SDblQue(SDblQue* aQ, TInt) // move entries from aQ onto this queue and clear aQ - aQ must not be empty sl@0: { new (this) SDblQue(*aQ); iA.iNext->iPrev=&iA; iA.iPrev->iNext=&iA; new (aQ) SDblQue; } sl@0: sl@0: sl@0: /** sl@0: Tests whether this doubly linked list is empty. sl@0: sl@0: @return True, if the list is empty; false, otherwise. sl@0: */ sl@0: FORCE_INLINE TBool IsEmpty() const sl@0: { return (iA.iNext==&iA); } sl@0: sl@0: sl@0: /** sl@0: Gets a pointer to the first item in this doubly linked list. sl@0: sl@0: @return A pointer to the first item. sl@0: */ sl@0: FORCE_INLINE SDblQueLink* First() const sl@0: { return iA.iNext; } sl@0: sl@0: sl@0: /** sl@0: Gets a pointer to the last item in this doubly linked list. sl@0: sl@0: @return A pointer to the last item. sl@0: */ sl@0: FORCE_INLINE SDblQueLink* Last() const sl@0: { return iA.iPrev; } sl@0: sl@0: sl@0: /** sl@0: Adds the specified link item onto the end of this doubly linked list. sl@0: sl@0: @param aL A pointer to the link item to be added. sl@0: */ sl@0: FORCE_INLINE void Add(SDblQueLink* aL) sl@0: { sl@0: SDblQueLink* prev = iA.iPrev; sl@0: aL->iNext=&iA; sl@0: aL->iPrev=prev; sl@0: prev->iNext=aL; sl@0: iA.iPrev=aL; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Adds the specified link item onto the front of this doubly linked list. sl@0: sl@0: @param aL A pointer to the link item to be added. sl@0: */ sl@0: FORCE_INLINE void AddHead(SDblQueLink* aL) sl@0: { sl@0: SDblQueLink* next = iA.iNext; sl@0: aL->iNext=next; sl@0: aL->iPrev=&iA; sl@0: next->iPrev=aL; sl@0: iA.iNext=aL; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Removes the last link item from the linked list and adds it to the front sl@0: of the list. sl@0: */ sl@0: inline void Rotate() sl@0: { SDblQueLink* pL=iA.iPrev; pL->Deque(); AddHead(pL); } sl@0: sl@0: sl@0: /** sl@0: Gets the first link item in the linked list. sl@0: sl@0: @return The first link item in the list; NULL, if the list is empty. sl@0: */ sl@0: inline SDblQueLink* GetFirst() sl@0: { if (IsEmpty()) return NULL; else return First()->Deque(); } sl@0: sl@0: sl@0: /** sl@0: Gets the last link item in the linked list. sl@0: sl@0: @return The last link item in the list; NULL, if the list is empty. sl@0: */ sl@0: inline SDblQueLink* GetLast() sl@0: { if (IsEmpty()) return NULL; else return Last()->Deque(); } sl@0: sl@0: sl@0: /** sl@0: Appends entries from the specified linked list onto this list, and clears sl@0: the specified link list anchor. sl@0: sl@0: @param aQ The source linked list. sl@0: */ sl@0: inline void MoveFrom(SDblQue* aQ) // append entries from aQ onto this queue and clear aQ sl@0: { if (!aQ->IsEmpty()) sl@0: {iA.iPrev->iNext=aQ->iA.iNext; aQ->iA.iNext->iPrev=iA.iPrev; iA.iPrev=aQ->iA.iPrev; iA.iPrev->iNext=&iA; new (aQ) SDblQue; } sl@0: } sl@0: sl@0: sl@0: /** sl@0: The anchor point for the doubly linked list. sl@0: */ sl@0: SDblQueLink iA; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: An object that forms part of a doubly linked list arranged sl@0: in descending key order. sl@0: sl@0: @see SOrdQue sl@0: */ sl@0: struct SOrdQueLink : public SDblQueLink sl@0: { sl@0: sl@0: sl@0: /** sl@0: The key value used to order the link item. sl@0: */ sl@0: TInt iKey; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Anchor for a doubly linked list of SOrdQueLink items. sl@0: sl@0: The items in this linked list are in descending key order. sl@0: sl@0: @see SOrdQueLink sl@0: */ sl@0: struct SOrdQue : public SDblQue sl@0: { sl@0: sl@0: sl@0: /** sl@0: Adds the specified link item into this doubly linked list so that sl@0: the list remains in descending key order. sl@0: sl@0: @param aL A pointer to the link item to be added. sl@0: */ sl@0: inline void Add(SOrdQueLink* aL) sl@0: { sl@0: SOrdQueLink* pQ=(SOrdQueLink*)iA.iNext; sl@0: TInt k=aL->iKey; sl@0: while(pQ!=&iA && (pQ->iKey>=k)) pQ=(SOrdQueLink*)pQ->iNext; sl@0: aL->InsertBefore(pQ); sl@0: } sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: An object that forms part of a doubly linked list arranged sl@0: in 'delta' order. sl@0: sl@0: The item represents some value that is an increment, or delta, sl@0: on the value represented by a preceding element. sl@0: sl@0: @see SDeltaQue sl@0: */ sl@0: struct SDeltaQueLink : public SDblQueLink sl@0: { sl@0: /** sl@0: The delta value. sl@0: */ sl@0: TInt iDelta; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Anchor for a doubly linked list of SDeltaQueLink items. sl@0: sl@0: An item in this linked list represents a value that is an increment, sl@0: or a delta, on the value represented by a preceding element. sl@0: The list is ordered so that the head of the queue represents a nominal zero point. sl@0: sl@0: @see SDeltaQueLink sl@0: */ sl@0: struct SDeltaQue : public SDblQue sl@0: { sl@0: sl@0: sl@0: /** sl@0: Gets the delta value of the first link item in the list. sl@0: sl@0: @return The delta value. sl@0: */ sl@0: inline TInt FirstDelta() const sl@0: {return ((SDeltaQueLink*)First())->iDelta;} sl@0: sl@0: sl@0: /** sl@0: Decrements the delta value of the first item in the list by the specified value. sl@0: sl@0: @param aCount The amount by which the delta value is to be reduced. sl@0: sl@0: @return True, if the resulting delta value is negative or zero; sl@0: false, if the value is positive. sl@0: */ sl@0: inline TBool CountDown(TInt aCount) sl@0: {SDeltaQueLink& l=*(SDeltaQueLink*)First(); return((l.iDelta-=aCount)<=0);} sl@0: sl@0: sl@0: /** sl@0: Adds the specified list item, having the specified 'distance' from sl@0: the nominal zero point, into the list. sl@0: sl@0: The item is added into the list, the adjacent delta values are adjusted, sl@0: and a suitable delta value assigned to the new item so that sl@0: the new item is at the specified 'distance' from the nominal zero point. sl@0: sl@0: @param aL The item to be inserted. sl@0: @param aDelta The 'distance' of the item from the nominal zero point. sl@0: */ sl@0: inline void Add(SDeltaQueLink* aL, TInt aDelta) sl@0: { sl@0: SDeltaQueLink* pQ=(SDeltaQueLink*)iA.iNext; sl@0: while(pQ!=&iA && aDelta>=pQ->iDelta) sl@0: { aDelta-=pQ->iDelta; pQ=(SDeltaQueLink*)pQ->iNext; } sl@0: aL->iDelta=aDelta; sl@0: aL->InsertBefore(pQ); sl@0: if (pQ!=&iA) pQ->iDelta-=aDelta; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Removes the specified link item from the list. sl@0: sl@0: The delta value of the item following the removed item is adjusted sl@0: so that its 'distance' from the nominal zero point remains the same. sl@0: sl@0: @param aL The list item to be removed. sl@0: sl@0: @return A pointer to the item removed from the queue. sl@0: */ sl@0: inline SDeltaQueLink* Remove(SDeltaQueLink* aL) sl@0: { sl@0: if (aL->iNext!=&iA) sl@0: { sl@0: SDeltaQueLink& next=*(SDeltaQueLink*)aL->iNext; sl@0: next.iDelta+=aL->iDelta; sl@0: } sl@0: return (SDeltaQueLink*)aL->Deque(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: Removes the first item from the linked list if its delta value sl@0: is zero or negative. sl@0: sl@0: @return A pointer to the item removed from the linked list. sl@0: This is NULL, if the first element has a positive delta value, sl@0: and has not been removed from the list. sl@0: */ sl@0: inline SDeltaQueLink* RemoveFirst() sl@0: { sl@0: SDeltaQueLink& l=*(SDeltaQueLink*)First(); sl@0: if (l.iDelta<=0) sl@0: return Remove(&l); sl@0: return NULL; sl@0: } sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: An object that forms part of a TPriList, priority ordered lists. sl@0: sl@0: @see TPriListBase sl@0: @see TPriList sl@0: */ sl@0: class TPriListLink : public SDblQueLink sl@0: { sl@0: public: sl@0: sl@0: sl@0: /** sl@0: Default constructor. sl@0: sl@0: Sets the priority value to zero. sl@0: */ sl@0: inline TPriListLink() : iPriority(0) {} sl@0: sl@0: sl@0: /** sl@0: Constructor. sl@0: sl@0: Sets the priority to the specified value. sl@0: sl@0: @param aPriority The priority value. sl@0: */ sl@0: inline TPriListLink(TInt aPriority) : iPriority((TUint8)aPriority) {} sl@0: sl@0: sl@0: /** sl@0: Tests whether this is a solitary link item. sl@0: sl@0: @return True, if this is a solitary link item; false, otherwise. sl@0: */ sl@0: inline TBool Alone() const sl@0: { return (iNext==(SDblQueLink*)this); } sl@0: public: sl@0: sl@0: /** sl@0: The priority value. sl@0: */ sl@0: TUint8 iPriority; sl@0: sl@0: /** sl@0: Reserved for future use. sl@0: */ sl@0: TUint8 iSpare1; sl@0: sl@0: sl@0: /** sl@0: Reserved for future use. sl@0: */ sl@0: TUint8 iSpare2; sl@0: sl@0: sl@0: /** sl@0: Reserved for future use. sl@0: */ sl@0: TUint8 iSpare3; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Base class for a TPriList, priority ordered lists. sl@0: sl@0: @see TPriListLink sl@0: @see TPriList sl@0: */ sl@0: class TPriListBase sl@0: { sl@0: public: sl@0: IMPORT_C TPriListBase(TInt aNumPriorities); sl@0: IMPORT_C TInt HighestPriority(); sl@0: IMPORT_C TPriListLink* First(); sl@0: IMPORT_C void Add(TPriListLink* aLink); sl@0: IMPORT_C void AddHead(TPriListLink* aLink); sl@0: IMPORT_C void Remove(TPriListLink* aLink); sl@0: IMPORT_C void ChangePriority(TPriListLink* aLink, TInt aNewPriority); sl@0: sl@0: /** sl@0: Tests whether there are any non-empty lists. sl@0: sl@0: @return True, if there are non-empty lists; false, if all lists are empty. sl@0: */ sl@0: inline TBool NonEmpty() const sl@0: { return iPresent[0]|iPresent[1]; } sl@0: sl@0: /** sl@0: Tests whether there are any non-empty lists. sl@0: sl@0: @return True, if all lists are empty sl@0: */ sl@0: inline TBool IsEmpty() const sl@0: { return !iPresent[0] && !iPresent[1]; } sl@0: sl@0: /** sl@0: Tests whether any linked list with priority greater than p is non-empty. sl@0: sl@0: @param p The priority value (0-63). sl@0: sl@0: @return True, if any list with priority greater than p is non-empty; false, otherwise. sl@0: */ sl@0: inline TBool operator>(TInt p) const sl@0: { return ((p<32) ? (iPresent[1] | (iPresent[0]>>p)>>1) : (iPresent[1]>>(p-32))>>1 ); } sl@0: public: sl@0: sl@0: /** sl@0: 64-bit mask to indicate which list is non-empty. sl@0: sl@0: Bit n in the mask is set if and only if the linked list for priority n is non-empty. sl@0: */ sl@0: union sl@0: { sl@0: TUint iPresent[2]; sl@0: TUint64 iPresent64; sl@0: }; sl@0: sl@0: /** sl@0: Pointer to the first linked list. sl@0: */ sl@0: SDblQueLink* iQueue[1]; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: sl@0: Anchor for a collection of doubly linked lists, where each list sl@0: corresponds to a priority value. sl@0: sl@0: The lists are ordered by priority value, but items within sl@0: a list are in chronological order. sl@0: sl@0: The number of lists is defined by the template integer parameter, sl@0: and each item in each list is of a class type defined by the template class parameter. sl@0: The number of lists must be between 1 and 64 inclusive. sl@0: sl@0: @see TPriListLink sl@0: */ sl@0: class TPriList : public TPriListBase sl@0: { sl@0: public: sl@0: /** sl@0: Constructor. sl@0: */ sl@0: inline TPriList() : TPriListBase(n) {} sl@0: sl@0: sl@0: /** sl@0: Finds the highest priority item present on a priority list. sl@0: If multiple items at the same priority are present, return the first to be sl@0: added in chronological order. sl@0: sl@0: @return a pointer to the item or NULL if the list is empty. sl@0: */ sl@0: inline T* First() { return (T*)TPriListBase::First(); } sl@0: private: sl@0: SDblQueLink* iExtraQueues[n-1]; sl@0: }; sl@0: sl@0: sl@0: sl@0: /** Base for variant interface block sl@0: @internalTechnology sl@0: @prototype sl@0: */ sl@0: struct SInterfaceBlockBase sl@0: { sl@0: TUint32 iVer; // version number sl@0: TUint32 iSize; // size in bytes sl@0: }; sl@0: #endif