|
1 // Copyright (c) 1998-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\nkern\sched.cpp |
|
15 // |
|
16 // |
|
17 |
|
18 // TDfc member data |
|
19 #define __INCLUDE_TDFC_DEFINES__ |
|
20 #define __INCLUDE_NTHREADBASE_DEFINES__ |
|
21 |
|
22 #include "nk_priv.h" |
|
23 |
|
24 void ResumeDelayedThreads(TAny*) |
|
25 { |
|
26 TScheduler& s=TheScheduler; |
|
27 while (!s.iDelayedQ.IsEmpty()) |
|
28 { |
|
29 NThreadBase& t = *(NThreadBase*)s.iDelayedQ.First()->Deque(); |
|
30 t.i_ThrdAttr &= ~KThreadAttDelayed; |
|
31 if (t.iSuspendCount==0) |
|
32 t.DoReady(); |
|
33 else |
|
34 t.iNState=NThreadBase::ESuspended; |
|
35 } |
|
36 } |
|
37 |
|
38 // Don't need to zero initialise anything here since |
|
39 // TheScheduler resides in .bss |
|
40 TScheduler::TScheduler() |
|
41 : TPriListBase(KNumPriorities), iKernCSLocked(1), iDelayDfc(ResumeDelayedThreads, NULL) |
|
42 { |
|
43 } |
|
44 |
|
45 |
|
46 /** Return a pointer to the scheduler |
|
47 Intended for use by the crash debugger, not for general device driver use. |
|
48 |
|
49 @return Pointer to the scheduler object |
|
50 @internalTechnology |
|
51 */ |
|
52 EXPORT_C TScheduler* TScheduler::Ptr() |
|
53 { |
|
54 return &TheScheduler; |
|
55 } |
|
56 |
|
57 |
|
58 #ifndef __MSTIM_MACHINE_CODED__ |
|
59 // Enter and leave with interrupts off |
|
60 void TScheduler::TimesliceTick() |
|
61 { |
|
62 NThreadBase* pC=iCurrentThread; |
|
63 if (pC->iTime>0 && --pC->iTime==0) |
|
64 RescheduleNeeded(); |
|
65 } |
|
66 #endif |
|
67 |
|
68 #ifndef __SCHEDULER_MACHINE_CODED__ |
|
69 void TScheduler::Remove(NThreadBase* aThread) |
|
70 { |
|
71 __NK_ASSERT_DEBUG(!aThread->iHeldFastMutex); // can't block while holding fast mutex |
|
72 aThread->iTime=aThread->iTimeslice; // thread has blocked so it gets a fresh timeslice for next time |
|
73 TPriListBase::Remove(aThread); |
|
74 } |
|
75 #endif |
|
76 |
|
77 void TScheduler::RotateReadyList(TInt p) |
|
78 // |
|
79 // rotate the ready list for priority p |
|
80 // |
|
81 { |
|
82 __NK_ASSERT_DEBUG(p>=0 && p<KNumPriorities); |
|
83 SDblQueLink* pQ=iQueue[p]; |
|
84 if (pQ) |
|
85 { |
|
86 SDblQueLink* pN=pQ->iNext; |
|
87 if (pN!=pQ) |
|
88 { |
|
89 NThread* pT=(NThread*)pQ; |
|
90 pT->iTime=pT->iTimeslice; |
|
91 iQueue[p]=pN; |
|
92 if (pQ==iCurrentThread) |
|
93 RescheduleNeeded(); |
|
94 } |
|
95 } |
|
96 } |
|
97 |
|
98 /** Converts a time interval in microseconds to thread timeslice ticks |
|
99 |
|
100 @param aMicroseconds time interval in microseconds. |
|
101 @return Number of thread timeslice ticks. Non-integral results are rounded up. |
|
102 |
|
103 @pre aMicroseconds should be nonnegative |
|
104 @pre any context |
|
105 */ |
|
106 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds) |
|
107 { |
|
108 TUint32 msp = TheTimerQ.iTickPeriod; |
|
109 TUint32 ticks = (TUint32(aMicroseconds) + msp - 1) / msp; |
|
110 return ticks; |
|
111 } |
|
112 |
|
113 |
|
114 /** Return the total CPU time so far used by the specified thread. |
|
115 |
|
116 @return The total CPU time in units of 1/NKern::CpuTimeMeasFreq(). |
|
117 */ |
|
118 EXPORT_C TUint64 NKern::ThreadCpuTime(NThread* aThread) |
|
119 { |
|
120 #ifdef MONITOR_THREAD_CPU_TIME |
|
121 NKern::Lock(); |
|
122 TUint64 t = aThread->iTotalCpuTime; |
|
123 if (aThread == TheScheduler.iCurrentThread) |
|
124 t += TUint64(NKern::FastCounter() - aThread->iLastStartTime); |
|
125 NKern::Unlock(); |
|
126 return t; |
|
127 #else |
|
128 return 0; |
|
129 #endif |
|
130 } |