author | Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com> |
Fri, 16 Apr 2010 16:24:37 +0300 | |
changeset 90 | 947f0dc9f7a8 |
parent 0 | a41df078684a |
child 109 | b3a1d9898418 |
child 177 | a232af6b0b1f |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright (c) 2005-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\nkernsmp\nkerns.cpp |
|
15 |
// |
|
16 |
// |
|
17 |
||
18 |
// NThreadBase member data |
|
19 |
#define __INCLUDE_NTHREADBASE_DEFINES__ |
|
20 |
||
21 |
#include <e32cmn.h> |
|
22 |
#include <e32cmn_private.h> |
|
23 |
#include "nk_priv.h" |
|
24 |
||
25 |
extern "C" void ExcFault(TAny*); |
|
26 |
||
27 |
/****************************************************************************** |
|
28 |
* Fast mutex |
|
29 |
******************************************************************************/ |
|
30 |
/** Create a fast mutex |
|
31 |
||
32 |
@publishedPartner |
|
33 |
@released |
|
34 |
*/ |
|
35 |
EXPORT_C NFastMutex::NFastMutex() |
|
36 |
: iHoldingThread(0), iMutexLock(TSpinLock::EOrderFastMutex) |
|
37 |
{ |
|
38 |
} |
|
39 |
||
40 |
/****************************************************************************** |
|
41 |
* NSchedulable |
|
42 |
******************************************************************************/ |
|
43 |
NSchedulable::NSchedulable() |
|
44 |
: iSSpinLock(TSpinLock::EOrderThread) |
|
45 |
{ |
|
46 |
iPriority = 0; |
|
47 |
iReady = 0; |
|
48 |
iCurrent = 0; |
|
49 |
iLastCpu = 0; |
|
50 |
iPauseCount = 0; |
|
51 |
iSuspended = 0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
52 |
iACount = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
53 |
iPreferredCpu = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
54 |
iActiveState = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
55 |
i_NSchedulable_Spare2 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
56 |
iTransientCpu = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
57 |
iForcedCpu = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
58 |
iLbState = ELbState_Inactive; |
0 | 59 |
iCpuChange = 0; |
60 |
iStopping = 0; |
|
61 |
iFreezeCpu = 0; |
|
62 |
iParent = (NSchedulable*)0xdeadbeef; |
|
63 |
iCpuAffinity = 0; |
|
64 |
new (i_IDfcMem) TDfc(&DeferredReadyIDfcFn, this); |
|
65 |
iEventState = 0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
66 |
iRunCount.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
67 |
iLastRunTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
68 |
iTotalCpuTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
69 |
iLastActivationTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
70 |
iTotalActiveTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
71 |
iSavedCpuTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
72 |
iSavedActiveTime.i64 = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
73 |
iLbLink.iNext = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
74 |
memclr(&iLbInfo, EMaxLbInfoSize); |
0 | 75 |
} |
76 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
77 |
void NSchedulable::AddToEnumerateList() |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
78 |
{ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
79 |
TScheduler& s = TheScheduler; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
80 |
SIterDQ& dq = iParent ? s.iAllThreads : s.iAllGroups; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
81 |
NKern::Lock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
82 |
s.iEnumerateLock.LockOnly(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
83 |
dq.Add(&iEnumerateLink); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
84 |
TUint32 active = s.iThreadAcceptCpus; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
85 |
TUint32 cpus = active & iCpuAffinity; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
86 |
if (!cpus) |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
87 |
cpus = active; // can't run on any currently active CPU, just pick an active one until it becomes ready |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
88 |
TInt ecpu = __e32_find_ls1_32(cpus); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
89 |
iEventState = (ecpu<<EEventCpuShift) | (ecpu<<EThreadCpuShift); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
90 |
s.iEnumerateLock.UnlockOnly(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
91 |
NKern::Unlock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
92 |
} |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
93 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
94 |
|
0 | 95 |
/****************************************************************************** |
96 |
* NThreadGroup |
|
97 |
******************************************************************************/ |
|
98 |
NThreadGroup::NThreadGroup() |
|
99 |
{ |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
100 |
iACount = 1; |
0 | 101 |
iParent = 0; |
102 |
iThreadCount = 0; |
|
103 |
new (&iSSpinLock) TSpinLock(TSpinLock::EOrderThreadGroup); |
|
104 |
} |
|
105 |
||
106 |
/** Create a thread group |
|
107 |
||
108 |
@publishedPartner |
|
109 |
@prototype |
|
110 |
*/ |
|
111 |
EXPORT_C TInt NKern::GroupCreate(NThreadGroup* aGroup, SNThreadGroupCreateInfo& aInfo) |
|
112 |
{ |
|
113 |
new (aGroup) NThreadGroup(); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
114 |
aGroup->iDestructionDfc = aInfo.iDestructionDfc; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
115 |
aGroup->iCpuAffinity = NSchedulable::PreprocessCpuAffinity(aInfo.iCpuAffinity); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
116 |
aGroup->AddToEnumerateList(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
117 |
aGroup->InitLbInfo(); |
0 | 118 |
return KErrNone; |
119 |
} |
|
120 |
||
121 |
||
122 |
/** Destroy a thread group |
|
123 |
||
124 |
@pre Call in thread context, interrupts enabled, preemption enabled |
|
125 |
@pre No fast mutex held |
|
126 |
@pre Calling thread in critical section |
|
127 |
@pre All threads have left the group |
|
128 |
||
129 |
@publishedPartner |
|
130 |
@prototype |
|
131 |
*/ |
|
132 |
EXPORT_C void NKern::GroupDestroy(NThreadGroup* aGroup) |
|
133 |
{ |
|
134 |
NKern::ThreadEnterCS(); |
|
135 |
aGroup->DetachTiedEvents(); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
136 |
NKern::Lock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
137 |
aGroup->AcqSLock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
138 |
if (aGroup->iLbLink.iNext) |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
139 |
aGroup->LbUnlink(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
140 |
aGroup->RelSLock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
141 |
aGroup->DropRef(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
142 |
NKern::Unlock(); |
0 | 143 |
NKern::ThreadLeaveCS(); |
144 |
} |
|
145 |
||
146 |
||
147 |
/****************************************************************************** |
|
148 |
* Thread |
|
149 |
******************************************************************************/ |
|
150 |
void InvalidExec() |
|
151 |
{ |
|
152 |
FAULT(); |
|
153 |
} |
|
154 |
||
155 |
static const SFastExecTable DefaultFastExecTable={0,{0}}; |
|
156 |
static const SSlowExecTable DefaultSlowExecTable={0,(TLinAddr)InvalidExec,0,{{0,0}}}; |
|
157 |
||
158 |
const SNThreadHandlers NThread_Default_Handlers = |
|
159 |
{ |
|
160 |
NTHREAD_DEFAULT_EXIT_HANDLER, |
|
161 |
NTHREAD_DEFAULT_STATE_HANDLER, |
|
162 |
NTHREAD_DEFAULT_EXCEPTION_HANDLER, |
|
163 |
NTHREAD_DEFAULT_TIMEOUT_HANDLER |
|
164 |
}; |
|
165 |
||
166 |
NThreadWaitState::NThreadWaitState() |
|
167 |
: iTimer(&TimerExpired, this) |
|
168 |
{ |
|
169 |
iWtSt64 = 0; |
|
170 |
iTimer.iTriggerTime = 0; |
|
171 |
iTimer.iNTimerSpare1 = 0; |
|
172 |
} |
|
173 |
||
174 |
NThreadBase::NThreadBase() |
|
175 |
: iRequestSemaphore(), iWaitState() |
|
176 |
{ |
|
177 |
iParent = this; |
|
178 |
iWaitLink.iPriority = 0; |
|
179 |
iBasePri = 0; |
|
180 |
iMutexPri = 0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
181 |
iNominalPri = 0; |
0 | 182 |
iLinkedObjType = EWaitNone; |
183 |
i_ThrdAttr = 0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
184 |
i_NThread_Initial = 0; |
0 | 185 |
iFastMutexDefer = 0; |
186 |
iRequestSemaphore.iOwningThread = (NThreadBase*)this; |
|
187 |
iTime = 0; |
|
188 |
iTimeslice = 0; |
|
189 |
iSavedSP = 0; |
|
190 |
iAddressSpace = 0; |
|
191 |
iHeldFastMutex = 0; |
|
192 |
iUserModeCallbacks = 0; |
|
193 |
iLinkedObj = 0; |
|
194 |
iNewParent = 0; |
|
195 |
iFastExecTable = 0; |
|
196 |
iSlowExecTable = 0; |
|
197 |
iCsCount = 0; |
|
198 |
iCsFunction = 0; |
|
199 |
iHandlers = 0; |
|
200 |
iSuspendCount = 0; |
|
201 |
iStackBase = 0; |
|
202 |
iStackSize = 0; |
|
203 |
iExtraContext = 0; |
|
204 |
iExtraContextSize = 0; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
205 |
iCoreCycling = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
206 |
iRebalanceAttr = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
207 |
iNThreadBaseSpare4c = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
208 |
iNThreadBaseSpare4d = 0; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
209 |
iNThreadBaseSpare5 = 0; |
0 | 210 |
iNThreadBaseSpare6 = 0; |
211 |
iNThreadBaseSpare7 = 0; |
|
212 |
iNThreadBaseSpare8 = 0; |
|
213 |
iNThreadBaseSpare9 = 0; |
|
214 |
} |
|
215 |
||
216 |
TInt NThreadBase::Create(SNThreadCreateInfo& aInfo, TBool aInitial) |
|
217 |
{ |
|
218 |
__KTRACE_OPT(KNKERN,DEBUGPRINT(">NThreadBase::Create %08x(%08x,%d)", this, &aInfo, aInitial)); |
|
219 |
if (aInfo.iPriority<0 || aInfo.iPriority>63) |
|
220 |
return KErrArgument; |
|
221 |
if (aInfo.iPriority==0 && !aInitial) |
|
222 |
return KErrArgument; |
|
223 |
// if (aInfo.iCpu!=KCpuAny && aInfo.iCpu>=TheScheduler.iNumCpus) |
|
224 |
// return KErrArgument; |
|
225 |
iStackBase=(TLinAddr)aInfo.iStackBase; |
|
226 |
iStackSize=aInfo.iStackSize; |
|
227 |
iTimeslice=(aInfo.iTimeslice>0)?aInfo.iTimeslice:-1; |
|
228 |
iTime=iTimeslice; |
|
229 |
iPriority=TUint8(aInfo.iPriority); |
|
230 |
iBasePri=TUint8(aInfo.iPriority); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
231 |
iNominalPri=TUint8(aInfo.iPriority); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
232 |
iCpuAffinity = NSchedulable::PreprocessCpuAffinity(aInfo.iCpuAffinity); |
0 | 233 |
iHandlers = aInfo.iHandlers ? aInfo.iHandlers : &NThread_Default_Handlers; |
234 |
iFastExecTable=aInfo.iFastExecTable?aInfo.iFastExecTable:&DefaultFastExecTable; |
|
235 |
iSlowExecTable=(aInfo.iSlowExecTable?aInfo.iSlowExecTable:&DefaultSlowExecTable)->iEntries; |
|
236 |
i_ThrdAttr=(TUint8)aInfo.iAttributes; |
|
237 |
if (aInitial) |
|
238 |
{ |
|
239 |
TSubScheduler& ss = SubScheduler(); |
|
240 |
iLastCpu = (TUint8)ss.iCpuNum; |
|
241 |
iReady = (TUint8)(iLastCpu | EReadyOffset); |
|
242 |
iCurrent = iReady; |
|
243 |
iCpuAffinity = iLastCpu; |
|
244 |
iEventState = (iLastCpu<<EEventCpuShift) | (iLastCpu<<EThreadCpuShift); |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
245 |
ss.SSAddEntry(this); |
0 | 246 |
i_NThread_Initial = TRUE; |
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
247 |
iACount = 1; |
0 | 248 |
ss.iInitialThread = (NThread*)this; |
249 |
NKern::Unlock(); // now that current thread is defined |
|
250 |
} |
|
251 |
else |
|
252 |
{ |
|
253 |
iSuspendCount = 1; |
|
254 |
iSuspended = 1; |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
255 |
iEventState = 0; |
0 | 256 |
if (aInfo.iGroup) |
257 |
{ |
|
258 |
NKern::Lock(); |
|
259 |
AcqSLock(); |
|
260 |
aInfo.iGroup->AcqSLock(); |
|
261 |
iParent = (NSchedulable*)aInfo.iGroup; |
|
262 |
++aInfo.iGroup->iThreadCount; |
|
263 |
iEventState |= EEventParent; |
|
264 |
RelSLock(); |
|
265 |
NKern::Unlock(); |
|
266 |
} |
|
267 |
} |
|
268 |
__KTRACE_OPT(KNKERN,DEBUGPRINT("<NThreadBase::Create OK")); |
|
269 |
return KErrNone; |
|
270 |
} |
|
271 |
||
272 |
void NThread_Default_State_Handler(NThread* __DEBUG_ONLY(aThread), TInt __DEBUG_ONLY(aOperation), TInt __DEBUG_ONLY(aParameter)) |
|
273 |
{ |
|
274 |
// __KTRACE_OPT(KPANIC,DEBUGPRINT("Unknown NState %d: thread %T op %08x par %08x",aThread,aThread->iNState,aOperation,aParameter)); |
|
275 |
#ifdef _DEBUG |
|
276 |
DEBUGPRINT("UnknownState: thread %T op %08x par %08x",aThread,aOperation,aParameter); |
|
277 |
#endif |
|
278 |
FAULT(); |
|
279 |
} |
|
280 |
||
281 |
void NThread_Default_Exception_Handler(TAny* aContext, NThread*) |
|
282 |
{ |
|
283 |
ExcFault(aContext); |
|
284 |
} |
|
285 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
286 |
// |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
287 |
// Destroy a thread before it has ever run |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
288 |
// Must be called before first resumption of thread |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
289 |
// |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
290 |
void NThread::Stillborn() |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
291 |
{ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
292 |
__NK_ASSERT_ALWAYS(iACount==0); // ensure thread has never been resumed |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
293 |
NKern::Lock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
294 |
RemoveFromEnumerateList(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
295 |
NKern::Unlock(); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
296 |
} |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
297 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
298 |
|
0 | 299 |
|
300 |
/** Create a nanothread. |
|
301 |
||
302 |
This function is intended to be used by the EPOC kernel and by personality |
|
303 |
layers. A nanothread may not use most of the functions available to normal |
|
304 |
Symbian OS threads. Use Kern::ThreadCreate() to create a Symbian OS thread. |
|
305 |
||
306 |
@param aThread Pointer to control block for thread to create. |
|
307 |
@param aInfo Information needed for creating the thread. |
|
308 |
||
309 |
@see SNThreadCreateInfo |
|
310 |
@see Kern::ThreadCreate |
|
311 |
||
312 |
@pre Call in a thread context. |
|
313 |
@pre Interrupts must be enabled. |
|
314 |
@pre Kernel must be unlocked. |
|
315 |
*/ |
|
316 |
EXPORT_C TInt NKern::ThreadCreate(NThread* aThread, SNThreadCreateInfo& aInfo) |
|
317 |
{ |
|
318 |
CHECK_PRECONDITIONS(MASK_KERNEL_UNLOCKED|MASK_INTERRUPTS_ENABLED|MASK_NOT_ISR|MASK_NOT_IDFC,"NKern::ThreadCreate"); |
|
319 |
return aThread->Create(aInfo,FALSE); |
|
320 |
} |
|
321 |
||
322 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
323 |
/****************************************************************************** |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
324 |
* User-mode callbacks |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
325 |
******************************************************************************/ |
0 | 326 |
TUserModeCallback::TUserModeCallback(TUserModeCallbackFunc aFunc) |
327 |
: iNext(KUserModeCallbackUnqueued), |
|
328 |
iFunc(aFunc) |
|
329 |
{ |
|
330 |
} |
|
331 |
||
332 |
TUserModeCallback::~TUserModeCallback() |
|
333 |
{ |
|
334 |
__NK_ASSERT_DEBUG(iNext == KUserModeCallbackUnqueued); |
|
335 |
} |
|
336 |
||
337 |
void NKern::CancelUserModeCallbacks() |
|
338 |
{ |
|
339 |
// Call any queued callbacks with the EUserModeCallbackCancel reason code, in the current |
|
340 |
// thread. |
|
341 |
||
342 |
TUserModeCallback* listHead = |
|
343 |
(TUserModeCallback*)__e32_atomic_swp_ord_ptr(&NCurrentThread()->iUserModeCallbacks, NULL); |
|
344 |
while (listHead) |
|
345 |
{ |
|
346 |
TUserModeCallback* callback = listHead; |
|
347 |
listHead = listHead->iNext; |
|
348 |
callback->iNext = KUserModeCallbackUnqueued; |
|
349 |
__e32_memory_barrier(); |
|
350 |
callback->iFunc(callback, EUserModeCallbackCancel); |
|
351 |
} |
|
352 |
} |
|
353 |
||
354 |
void NKern::MoveUserModeCallbacks(NThreadBase* aDestThread, NThreadBase* aSrcThread) |
|
355 |
{ |
|
356 |
// Move all queued user-mode callbacks from the source thread to the destination thread, and |
|
357 |
// prevent any more from being queued. Used by the kernel thread code so that callbacks get |
|
358 |
// cancelled in another thread if the thread they were originally queued on dies. |
|
359 |
||
360 |
// Atomically remove list of callbacks and set pointer to 1 |
|
361 |
// The latter ensures any subsequent attempts to add callbacks fail |
|
362 |
TUserModeCallback* sourceListStart = |
|
363 |
(TUserModeCallback*)__e32_atomic_swp_ord_ptr(&aSrcThread->iUserModeCallbacks, (TAny*)1); |
|
364 |
__NK_ASSERT_DEBUG(((TUint)sourceListStart & 3) == 0); // check this only gets called once per thread |
|
365 |
||
366 |
if (sourceListStart == NULL) |
|
367 |
return; |
|
368 |
||
369 |
TUserModeCallback* sourceListEnd = sourceListStart; |
|
370 |
while (sourceListEnd->iNext != NULL) |
|
371 |
sourceListEnd = sourceListEnd->iNext; |
|
372 |
||
373 |
NKern::Lock(); |
|
374 |
TUserModeCallback* destListStart = aDestThread->iUserModeCallbacks; |
|
375 |
do |
|
376 |
{ |
|
377 |
__NK_ASSERT_DEBUG(((TUint)destListStart & 3) == 0); // dest thread must not die |
|
378 |
sourceListEnd->iNext = destListStart; |
|
379 |
} while (!__e32_atomic_cas_ord_ptr(&aDestThread->iUserModeCallbacks, &destListStart, sourceListStart)); |
|
380 |
NKern::Unlock(); |
|
381 |
} |
|
382 |
||
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
383 |
|
0 | 384 |
/** Initialise the null thread |
385 |
@internalComponent |
|
386 |
*/ |
|
387 |
void NKern::Init(NThread* aThread, SNThreadCreateInfo& aInfo) |
|
388 |
{ |
|
389 |
aInfo.iFunction=NULL; // irrelevant |
|
390 |
aInfo.iPriority=0; // null thread has lowest priority |
|
391 |
aInfo.iTimeslice=0; // null thread not timesliced |
|
392 |
aInfo.iAttributes=0; // null thread does not require implicit locks |
|
393 |
aThread->Create(aInfo,TRUE); // create the null thread |
|
394 |
} |
|
395 |
||
396 |
/** @internalTechnology */ |
|
397 |
EXPORT_C void NKern::RecordIntLatency(TInt /*aLatency*/, TInt /*aIntMask*/) |
|
398 |
{ |
|
399 |
} |
|
400 |
||
401 |
||
402 |
/** @internalTechnology */ |
|
403 |
EXPORT_C void NKern::RecordThreadLatency(TInt /*aLatency*/) |
|
404 |
{ |
|
405 |
} |
|
406 |
||
407 |
/******************************************** |
|
408 |
* Deterministic Priority List Implementation |
|
409 |
********************************************/ |
|
410 |
||
411 |
||
412 |
/** Construct a priority list with the specified number of priorities |
|
413 |
||
414 |
@param aNumPriorities The number of priorities (must be 1-64). |
|
415 |
*/ |
|
416 |
EXPORT_C TPriListBase::TPriListBase(TInt aNumPriorities) |
|
417 |
{ |
|
418 |
memclr(this, sizeof(TPriListBase)+(aNumPriorities-1)*sizeof(SDblQueLink*) ); |
|
419 |
} |
|
420 |
||
421 |
||
422 |
/******************************************** |
|
423 |
* Miscellaneous |
|
424 |
********************************************/ |
|
425 |
||
426 |
/** Get the current value of the high performance counter. |
|
427 |
||
428 |
If a high performance counter is not available, this uses the millisecond |
|
429 |
tick count instead. |
|
430 |
*/ |
|
431 |
EXPORT_C TUint32 NKern::FastCounter() |
|
432 |
{ |
|
433 |
return (TUint32)Timestamp(); |
|
434 |
} |
|
435 |
||
436 |
||
437 |
/** Get the frequency of counter queried by NKern::FastCounter(). |
|
438 |
*/ |
|
439 |
EXPORT_C TInt NKern::FastCounterFrequency() |
|
440 |
{ |
|
441 |
return (TInt)TimestampFrequency(); |
|
442 |
} |
|
443 |
||
444 |
||
445 |
extern "C" { |
|
446 |
TUint32 CrashState; |
|
447 |
} |
|
448 |
||
449 |
EXPORT_C TBool NKern::Crashed() |
|
450 |
{ |
|
451 |
return CrashState!=0; |
|
452 |
} |
|
453 |
||
454 |
||
455 |
/** Returns number of nanokernel timer ticks since system started. |
|
456 |
@return tick count |
|
457 |
@pre any context |
|
458 |
*/ |
|
459 |
EXPORT_C TUint32 NKern::TickCount() |
|
460 |
{ |
|
461 |
return NTickCount(); |
|
462 |
} |
|
463 |
||
464 |
||
465 |
TUint32 BTrace::BigTraceId = 0; |
|
466 |
||
467 |
TBool BTrace::DoOutBig(TUint32 a0, TUint32 a1, const TAny* aData, TInt aDataSize, TUint32 aContext, TUint32 aPc) |
|
468 |
{ |
|
469 |
SBTraceData& traceData = BTraceData; |
|
470 |
||
471 |
// see if trace is small enough to fit in single record... |
|
472 |
if(TUint(aDataSize)<=TUint(KMaxBTraceDataArray+4)) |
|
473 |
{ |
|
474 |
a0 += aDataSize; |
|
475 |
TUint32 a2 = 0; |
|
476 |
TUint32 a3 = 0; |
|
477 |
if(aDataSize) |
|
478 |
{ |
|
479 |
a2 = *((TUint32*&)aData)++; // first 4 bytes into a2 |
|
480 |
if(aDataSize>=4 && aDataSize<=8) |
|
481 |
a3 = *(TUint32*)aData; // only 4 more bytes, so pass by value, not pointer |
|
482 |
else |
|
483 |
a3 = (TUint32)aData; |
|
484 |
} |
|
485 |
__ACQUIRE_BTRACE_LOCK(); |
|
486 |
TBool r = traceData.iHandler(a0,0,aContext,a1,a2,a3,0,aPc); |
|
487 |
__RELEASE_BTRACE_LOCK(); |
|
488 |
return r; |
|
489 |
} |
|
490 |
||
491 |
// adjust for header2, extra, and size word... |
|
492 |
a0 |= BTrace::EHeader2Present<<(BTrace::EFlagsIndex*8)|BTrace::EExtraPresent<<(BTrace::EFlagsIndex*8); |
|
493 |
a0 += 12; |
|
494 |
||
495 |
TUint32 traceId = __e32_atomic_add_ord32(&BigTraceId, 1); |
|
496 |
TUint32 header2 = BTrace::EMultipartFirst; |
|
497 |
TInt offset = 0; |
|
498 |
do |
|
499 |
{ |
|
500 |
TUint32 size = aDataSize-offset; |
|
501 |
if(size>KMaxBTraceDataArray) |
|
502 |
size = KMaxBTraceDataArray; |
|
503 |
else |
|
504 |
header2 = BTrace::EMultipartLast; |
|
505 |
if(size<=4) |
|
506 |
*(TUint32*)&aData = *(TUint32*)aData; // 4 bytes or less are passed by value, not pointer |
|
507 |
||
508 |
__ACQUIRE_BTRACE_LOCK(); |
|
509 |
TBool result = traceData.iHandler(a0+size,header2,aContext,aDataSize,a1,(TUint32)aData,traceId,aPc); |
|
510 |
__RELEASE_BTRACE_LOCK(); |
|
511 |
if (!result) |
|
512 |
return result; |
|
513 |
||
514 |
offset += size; |
|
515 |
*(TUint8**)&aData += size; |
|
516 |
||
517 |
header2 = BTrace::EMultipartMiddle; |
|
518 |
a1 = offset; |
|
519 |
} |
|
520 |
while(offset<aDataSize); |
|
521 |
||
522 |
return TRUE; |
|
523 |
} |
|
524 |
||
525 |
EXPORT_C TSpinLock* BTrace::LockPtr() |
|
526 |
{ |
|
527 |
#ifdef __USE_BTRACE_LOCK__ |
|
528 |
return &BTraceLock; |
|
529 |
#else |
|
530 |
return 0; |
|
531 |
#endif |
|
532 |
} |
|
90
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
533 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
534 |
TDfcQue* TScheduler::RebalanceDfcQ() |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
535 |
{ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
536 |
return TheScheduler.iRebalanceDfcQ; |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
537 |
} |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
538 |
|
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
539 |
NThread* TScheduler::LBThread() |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
540 |
{ |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
541 |
return (NThread*)(TheScheduler.iRebalanceDfcQ->iThread); |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
542 |
} |
947f0dc9f7a8
Revision: 201015
Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
parents:
0
diff
changeset
|
543 |