--- /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 <e32err.h>
+#include <nk_cpu.h>
+
+#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<class T, int n>
+/**
+@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