|
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 |