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