1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/nkern/nklib.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,726 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\nkern\nklib.h
1.18 +//
1.19 +// WARNING: This file contains some APIs which are internal and are subject
1.20 +// to change without notice. Such APIs should therefore not be used
1.21 +// outside the Kernel and Hardware Services package.
1.22 +//
1.23 +
1.24 +#ifndef __NKLIB_H__
1.25 +#define __NKLIB_H__
1.26 +#include <e32err.h>
1.27 +#include <nk_cpu.h>
1.28 +
1.29 +#ifndef __KERNEL_MODE__
1.30 +#error Including kernel header in user code
1.31 +#endif
1.32 +
1.33 +#if defined(__GCC32__)
1.34 +
1.35 +
1.36 +
1.37 +
1.38 +/**
1.39 +@publishedPartner
1.40 +@released
1.41 +
1.42 +64-bit signed integer type.
1.43 +*/
1.44 +typedef long long Int64;
1.45 +
1.46 +
1.47 +
1.48 +
1.49 +/**
1.50 +@publishedPartner
1.51 +@released
1.52 +
1.53 +64-bit unsigned integer type.
1.54 +*/
1.55 +typedef unsigned long long Uint64;
1.56 +
1.57 +
1.58 +
1.59 +
1.60 +#elif defined(__VC32__)
1.61 +typedef __int64 Int64;
1.62 +typedef unsigned __int64 Uint64;
1.63 +#elif defined(__CW32__)
1.64 +#pragma longlong on
1.65 +typedef long long Int64;
1.66 +typedef unsigned long long Uint64;
1.67 +#endif
1.68 +
1.69 +
1.70 +
1.71 +
1.72 +/**
1.73 +@publishedPartner
1.74 +@released
1.75 +
1.76 +Defines a 64-bit time value.
1.77 +*/
1.78 +typedef Int64 TTimeK;
1.79 +
1.80 +
1.81 +
1.82 +
1.83 +#if defined(__VC32__) || defined(__CW32__)
1.84 +extern "C"
1.85 +/** @internalComponent */
1.86 +__NORETURN__ void abort();
1.87 +#endif
1.88 +
1.89 +#ifndef __PLACEMENT_NEW_INLINE
1.90 +#define __PLACEMENT_NEW_INLINE
1.91 +// Global placement operator new
1.92 +/** @internalComponent */
1.93 +inline TAny* operator new(TUint /*aSize*/, TAny* aBase) __NO_THROW
1.94 + {return aBase;}
1.95 +
1.96 +// Global placement operator delete
1.97 +/** @internalComponent */
1.98 +inline void operator delete(TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW
1.99 + {}
1.100 +#endif //__PLACEMENT_NEW_INLINE
1.101 +
1.102 +#ifndef __PLACEMENT_VEC_NEW_INLINE
1.103 +#define __PLACEMENT_VEC_NEW_INLINE
1.104 +// Global placement operator new[]
1.105 +/** @internalComponent */
1.106 +inline TAny* operator new[](TUint /*aSize*/, TAny* aBase) __NO_THROW
1.107 + {return aBase;}
1.108 +
1.109 +// Global placement operator delete[]
1.110 +/** @internalComponent */
1.111 +inline void operator delete[](TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW
1.112 + {}
1.113 +#endif //__PLACEMENT_VEC_NEW_INLINE
1.114 +
1.115 +/**
1.116 + Macro to offset a SDblQueLink pointer back to the base of a class containing it
1.117 + @publishedPartner
1.118 + @released
1.119 +*/
1.120 +#define _LOFF(p,T,f) ((T*)(((TUint8*)(p))-_FOFF(T,f)))
1.121 +
1.122 +#ifdef _DEBUG
1.123 +
1.124 +/** @internalComponent */
1.125 +#define KILL_LINK_VALUE (SDblQueLink*)0xdfdfdfdf
1.126 +
1.127 +/** @internalComponent */
1.128 +#define KILL_LINK(l) (l)->iNext=(l)->iPrev=KILL_LINK_VALUE
1.129 +
1.130 +#else
1.131 +
1.132 +#define KILL_LINK(l)
1.133 +
1.134 +#endif
1.135 +
1.136 +
1.137 +#ifdef __ARMCC__
1.138 +#define FORCE_INLINE __forceinline
1.139 +#else
1.140 +#define FORCE_INLINE inline
1.141 +#endif
1.142 +
1.143 +
1.144 +/**
1.145 +@publishedPartner
1.146 +@released
1.147 +
1.148 +An object that forms part of a doubly linked list.
1.149 +
1.150 +SDblQueLink can also be embedded within another object so that that object
1.151 +can form part of the doubly linked list.
1.152 +
1.153 +@see SDblQue
1.154 +*/
1.155 +struct SDblQueLink
1.156 + {
1.157 +
1.158 +#ifdef _DEBUG
1.159 + /**
1.160 + Default constructor; only defined for debug builds.
1.161 +
1.162 + It initialises the link pointers.
1.163 + */
1.164 + FORCE_INLINE SDblQueLink() {iNext=iPrev=NULL;}
1.165 +#endif
1.166 +
1.167 +
1.168 + /**
1.169 + Removes this link item from the doubly linked list.
1.170 +
1.171 + @return A pointer to this link item.
1.172 + */
1.173 + FORCE_INLINE SDblQueLink* Deque()
1.174 + {
1.175 + SDblQueLink* next = iNext;
1.176 + SDblQueLink* prev = iPrev;
1.177 + next->iPrev=prev;
1.178 + prev->iNext=next;
1.179 + KILL_LINK(this);
1.180 + return this;
1.181 + }
1.182 +
1.183 +
1.184 + /**
1.185 + Inserts this link item into the list so that it precedes the specified link item.
1.186 +
1.187 + @param aL A pointer to the link item which is to follow this link item.
1.188 + */
1.189 + FORCE_INLINE void InsertBefore(SDblQueLink* aL)
1.190 + {
1.191 + SDblQueLink* prev = aL->iPrev;
1.192 + iNext=aL;
1.193 + iPrev=prev;
1.194 + prev->iNext=this;
1.195 + aL->iPrev=this;
1.196 + }
1.197 +
1.198 +
1.199 + /**
1.200 + Inserts this link item into the list so that it follows the specified link item.
1.201 +
1.202 + @param aL A pointer to the link item which is to precede this link item.
1.203 + */
1.204 + FORCE_INLINE void InsertAfter(SDblQueLink* aL)
1.205 + {
1.206 + SDblQueLink* next = aL->iNext;
1.207 + iPrev=aL;
1.208 + iNext=next;
1.209 + next->iPrev=this;
1.210 + aL->iNext=this;
1.211 + }
1.212 +
1.213 +
1.214 + /**
1.215 + Tests whether this is the only link item in the list.
1.216 +
1.217 + @return True, if this is the only link item in the list; false, otherwise.
1.218 + */
1.219 + inline TBool Alone() const
1.220 + { return (iNext==iPrev); }
1.221 +
1.222 +
1.223 + /**
1.224 + Pointer to the next link item in the list.
1.225 + */
1.226 + SDblQueLink* iNext;
1.227 +
1.228 + /**
1.229 + Pointer to the previous link item in the list.
1.230 + */
1.231 + SDblQueLink* iPrev;
1.232 + };
1.233 +
1.234 +
1.235 +
1.236 +
1.237 +/**
1.238 +@publishedPartner
1.239 +@released
1.240 +
1.241 +Anchor for a doubly linked list of SDblQueLink items.
1.242 +
1.243 +@see SDblQueLink
1.244 +*/
1.245 +struct SDblQue
1.246 + {
1.247 +
1.248 +
1.249 + /**
1.250 + Default constructor.
1.251 + */
1.252 + FORCE_INLINE SDblQue()
1.253 + { iA.iNext=iA.iPrev=&iA; }
1.254 +
1.255 +
1.256 + /**
1.257 + Moves link items from the specified list onto this list, and clears the specified list
1.258 +
1.259 + @param aQ The source linked list. This list must not be empty.
1.260 + */
1.261 + inline SDblQue(SDblQue* aQ, TInt) // move entries from aQ onto this queue and clear aQ - aQ must not be empty
1.262 + { new (this) SDblQue(*aQ); iA.iNext->iPrev=&iA; iA.iPrev->iNext=&iA; new (aQ) SDblQue; }
1.263 +
1.264 +
1.265 + /**
1.266 + Tests whether this doubly linked list is empty.
1.267 +
1.268 + @return True, if the list is empty; false, otherwise.
1.269 + */
1.270 + FORCE_INLINE TBool IsEmpty() const
1.271 + { return (iA.iNext==&iA); }
1.272 +
1.273 +
1.274 + /**
1.275 + Gets a pointer to the first item in this doubly linked list.
1.276 +
1.277 + @return A pointer to the first item.
1.278 + */
1.279 + FORCE_INLINE SDblQueLink* First() const
1.280 + { return iA.iNext; }
1.281 +
1.282 +
1.283 + /**
1.284 + Gets a pointer to the last item in this doubly linked list.
1.285 +
1.286 + @return A pointer to the last item.
1.287 + */
1.288 + FORCE_INLINE SDblQueLink* Last() const
1.289 + { return iA.iPrev; }
1.290 +
1.291 +
1.292 + /**
1.293 + Adds the specified link item onto the end of this doubly linked list.
1.294 +
1.295 + @param aL A pointer to the link item to be added.
1.296 + */
1.297 + FORCE_INLINE void Add(SDblQueLink* aL)
1.298 + {
1.299 + SDblQueLink* prev = iA.iPrev;
1.300 + aL->iNext=&iA;
1.301 + aL->iPrev=prev;
1.302 + prev->iNext=aL;
1.303 + iA.iPrev=aL;
1.304 + }
1.305 +
1.306 +
1.307 + /**
1.308 + Adds the specified link item onto the front of this doubly linked list.
1.309 +
1.310 + @param aL A pointer to the link item to be added.
1.311 + */
1.312 + FORCE_INLINE void AddHead(SDblQueLink* aL)
1.313 + {
1.314 + SDblQueLink* next = iA.iNext;
1.315 + aL->iNext=next;
1.316 + aL->iPrev=&iA;
1.317 + next->iPrev=aL;
1.318 + iA.iNext=aL;
1.319 + }
1.320 +
1.321 +
1.322 + /**
1.323 + Removes the last link item from the linked list and adds it to the front
1.324 + of the list.
1.325 + */
1.326 + inline void Rotate()
1.327 + { SDblQueLink* pL=iA.iPrev; pL->Deque(); AddHead(pL); }
1.328 +
1.329 +
1.330 + /**
1.331 + Gets the first link item in the linked list.
1.332 +
1.333 + @return The first link item in the list; NULL, if the list is empty.
1.334 + */
1.335 + inline SDblQueLink* GetFirst()
1.336 + { if (IsEmpty()) return NULL; else return First()->Deque(); }
1.337 +
1.338 +
1.339 + /**
1.340 + Gets the last link item in the linked list.
1.341 +
1.342 + @return The last link item in the list; NULL, if the list is empty.
1.343 + */
1.344 + inline SDblQueLink* GetLast()
1.345 + { if (IsEmpty()) return NULL; else return Last()->Deque(); }
1.346 +
1.347 +
1.348 + /**
1.349 + Appends entries from the specified linked list onto this list, and clears
1.350 + the specified link list anchor.
1.351 +
1.352 + @param aQ The source linked list.
1.353 + */
1.354 + inline void MoveFrom(SDblQue* aQ) // append entries from aQ onto this queue and clear aQ
1.355 + { if (!aQ->IsEmpty())
1.356 + {iA.iPrev->iNext=aQ->iA.iNext; aQ->iA.iNext->iPrev=iA.iPrev; iA.iPrev=aQ->iA.iPrev; iA.iPrev->iNext=&iA; new (aQ) SDblQue; }
1.357 + }
1.358 +
1.359 +
1.360 + /**
1.361 + The anchor point for the doubly linked list.
1.362 + */
1.363 + SDblQueLink iA;
1.364 + };
1.365 +
1.366 +
1.367 +
1.368 +
1.369 +/**
1.370 +@publishedPartner
1.371 +@released
1.372 +
1.373 +An object that forms part of a doubly linked list arranged
1.374 +in descending key order.
1.375 +
1.376 +@see SOrdQue
1.377 +*/
1.378 +struct SOrdQueLink : public SDblQueLink
1.379 + {
1.380 +
1.381 +
1.382 + /**
1.383 + The key value used to order the link item.
1.384 + */
1.385 + TInt iKey;
1.386 + };
1.387 +
1.388 +
1.389 +
1.390 +
1.391 +/**
1.392 +@publishedPartner
1.393 +@released
1.394 +
1.395 +Anchor for a doubly linked list of SOrdQueLink items.
1.396 +
1.397 +The items in this linked list are in descending key order.
1.398 +
1.399 +@see SOrdQueLink
1.400 +*/
1.401 +struct SOrdQue : public SDblQue
1.402 + {
1.403 +
1.404 +
1.405 + /**
1.406 + Adds the specified link item into this doubly linked list so that
1.407 + the list remains in descending key order.
1.408 +
1.409 + @param aL A pointer to the link item to be added.
1.410 + */
1.411 + inline void Add(SOrdQueLink* aL)
1.412 + {
1.413 + SOrdQueLink* pQ=(SOrdQueLink*)iA.iNext;
1.414 + TInt k=aL->iKey;
1.415 + while(pQ!=&iA && (pQ->iKey>=k)) pQ=(SOrdQueLink*)pQ->iNext;
1.416 + aL->InsertBefore(pQ);
1.417 + }
1.418 + };
1.419 +
1.420 +
1.421 +
1.422 +
1.423 +/**
1.424 +@publishedPartner
1.425 +@released
1.426 +
1.427 +An object that forms part of a doubly linked list arranged
1.428 +in 'delta' order.
1.429 +
1.430 +The item represents some value that is an increment, or delta,
1.431 +on the value represented by a preceding element.
1.432 +
1.433 +@see SDeltaQue
1.434 +*/
1.435 +struct SDeltaQueLink : public SDblQueLink
1.436 + {
1.437 + /**
1.438 + The delta value.
1.439 + */
1.440 + TInt iDelta;
1.441 + };
1.442 +
1.443 +
1.444 +
1.445 +
1.446 +/**
1.447 +@publishedPartner
1.448 +@released
1.449 +
1.450 +Anchor for a doubly linked list of SDeltaQueLink items.
1.451 +
1.452 +An item in this linked list represents a value that is an increment,
1.453 +or a delta, on the value represented by a preceding element.
1.454 +The list is ordered so that the head of the queue represents a nominal zero point.
1.455 +
1.456 +@see SDeltaQueLink
1.457 +*/
1.458 +struct SDeltaQue : public SDblQue
1.459 + {
1.460 +
1.461 +
1.462 + /**
1.463 + Gets the delta value of the first link item in the list.
1.464 +
1.465 + @return The delta value.
1.466 + */
1.467 + inline TInt FirstDelta() const
1.468 + {return ((SDeltaQueLink*)First())->iDelta;}
1.469 +
1.470 +
1.471 + /**
1.472 + Decrements the delta value of the first item in the list by the specified value.
1.473 +
1.474 + @param aCount The amount by which the delta value is to be reduced.
1.475 +
1.476 + @return True, if the resulting delta value is negative or zero;
1.477 + false, if the value is positive.
1.478 + */
1.479 + inline TBool CountDown(TInt aCount)
1.480 + {SDeltaQueLink& l=*(SDeltaQueLink*)First(); return((l.iDelta-=aCount)<=0);}
1.481 +
1.482 +
1.483 + /**
1.484 + Adds the specified list item, having the specified 'distance' from
1.485 + the nominal zero point, into the list.
1.486 +
1.487 + The item is added into the list, the adjacent delta values are adjusted,
1.488 + and a suitable delta value assigned to the new item so that
1.489 + the new item is at the specified 'distance' from the nominal zero point.
1.490 +
1.491 + @param aL The item to be inserted.
1.492 + @param aDelta The 'distance' of the item from the nominal zero point.
1.493 + */
1.494 + inline void Add(SDeltaQueLink* aL, TInt aDelta)
1.495 + {
1.496 + SDeltaQueLink* pQ=(SDeltaQueLink*)iA.iNext;
1.497 + while(pQ!=&iA && aDelta>=pQ->iDelta)
1.498 + { aDelta-=pQ->iDelta; pQ=(SDeltaQueLink*)pQ->iNext; }
1.499 + aL->iDelta=aDelta;
1.500 + aL->InsertBefore(pQ);
1.501 + if (pQ!=&iA) pQ->iDelta-=aDelta;
1.502 + }
1.503 +
1.504 +
1.505 + /**
1.506 + Removes the specified link item from the list.
1.507 +
1.508 + The delta value of the item following the removed item is adjusted
1.509 + so that its 'distance' from the nominal zero point remains the same.
1.510 +
1.511 + @param aL The list item to be removed.
1.512 +
1.513 + @return A pointer to the item removed from the queue.
1.514 + */
1.515 + inline SDeltaQueLink* Remove(SDeltaQueLink* aL)
1.516 + {
1.517 + if (aL->iNext!=&iA)
1.518 + {
1.519 + SDeltaQueLink& next=*(SDeltaQueLink*)aL->iNext;
1.520 + next.iDelta+=aL->iDelta;
1.521 + }
1.522 + return (SDeltaQueLink*)aL->Deque();
1.523 + }
1.524 +
1.525 +
1.526 + /**
1.527 + Removes the first item from the linked list if its delta value
1.528 + is zero or negative.
1.529 +
1.530 + @return A pointer to the item removed from the linked list.
1.531 + This is NULL, if the first element has a positive delta value,
1.532 + and has not been removed from the list.
1.533 + */
1.534 + inline SDeltaQueLink* RemoveFirst()
1.535 + {
1.536 + SDeltaQueLink& l=*(SDeltaQueLink*)First();
1.537 + if (l.iDelta<=0)
1.538 + return Remove(&l);
1.539 + return NULL;
1.540 + }
1.541 + };
1.542 +
1.543 +
1.544 +
1.545 +
1.546 +/**
1.547 +@publishedPartner
1.548 +@released
1.549 +
1.550 +An object that forms part of a TPriList, priority ordered lists.
1.551 +
1.552 +@see TPriListBase
1.553 +@see TPriList
1.554 +*/
1.555 +class TPriListLink : public SDblQueLink
1.556 + {
1.557 +public:
1.558 +
1.559 +
1.560 + /**
1.561 + Default constructor.
1.562 +
1.563 + Sets the priority value to zero.
1.564 + */
1.565 + inline TPriListLink() : iPriority(0) {}
1.566 +
1.567 +
1.568 + /**
1.569 + Constructor.
1.570 +
1.571 + Sets the priority to the specified value.
1.572 +
1.573 + @param aPriority The priority value.
1.574 + */
1.575 + inline TPriListLink(TInt aPriority) : iPriority((TUint8)aPriority) {}
1.576 +
1.577 +
1.578 + /**
1.579 + Tests whether this is a solitary link item.
1.580 +
1.581 + @return True, if this is a solitary link item; false, otherwise.
1.582 + */
1.583 + inline TBool Alone() const
1.584 + { return (iNext==(SDblQueLink*)this); }
1.585 +public:
1.586 +
1.587 + /**
1.588 + The priority value.
1.589 + */
1.590 + TUint8 iPriority;
1.591 +
1.592 + /**
1.593 + Reserved for future use.
1.594 + */
1.595 + TUint8 iSpare1;
1.596 +
1.597 +
1.598 + /**
1.599 + Reserved for future use.
1.600 + */
1.601 + TUint8 iSpare2;
1.602 +
1.603 +
1.604 + /**
1.605 + Reserved for future use.
1.606 + */
1.607 + TUint8 iSpare3;
1.608 + };
1.609 +
1.610 +
1.611 +
1.612 +
1.613 +/**
1.614 +@publishedPartner
1.615 +@released
1.616 +
1.617 +Base class for a TPriList, priority ordered lists.
1.618 +
1.619 +@see TPriListLink
1.620 +@see TPriList
1.621 +*/
1.622 +class TPriListBase
1.623 + {
1.624 +public:
1.625 + IMPORT_C TPriListBase(TInt aNumPriorities);
1.626 + IMPORT_C TInt HighestPriority();
1.627 + IMPORT_C TPriListLink* First();
1.628 + IMPORT_C void Add(TPriListLink* aLink);
1.629 + IMPORT_C void AddHead(TPriListLink* aLink);
1.630 + IMPORT_C void Remove(TPriListLink* aLink);
1.631 + IMPORT_C void ChangePriority(TPriListLink* aLink, TInt aNewPriority);
1.632 +
1.633 + /**
1.634 + Tests whether there are any non-empty lists.
1.635 +
1.636 + @return True, if there are non-empty lists; false, if all lists are empty.
1.637 + */
1.638 + inline TBool NonEmpty() const
1.639 + { return iPresent[0]|iPresent[1]; }
1.640 +
1.641 + /**
1.642 + Tests whether there are any non-empty lists.
1.643 +
1.644 + @return True, if all lists are empty
1.645 + */
1.646 + inline TBool IsEmpty() const
1.647 + { return !iPresent[0] && !iPresent[1]; }
1.648 +
1.649 + /**
1.650 + Tests whether any linked list with priority greater than p is non-empty.
1.651 +
1.652 + @param p The priority value (0-63).
1.653 +
1.654 + @return True, if any list with priority greater than p is non-empty; false, otherwise.
1.655 + */
1.656 + inline TBool operator>(TInt p) const
1.657 + { return ((p<32) ? (iPresent[1] | (iPresent[0]>>p)>>1) : (iPresent[1]>>(p-32))>>1 ); }
1.658 +public:
1.659 +
1.660 + /**
1.661 + 64-bit mask to indicate which list is non-empty.
1.662 +
1.663 + Bit n in the mask is set if and only if the linked list for priority n is non-empty.
1.664 + */
1.665 + union
1.666 + {
1.667 + TUint iPresent[2];
1.668 + TUint64 iPresent64;
1.669 + };
1.670 +
1.671 + /**
1.672 + Pointer to the first linked list.
1.673 + */
1.674 + SDblQueLink* iQueue[1];
1.675 + };
1.676 +
1.677 +
1.678 +
1.679 +
1.680 +template<class T, int n>
1.681 +/**
1.682 +@publishedPartner
1.683 +@released
1.684 +
1.685 +Anchor for a collection of doubly linked lists, where each list
1.686 +corresponds to a priority value.
1.687 +
1.688 +The lists are ordered by priority value, but items within
1.689 +a list are in chronological order.
1.690 +
1.691 +The number of lists is defined by the template integer parameter,
1.692 +and each item in each list is of a class type defined by the template class parameter.
1.693 +The number of lists must be between 1 and 64 inclusive.
1.694 +
1.695 +@see TPriListLink
1.696 +*/
1.697 +class TPriList : public TPriListBase
1.698 + {
1.699 +public:
1.700 + /**
1.701 + Constructor.
1.702 + */
1.703 + inline TPriList() : TPriListBase(n) {}
1.704 +
1.705 +
1.706 + /**
1.707 + Finds the highest priority item present on a priority list.
1.708 + If multiple items at the same priority are present, return the first to be
1.709 + added in chronological order.
1.710 +
1.711 + @return a pointer to the item or NULL if the list is empty.
1.712 + */
1.713 + inline T* First() { return (T*)TPriListBase::First(); }
1.714 +private:
1.715 + SDblQueLink* iExtraQueues[n-1];
1.716 + };
1.717 +
1.718 +
1.719 +
1.720 +/** Base for variant interface block
1.721 +@internalTechnology
1.722 +@prototype
1.723 +*/
1.724 +struct SInterfaceBlockBase
1.725 + {
1.726 + TUint32 iVer; // version number
1.727 + TUint32 iSize; // size in bytes
1.728 + };
1.729 +#endif