os/kernelhwsrv/kernel/eka/include/nkern/nklib.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32\include\nkern\nklib.h
    15 // 
    16 // WARNING: This file contains some APIs which are internal and are subject
    17 //          to change without notice. Such APIs should therefore not be used
    18 //          outside the Kernel and Hardware Services package.
    19 //
    20 
    21 #ifndef __NKLIB_H__
    22 #define __NKLIB_H__
    23 #include <e32err.h>
    24 #include <nk_cpu.h>
    25 
    26 #ifndef __KERNEL_MODE__
    27 #error Including kernel header in user code
    28 #endif
    29 
    30 #if defined(__GCC32__)
    31 
    32 
    33 
    34 
    35 /**
    36 @publishedPartner
    37 @released
    38 
    39 64-bit signed integer type.
    40 */
    41 typedef long long Int64;
    42 
    43 
    44 
    45 
    46 /**
    47 @publishedPartner
    48 @released
    49 	
    50 64-bit unsigned integer type.	
    51 */
    52 typedef unsigned long long Uint64;
    53 
    54 
    55 
    56 
    57 #elif defined(__VC32__)
    58 typedef __int64 Int64;
    59 typedef unsigned __int64 Uint64;
    60 #elif defined(__CW32__)
    61 #pragma longlong on
    62 typedef long long Int64;
    63 typedef unsigned long long Uint64;
    64 #endif
    65 
    66 
    67 
    68 
    69 /**
    70 @publishedPartner
    71 @released
    72 	
    73 Defines a 64-bit time value. 
    74 */
    75 typedef Int64 TTimeK;
    76 
    77 
    78 
    79 
    80 #if defined(__VC32__) || defined(__CW32__)
    81 extern "C"
    82 /** @internalComponent */
    83 __NORETURN__ void abort();
    84 #endif
    85 
    86 #ifndef __PLACEMENT_NEW_INLINE
    87 #define __PLACEMENT_NEW_INLINE
    88 // Global placement operator new
    89 /** @internalComponent */
    90 inline TAny* operator new(TUint /*aSize*/, TAny* aBase) __NO_THROW
    91 	{return aBase;}
    92 
    93 // Global placement operator delete
    94 /** @internalComponent */
    95 inline void operator delete(TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW
    96 	{}
    97 #endif //__PLACEMENT_NEW_INLINE
    98 
    99 #ifndef __PLACEMENT_VEC_NEW_INLINE
   100 #define __PLACEMENT_VEC_NEW_INLINE
   101 // Global placement operator new[]
   102 /** @internalComponent */
   103 inline TAny* operator new[](TUint /*aSize*/, TAny* aBase) __NO_THROW
   104 	{return aBase;}
   105 
   106 // Global placement operator delete[]
   107 /** @internalComponent */
   108 inline void operator delete[](TAny* /*aPtr*/, TAny* /*aBase*/) __NO_THROW
   109 	{}
   110 #endif //__PLACEMENT_VEC_NEW_INLINE
   111 
   112 /**
   113 	Macro to offset a SDblQueLink pointer back to the base of a class containing it
   114 	@publishedPartner
   115 	@released
   116 */
   117 #define _LOFF(p,T,f) ((T*)(((TUint8*)(p))-_FOFF(T,f)))
   118 
   119 #ifdef _DEBUG
   120 
   121 /** @internalComponent */
   122 #define KILL_LINK_VALUE (SDblQueLink*)0xdfdfdfdf
   123 
   124 /** @internalComponent */
   125 #define KILL_LINK(l)	(l)->iNext=(l)->iPrev=KILL_LINK_VALUE
   126 
   127 #else
   128 
   129 #define KILL_LINK(l)
   130 
   131 #endif
   132 
   133 
   134 #ifdef __ARMCC__
   135 #define FORCE_INLINE __forceinline
   136 #else
   137 #define FORCE_INLINE inline
   138 #endif
   139 
   140 
   141 /**
   142 @publishedPartner
   143 @released
   144 
   145 An object that forms part of a doubly linked list.
   146 
   147 SDblQueLink can also be embedded within another object so that that object
   148 can form part of the doubly linked list.
   149 
   150 @see SDblQue
   151 */
   152 struct SDblQueLink
   153 	{
   154 	
   155 #ifdef _DEBUG
   156     /**
   157     Default constructor; only defined for debug builds.
   158     
   159     It initialises the link pointers.
   160     */
   161 	FORCE_INLINE SDblQueLink() {iNext=iPrev=NULL;}
   162 #endif
   163 
   164 
   165     /**
   166     Removes this link item from the doubly linked list.
   167     
   168     @return A pointer to this link item.
   169     */
   170 	FORCE_INLINE SDblQueLink* Deque()
   171 		{
   172 		SDblQueLink* next = iNext;
   173 		SDblQueLink* prev = iPrev;
   174 		next->iPrev=prev;
   175 		prev->iNext=next;
   176 		KILL_LINK(this);
   177 		return this;
   178 		}
   179 
   180 
   181     /**
   182     Inserts this link item into the list so that it precedes the specified link item.
   183     
   184     @param aL A pointer to the link item which is to follow this link item.
   185     */
   186 	FORCE_INLINE void InsertBefore(SDblQueLink* aL)
   187 		{
   188 		SDblQueLink* prev = aL->iPrev;
   189 		iNext=aL;
   190 		iPrev=prev;
   191 		prev->iNext=this;
   192 		aL->iPrev=this;
   193 		}
   194 	
   195 		
   196 	/**
   197 	Inserts this link item into the list so that it follows the specified link item.
   198     
   199     @param aL A pointer to the link item which is to precede this link item.
   200     */
   201 	FORCE_INLINE void InsertAfter(SDblQueLink* aL)
   202 		{
   203 		SDblQueLink* next = aL->iNext;
   204 		iPrev=aL;
   205 		iNext=next;
   206 		next->iPrev=this;
   207 		aL->iNext=this;
   208 		}
   209 	
   210 	
   211 	/**
   212 	Tests whether this is the only link item in the list.
   213 	
   214 	@return True, if this is the only link item in the list; false, otherwise.
   215     */
   216 	inline TBool Alone() const
   217 		{ return (iNext==iPrev); }
   218     
   219     
   220     /**
   221     Pointer to the next link item in the list.
   222     */
   223 	SDblQueLink* iNext;
   224 	
   225 	/**
   226     Pointer to the previous link item in the list.
   227     */
   228 	SDblQueLink* iPrev;
   229 	};
   230 
   231 
   232 
   233 
   234 /**
   235 @publishedPartner
   236 @released
   237 
   238 Anchor for a doubly linked list of SDblQueLink items.
   239 
   240 @see SDblQueLink
   241 */
   242 struct SDblQue
   243 	{
   244 	
   245 	
   246 	/**
   247 	Default constructor.
   248 	*/
   249 	FORCE_INLINE SDblQue()
   250 		{ iA.iNext=iA.iPrev=&iA; }
   251 		
   252 	
   253 	/**
   254 	Moves link items from the specified list onto this list, and clears the specified list
   255 	
   256 	@param aQ The source linked list. This list must not be empty.
   257 	*/	
   258 	inline SDblQue(SDblQue* aQ, TInt)		// move entries from aQ onto this queue and clear aQ - aQ must not be empty
   259 		{ new (this) SDblQue(*aQ); iA.iNext->iPrev=&iA; iA.iPrev->iNext=&iA; new (aQ) SDblQue; }
   260 		
   261 		
   262 	/**
   263 	Tests whether this doubly linked list is empty.
   264 	
   265 	@return True, if the list is empty; false, otherwise.
   266 	*/
   267 	FORCE_INLINE TBool IsEmpty() const
   268 		{ return (iA.iNext==&iA); }
   269 	
   270 		
   271     /**
   272     Gets a pointer to the first item in this doubly linked list.
   273     
   274     @return A pointer to the first item.
   275     */		
   276 	FORCE_INLINE SDblQueLink* First() const
   277 		{ return iA.iNext; }
   278 	
   279 		
   280     /**
   281     Gets a pointer to the last item in this doubly linked list.
   282     
   283     @return A pointer to the last item.
   284     */		
   285 	FORCE_INLINE SDblQueLink* Last() const
   286 		{ return iA.iPrev; }
   287 	
   288 		
   289 	/**
   290 	Adds the specified link item onto the end of this doubly linked list.
   291 	
   292 	@param aL A pointer to the link item to be added.
   293 	*/
   294 	FORCE_INLINE void Add(SDblQueLink* aL)
   295 		{
   296 		SDblQueLink* prev = iA.iPrev;
   297 		aL->iNext=&iA;
   298 		aL->iPrev=prev;
   299 		prev->iNext=aL;
   300 		iA.iPrev=aL;
   301 		}
   302 	
   303 		
   304 	/**
   305 	Adds the specified link item onto the front of this doubly linked list.
   306 	
   307 	@param aL A pointer to the link item to be added.
   308 	*/
   309 	FORCE_INLINE void AddHead(SDblQueLink* aL)
   310 		{
   311 		SDblQueLink* next = iA.iNext;
   312 		aL->iNext=next;
   313 		aL->iPrev=&iA;
   314 		next->iPrev=aL;
   315 		iA.iNext=aL;
   316 		}
   317 	
   318 		
   319 	/**
   320     Removes the last link item from the linked list and adds it to the front
   321     of the list. 
   322 	*/
   323 	inline void Rotate()
   324 		{ SDblQueLink* pL=iA.iPrev; pL->Deque(); AddHead(pL); }
   325 		
   326 		
   327 	/**
   328 	Gets the first link item in the linked list.
   329 	
   330 	@return The first link item in the list; NULL, if the list is empty.
   331 	*/
   332 	inline SDblQueLink* GetFirst()
   333 		{ if (IsEmpty()) return NULL; else return First()->Deque(); }
   334 
   335 
   336 	/**
   337 	Gets the last link item in the linked list.
   338 	
   339 	@return The last link item in the list; NULL, if the list is empty.
   340 	*/
   341 	inline SDblQueLink* GetLast()
   342 		{ if (IsEmpty()) return NULL; else return Last()->Deque(); }
   343 
   344 
   345 	/**
   346 	Appends entries from the specified linked list onto this list, and clears
   347 	the specified link list anchor.
   348 	
   349 	@param aQ The source linked list.
   350 	*/
   351 	inline void MoveFrom(SDblQue* aQ)	// append entries from aQ onto this queue and clear aQ
   352 		{ if (!aQ->IsEmpty())
   353 			{iA.iPrev->iNext=aQ->iA.iNext; aQ->iA.iNext->iPrev=iA.iPrev; iA.iPrev=aQ->iA.iPrev; iA.iPrev->iNext=&iA; new (aQ) SDblQue; }
   354 		}
   355 
   356 
   357     /**
   358     The anchor point for the doubly linked list.
   359     */
   360 	SDblQueLink iA;
   361 	};
   362 
   363 
   364 
   365 
   366 /**
   367 @publishedPartner
   368 @released
   369 
   370 An object that forms part of a doubly linked list arranged
   371 in descending key order.
   372 
   373 @see SOrdQue
   374 */
   375 struct SOrdQueLink : public SDblQueLink
   376 	{
   377 	
   378 	
   379 	/**
   380 	The key value used to order the link item.
   381 	*/
   382 	TInt iKey;
   383 	};
   384 
   385 
   386 
   387 
   388 /**
   389 @publishedPartner
   390 @released
   391 
   392 Anchor for a doubly linked list of SOrdQueLink items.
   393 
   394 The items in this linked list are in descending key order.
   395 
   396 @see SOrdQueLink
   397 */
   398 struct SOrdQue : public SDblQue
   399 	{
   400 	
   401 	
   402 	/**
   403 	Adds the specified link item into this doubly linked list so that
   404 	the list remains in descending key order.
   405 	
   406 	@param aL A pointer to the link item to be added.
   407 	*/
   408 	inline void Add(SOrdQueLink* aL)
   409 		{
   410 		SOrdQueLink* pQ=(SOrdQueLink*)iA.iNext;
   411 		TInt k=aL->iKey;
   412 		while(pQ!=&iA && (pQ->iKey>=k)) pQ=(SOrdQueLink*)pQ->iNext;
   413 		aL->InsertBefore(pQ);
   414 		}
   415 	};
   416 
   417 
   418 
   419 
   420 /**
   421 @publishedPartner
   422 @released
   423 
   424 An object that forms part of a doubly linked list arranged
   425 in 'delta' order.
   426 
   427 The item represents some value that is an increment, or delta,
   428 on the value represented by a preceding element.
   429 
   430 @see SDeltaQue
   431 */
   432 struct SDeltaQueLink : public SDblQueLink
   433 	{
   434 	/**
   435 	The delta value.
   436 	*/
   437 	TInt iDelta;
   438 	};
   439 
   440 
   441 
   442 
   443 /**
   444 @publishedPartner
   445 @released
   446 
   447 Anchor for a doubly linked list of SDeltaQueLink items.
   448 
   449 An item in this linked list represents a value that is an increment,
   450 or a delta, on the value represented by a preceding element.
   451 The list is ordered so that the head of the queue represents a nominal zero point.
   452 
   453 @see SDeltaQueLink
   454 */
   455 struct SDeltaQue : public SDblQue
   456 	{
   457 	
   458 	
   459 	/**
   460 	Gets the delta value of the first link item in the list.
   461 
   462     @return The delta value.
   463 	*/
   464 	inline TInt FirstDelta() const
   465 		{return ((SDeltaQueLink*)First())->iDelta;}
   466 		
   467 		
   468     /**
   469     Decrements the delta value of the first item in the list by the specified value.
   470 
   471     @param aCount The amount by which the delta value is to be reduced.
   472 
   473     @return True, if the resulting delta value is negative or zero;
   474             false, if the value is positive.
   475     */		
   476 	inline TBool CountDown(TInt aCount)
   477 		{SDeltaQueLink& l=*(SDeltaQueLink*)First(); return((l.iDelta-=aCount)<=0);}
   478 		
   479 	
   480 	/**
   481 	Adds the specified list item, having the specified 'distance' from
   482 	the nominal zero point, into the list.
   483 
   484     The item is added into the list, the adjacent delta values are adjusted,
   485     and a suitable delta value assigned to the new item so that
   486     the new item is at the specified 'distance' from the nominal zero point.
   487 
   488     @param aL     The item to be inserted. 
   489     @param aDelta The 'distance' of the item from the nominal zero point.
   490 	*/
   491 	inline void Add(SDeltaQueLink* aL, TInt aDelta)
   492 		{
   493 		SDeltaQueLink* pQ=(SDeltaQueLink*)iA.iNext;
   494 		while(pQ!=&iA && aDelta>=pQ->iDelta)
   495 			{ aDelta-=pQ->iDelta; pQ=(SDeltaQueLink*)pQ->iNext; }
   496 		aL->iDelta=aDelta;
   497 		aL->InsertBefore(pQ);
   498 		if (pQ!=&iA) pQ->iDelta-=aDelta;
   499 		}
   500 				
   501 		
   502 	/**
   503 	Removes the specified link item from the list.
   504 	
   505 	The delta value of the item following the removed item is adjusted
   506 	so that its 'distance' from the nominal zero point remains the same.
   507 	
   508 	@param aL The list item to be removed.
   509 	
   510 	@return A pointer to the item removed from the queue.
   511 	*/
   512 	inline SDeltaQueLink* Remove(SDeltaQueLink* aL)
   513 		{
   514 		if (aL->iNext!=&iA)
   515 			{
   516 			SDeltaQueLink& next=*(SDeltaQueLink*)aL->iNext;
   517 			next.iDelta+=aL->iDelta;
   518 			}
   519 		return (SDeltaQueLink*)aL->Deque();
   520 		}
   521 		
   522 		
   523     /**
   524     Removes the first item from the linked list if its delta value
   525     is zero or negative.
   526     
   527     @return A pointer to the item removed from the linked list.
   528             This is NULL, if the first element has a positive delta value,
   529             and has not been removed from the list.
   530     */		
   531 	inline SDeltaQueLink* RemoveFirst()
   532 		{
   533 		SDeltaQueLink& l=*(SDeltaQueLink*)First();
   534 		if (l.iDelta<=0)
   535 			return Remove(&l);
   536 		return NULL;
   537 		}
   538 	};
   539 
   540 
   541 
   542 
   543 /**
   544 @publishedPartner
   545 @released
   546 
   547 An object that forms part of a TPriList, priority ordered lists.
   548 
   549 @see TPriListBase
   550 @see TPriList
   551 */
   552 class TPriListLink : public SDblQueLink
   553 	{
   554 public:
   555 
   556     
   557     /**
   558     Default constructor.
   559     
   560     Sets the priority value to zero.
   561     */
   562 	inline TPriListLink() : iPriority(0) {}
   563 	
   564 	
   565     /**
   566     Constructor.
   567     
   568     Sets the priority to the specified value.
   569     
   570     @param aPriority The priority value.
   571     */
   572 	inline TPriListLink(TInt aPriority) : iPriority((TUint8)aPriority) {}
   573 	
   574 	
   575 	/**
   576 	Tests whether this is a solitary link item.
   577 	
   578 	@return True, if this is a solitary link item; false, otherwise. 
   579 	*/
   580 	inline TBool Alone() const
   581 		{ return (iNext==(SDblQueLink*)this); }
   582 public:
   583 
   584     /** 
   585     The priority value.
   586     */
   587 	TUint8 iPriority;
   588 	
   589 	/**
   590 	Reserved for future use.
   591 	*/
   592 	TUint8 iSpare1;
   593 	
   594 		
   595 	/**
   596 	Reserved for future use.
   597 	*/
   598 	TUint8 iSpare2;
   599 	
   600 		
   601 	/**
   602 	Reserved for future use.
   603 	*/
   604 	TUint8 iSpare3;
   605 	};
   606 
   607 
   608 
   609 
   610 /**
   611 @publishedPartner
   612 @released
   613 
   614 Base class for a TPriList, priority ordered lists.
   615 
   616 @see TPriListLink
   617 @see TPriList
   618 */
   619 class TPriListBase
   620 	{
   621 public:
   622 	IMPORT_C TPriListBase(TInt aNumPriorities);
   623 	IMPORT_C TInt HighestPriority();
   624 	IMPORT_C TPriListLink* First();
   625 	IMPORT_C void Add(TPriListLink* aLink);
   626 	IMPORT_C void AddHead(TPriListLink* aLink);
   627 	IMPORT_C void Remove(TPriListLink* aLink);
   628 	IMPORT_C void ChangePriority(TPriListLink* aLink, TInt aNewPriority);
   629 	
   630 	/**
   631 	Tests whether there are any non-empty lists.
   632 		
   633 	@return True, if there are non-empty lists; false, if all lists are empty.
   634 	*/
   635 	inline TBool NonEmpty() const
   636 		{ return iPresent[0]|iPresent[1]; }
   637 		
   638 	/**
   639 	Tests whether there are any non-empty lists.
   640 		
   641 	@return True, if all lists are empty
   642 	*/
   643 	inline TBool IsEmpty() const
   644 		{ return !iPresent[0] && !iPresent[1]; }
   645 		
   646 	/**
   647 	Tests whether any linked list with priority greater than p is non-empty.
   648 
   649 	@param p The priority value (0-63).
   650 
   651 	@return True, if any list with priority greater than p is non-empty; false, otherwise.	
   652 	*/
   653 	inline TBool operator>(TInt p) const
   654 		{ return ((p<32) ? (iPresent[1] | (iPresent[0]>>p)>>1) : (iPresent[1]>>(p-32))>>1 ); }
   655 public:
   656 
   657     /**
   658     64-bit mask to indicate which list is non-empty.
   659 
   660     Bit n in the mask is set if and only if the linked list for priority n is non-empty.
   661     */
   662 	union
   663 		{
   664 		TUint iPresent[2];
   665 		TUint64 iPresent64;
   666 		};
   667 	
   668 	/**
   669 	Pointer to the first linked list.
   670 	*/
   671 	SDblQueLink* iQueue[1];
   672 	};
   673 
   674 
   675 
   676 
   677 template<class T, int n>
   678 /**
   679 @publishedPartner
   680 @released
   681 
   682 Anchor for a collection of doubly linked lists, where each list
   683 corresponds to a priority value.
   684 
   685 The lists are ordered by priority value, but items within
   686 a list are in chronological order.
   687 
   688 The number of lists is defined by the template integer parameter,
   689 and each item in each list is of a class type defined by the template class parameter.
   690 The number of lists must be between 1 and 64 inclusive.
   691 
   692 @see TPriListLink
   693 */
   694 class TPriList : public TPriListBase
   695 	{
   696 public:
   697     /**
   698     Constructor.
   699     */
   700 	inline TPriList() : TPriListBase(n) {}
   701 	
   702 	
   703 	/**
   704 	Finds the highest priority item present on a priority list.
   705 	If multiple items at the same priority are present, return the first to be
   706 	added in chronological order.
   707 
   708 	@return	a pointer to the item or NULL if the list is empty.
   709 	*/
   710 	inline T* First() { return (T*)TPriListBase::First(); }
   711 private:
   712 	SDblQueLink* iExtraQueues[n-1];
   713 	};
   714 
   715 
   716 
   717 /** Base for variant interface block
   718 @internalTechnology
   719 @prototype
   720 */
   721 struct SInterfaceBlockBase
   722 	{
   723 	TUint32	iVer;	// version number
   724 	TUint32	iSize;	// size in bytes
   725 	};
   726 #endif