0
|
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\include\nkern\nk_priv.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 __NK_PRIV_H__
|
|
22 |
#define __NK_PRIV_H__
|
|
23 |
#include <cpudefs.h>
|
|
24 |
#include <nkern.h>
|
|
25 |
|
|
26 |
/********************************************
|
|
27 |
* DFCs
|
|
28 |
********************************************/
|
|
29 |
|
|
30 |
/**
|
|
31 |
@internalComponent
|
|
32 |
*/
|
|
33 |
inline TBool TDfc::TestAndSetQueued()
|
|
34 |
{ return __e32_atomic_swp_ord8(&iSpare3, 1); }
|
|
35 |
|
|
36 |
/********************************************
|
|
37 |
* Thread
|
|
38 |
********************************************/
|
|
39 |
|
|
40 |
class TUserModeCallback;
|
|
41 |
|
|
42 |
/**
|
|
43 |
@publishedPartner
|
|
44 |
@released
|
|
45 |
|
|
46 |
Base class for a nanokernel thread.
|
|
47 |
*/
|
|
48 |
class NThreadBase : public TPriListLink
|
|
49 |
{
|
|
50 |
public:
|
|
51 |
/**
|
|
52 |
Defines the possible states of a nanokernel thread.
|
|
53 |
*/
|
|
54 |
enum NThreadState
|
|
55 |
{
|
|
56 |
/**
|
|
57 |
The thread is eligible for execution.
|
|
58 |
|
|
59 |
Threads in this state are linked into the ready list.
|
|
60 |
The highest priority READY thread is the one that will run, unless it
|
|
61 |
is blocked on a fast mutex.
|
|
62 |
*/
|
|
63 |
EReady,
|
|
64 |
|
|
65 |
/**
|
|
66 |
The thread is explicitly suspended (rather than blocking on
|
|
67 |
a wait object).
|
|
68 |
*/
|
|
69 |
ESuspended,
|
|
70 |
|
|
71 |
/**
|
|
72 |
The thread is blocked waiting for a fast semaphore to be signalled.
|
|
73 |
*/
|
|
74 |
EWaitFastSemaphore,
|
|
75 |
|
|
76 |
/**
|
|
77 |
The thread is blocked waiting for a specific time period to elapse.
|
|
78 |
*/
|
|
79 |
ESleep,
|
|
80 |
|
|
81 |
/**
|
|
82 |
The thread is blocked on a wait object implemented in a layer above
|
|
83 |
the nanokernel.
|
|
84 |
|
|
85 |
In practice, this means that it is blocked on a Symbian OS
|
|
86 |
semaphore or mutex.
|
|
87 |
*/
|
|
88 |
EBlocked,
|
|
89 |
|
|
90 |
/**
|
|
91 |
The thread has terminated and will not execute again.
|
|
92 |
*/
|
|
93 |
EDead,
|
|
94 |
|
|
95 |
/**
|
|
96 |
The thread is a DFC-handling thread and it is blocked waiting for
|
|
97 |
the DFC to be queued.
|
|
98 |
*/
|
|
99 |
EWaitDfc,
|
|
100 |
|
|
101 |
/**
|
|
102 |
Not a thread state, but defines the maximum number of states.
|
|
103 |
*/
|
|
104 |
ENumNStates
|
|
105 |
};
|
|
106 |
|
|
107 |
|
|
108 |
|
|
109 |
|
|
110 |
/**
|
|
111 |
Defines a set of values that, when passed to a nanokernel state handler,
|
|
112 |
indicates which operation is being performed on the thread.
|
|
113 |
|
|
114 |
Every thread that can use a new type of wait object, must have a nanokernel
|
|
115 |
state handler installed to handle operations on that thread while it is
|
|
116 |
waiting on that wait object.
|
|
117 |
|
|
118 |
A wait handler has the signature:
|
|
119 |
@code
|
|
120 |
void StateHandler(NThread* aThread, TInt aOp, TInt aParam);
|
|
121 |
@endcode
|
|
122 |
|
|
123 |
where aOp is one of these enum values.
|
|
124 |
|
|
125 |
The state handler is always called with preemption disabled.
|
|
126 |
*/
|
|
127 |
enum NThreadOperation
|
|
128 |
{
|
|
129 |
/**
|
|
130 |
Indicates that the thread is suspended while not in a critical section,
|
|
131 |
and not holding a fast mutex.
|
|
132 |
|
|
133 |
StateHandler() is called in whichever context
|
|
134 |
NThreadBase::Suspend() is called from.
|
|
135 |
|
|
136 |
Note that the third parameter passed to StateHandler() contains
|
|
137 |
the requested suspension count.
|
|
138 |
*/
|
|
139 |
ESuspend=0,
|
|
140 |
|
|
141 |
/**
|
|
142 |
Indicates that the thread is being resumed while suspended, and
|
|
143 |
the last suspension has been removed.
|
|
144 |
|
|
145 |
StateHandler() is called in whichever context
|
|
146 |
NThreadBase::Resume() is called from.
|
|
147 |
*/
|
|
148 |
EResume=1,
|
|
149 |
|
|
150 |
/**
|
|
151 |
Indicates that the thread has all suspensions cancelled while
|
|
152 |
actually suspended.
|
|
153 |
|
|
154 |
Statehandler() is called in whichever context
|
|
155 |
NThreadBase::ForceResume() is called from.
|
|
156 |
*/
|
|
157 |
EForceResume=2,
|
|
158 |
|
|
159 |
/**
|
|
160 |
Indicates that the thread is being released from its wait.
|
|
161 |
|
|
162 |
Statehandler() is called in whichever context
|
|
163 |
NThreadBase::Release() is called from.
|
|
164 |
*/
|
|
165 |
ERelease=3,
|
|
166 |
|
|
167 |
/**
|
|
168 |
Indicates that the thread's priority is being changed.
|
|
169 |
|
|
170 |
StateHandler() is called in whichever context
|
|
171 |
NThreadBase::SetPriority() is called from.
|
|
172 |
*/
|
|
173 |
EChangePriority=4,
|
|
174 |
|
|
175 |
/**
|
|
176 |
Indicates that the thread has called NKern::ThreadLeaveCS() with
|
|
177 |
an unknown NThreadBase::iCsFunction that is negative, but not equal
|
|
178 |
to NThreadBase::ECsExitPending.
|
|
179 |
|
|
180 |
Note that NThreadBase::iCsFunction is internal to Symbian OS.
|
|
181 |
*/
|
|
182 |
ELeaveCS=5,
|
|
183 |
|
|
184 |
/**
|
|
185 |
Indicates that the thread's wait timeout has expired, and no timeout
|
|
186 |
handler has been defined for that thread.
|
|
187 |
|
|
188 |
StateHandler() is called in the context of the nanokernel
|
|
189 |
timer thread, DfcThread1.
|
|
190 |
*/
|
|
191 |
ETimeout=6,
|
|
192 |
};
|
|
193 |
|
|
194 |
enum NThreadCSFunction
|
|
195 |
{
|
|
196 |
ECSExitPending=-1,
|
|
197 |
ECSExitInProgress=-2
|
|
198 |
};
|
|
199 |
|
|
200 |
enum NThreadTimeoutOp
|
|
201 |
{
|
|
202 |
ETimeoutPreamble=0,
|
|
203 |
ETimeoutPostamble=1,
|
|
204 |
ETimeoutSpurious=2,
|
|
205 |
};
|
|
206 |
public:
|
|
207 |
NThreadBase();
|
|
208 |
TInt Create(SNThreadCreateInfo& anInfo, TBool aInitial);
|
|
209 |
IMPORT_C void CheckSuspendThenReady();
|
|
210 |
IMPORT_C void Ready();
|
|
211 |
void DoReady();
|
|
212 |
void DoCsFunction();
|
|
213 |
IMPORT_C TBool Suspend(TInt aCount);
|
|
214 |
IMPORT_C TBool Resume();
|
|
215 |
IMPORT_C TBool ForceResume();
|
|
216 |
IMPORT_C void Release(TInt aReturnCode);
|
|
217 |
IMPORT_C void RequestSignal();
|
|
218 |
IMPORT_C void SetPriority(TInt aPriority);
|
|
219 |
void SetEntry(NThreadFunction aFunction);
|
|
220 |
IMPORT_C void Kill();
|
|
221 |
void Exit();
|
|
222 |
void ForceExit();
|
|
223 |
// hooks for platform-specific code
|
|
224 |
void OnKill();
|
|
225 |
void OnExit();
|
|
226 |
public:
|
|
227 |
static void TimerExpired(TAny* aPtr);
|
|
228 |
inline void UnknownState(TInt aOp, TInt aParam)
|
|
229 |
{ (*iHandlers->iStateHandler)((NThread*)this,aOp,aParam); }
|
|
230 |
|
|
231 |
/** @internalComponent */
|
|
232 |
inline TUint8 Attributes()
|
|
233 |
{ return iSpare2; }
|
|
234 |
|
|
235 |
/** @internalComponent */
|
|
236 |
inline TUint8 SetAttributes(TUint8 aNewAtt)
|
|
237 |
{ return __e32_atomic_swp_ord8(&iSpare2, aNewAtt); }
|
|
238 |
|
|
239 |
/** @internalComponent */
|
|
240 |
inline TUint8 ModifyAttributes(TUint8 aClearMask, TUint8 aSetMask)
|
|
241 |
{ return __e32_atomic_axo_ord8(&iSpare2, (TUint8)~(aClearMask|aSetMask), aSetMask); }
|
|
242 |
|
|
243 |
/** @internalComponent */
|
|
244 |
inline void SetAddressSpace(TAny* a)
|
|
245 |
{ iAddressSpace=a; }
|
|
246 |
|
|
247 |
inline void SetReturnValue(TInt aValue)
|
|
248 |
{ iReturnValue=aValue; }
|
|
249 |
inline void SetExtraContext(TAny* a, TInt aSize)
|
|
250 |
{ iExtraContext = a; iExtraContextSize = aSize; }
|
|
251 |
|
|
252 |
/** @internalComponent */
|
|
253 |
void CallUserModeCallbacks();
|
|
254 |
public:
|
|
255 |
// TUint8 iNState; // use iSpare1 for state
|
|
256 |
// TUint8 i_ThrdAttr; /**< @internalComponent */ // use iSpare2 for attributes
|
|
257 |
// TUint8 iUserContextType; // use iSpare3
|
|
258 |
NFastMutex* iHeldFastMutex; /**< @internalComponent */ // fast mutex held by this thread
|
|
259 |
NFastMutex* iWaitFastMutex; /**< @internalComponent */ // fast mutex on which this thread is blocked
|
|
260 |
TAny* iAddressSpace; /**< @internalComponent */
|
|
261 |
TInt iTime; // time remaining
|
|
262 |
TInt iTimeslice; // timeslice for this thread
|
|
263 |
NFastSemaphore iRequestSemaphore; /**< @internalComponent */
|
|
264 |
TAny* iWaitObj; // object on which this thread is waiting
|
|
265 |
TInt iSuspendCount; /**< @internalComponent */ // -how many times we have been suspended
|
|
266 |
TInt iCsCount; /**< @internalComponent */ // critical section count
|
|
267 |
TInt iCsFunction; /**< @internalComponent */ // what to do on leaving CS: +n=suspend n times, 0=nothing, -1=exit
|
|
268 |
NTimer iTimer; /**< @internalComponent */
|
|
269 |
TInt iReturnValue;
|
|
270 |
TLinAddr iStackBase; /**< @internalComponent */
|
|
271 |
TInt iStackSize; /**< @internalComponent */
|
|
272 |
const SNThreadHandlers* iHandlers; /**< @internalComponent */ // additional thread event handlers
|
|
273 |
const SFastExecTable* iFastExecTable; /**< @internalComponent */
|
|
274 |
const SSlowExecEntry* iSlowExecTable; /**< @internalComponent */ // points to first entry iEntries[0]
|
|
275 |
TLinAddr iSavedSP; /**< @internalComponent */
|
|
276 |
TAny* iExtraContext; /**< @internalComponent */ // parent FPSCR value (iExtraContextSize == -1), coprocessor context (iExtraContextSize > 0) or NULL
|
|
277 |
TInt iExtraContextSize; /**< @internalComponent */ // +ve=dynamically allocated, 0=none, -1=iExtraContext stores parent FPSCR value
|
|
278 |
TUint iLastStartTime; /**< @internalComponent */ // last start of execution timestamp
|
|
279 |
TUint64 iTotalCpuTime; /**< @internalComponent */ // total time spent running, in hi-res timer ticks
|
|
280 |
TUint32 iTag; /**< @internalComponent */ // User defined set of bits which is ANDed with a mask when the thread is scheduled, and indicates if a DFC should be scheduled.
|
|
281 |
TAny* iVemsData; /**< @internalComponent */ // This pointer can be used by any VEMS to store any data associated with the thread. This data must be clean up before the Thread Exit Monitor completes.
|
|
282 |
TUserModeCallback* volatile iUserModeCallbacks; /**< @internalComponent */ // Head of singly-linked list of callbacks
|
|
283 |
TUint32 iSpare7; /**< @internalComponent */ // spare to allow growth while preserving BC
|
|
284 |
TUint32 iSpare8; /**< @internalComponent */ // spare to allow growth while preserving BC
|
|
285 |
};
|
|
286 |
|
|
287 |
__ASSERT_COMPILE(!(_FOFF(NThreadBase,iTotalCpuTime)&7));
|
|
288 |
|
|
289 |
#ifdef __INCLUDE_NTHREADBASE_DEFINES__
|
|
290 |
#define iNState iSpare1
|
|
291 |
#define i_ThrdAttr iSpare2
|
|
292 |
#define iUserContextType iSpare3
|
|
293 |
#endif
|
|
294 |
|
|
295 |
#define i_NThread_BasePri iPriority
|
|
296 |
|
|
297 |
/********************************************
|
|
298 |
* Scheduler
|
|
299 |
********************************************/
|
|
300 |
|
|
301 |
/**
|
|
302 |
@internalComponent
|
|
303 |
*/
|
|
304 |
class TScheduler : public TPriListBase
|
|
305 |
{
|
|
306 |
public:
|
|
307 |
TScheduler();
|
|
308 |
void Remove(NThreadBase* aThread);
|
|
309 |
void RotateReadyList(TInt aPriority);
|
|
310 |
void QueueDfcs();
|
|
311 |
static void Reschedule();
|
|
312 |
static void YieldTo(NThreadBase* aThread);
|
|
313 |
void TimesliceTick();
|
|
314 |
IMPORT_C static TScheduler* Ptr();
|
|
315 |
inline void SetProcessHandler(TLinAddr aHandler) {iProcessHandler=aHandler;}
|
|
316 |
private:
|
|
317 |
SDblQueLink* iExtraQueues[KNumPriorities-1];
|
|
318 |
public:
|
|
319 |
TUint8 iRescheduleNeededFlag;
|
|
320 |
TUint8 iDfcPendingFlag;
|
|
321 |
TInt iKernCSLocked;
|
|
322 |
SDblQue iDfcs;
|
|
323 |
TLinAddr iMonitorExceptionHandler;
|
|
324 |
TLinAddr iProcessHandler;
|
|
325 |
TLinAddr iRescheduleHook;
|
|
326 |
TUint8 iInIDFC;
|
|
327 |
NFastMutex iLock;
|
|
328 |
NThreadBase* iCurrentThread;
|
|
329 |
TAny* iAddressSpace;
|
|
330 |
TAny* iExtras[16];
|
|
331 |
// For EMI support
|
|
332 |
NThread* iSigma;
|
|
333 |
TDfc* iEmiDfc;
|
|
334 |
TUint32 iEmiMask;
|
|
335 |
TUint32 iEmiState;
|
|
336 |
TUint32 iEmiDfcTrigger;
|
|
337 |
TBool iLogging;
|
|
338 |
TAny* iBufferStart;
|
|
339 |
TAny* iBufferEnd;
|
|
340 |
TAny* iBufferTail;
|
|
341 |
TAny* iBufferHead;
|
|
342 |
// For BTrace suport
|
|
343 |
TUint8 iCpuUsageFilter;
|
|
344 |
TUint8 iFastMutexFilter;
|
|
345 |
BTrace::THandler iBTraceHandler;
|
|
346 |
// Idle notification
|
|
347 |
SDblQue iIdleDfcs;
|
|
348 |
TUint32 iIdleGenerationCount;
|
|
349 |
// Delayed threads
|
|
350 |
SDblQue iDelayedQ;
|
|
351 |
TDfc iDelayDfc;
|
|
352 |
};
|
|
353 |
|
|
354 |
GLREF_D TScheduler TheScheduler;
|
|
355 |
|
|
356 |
/**
|
|
357 |
@internalComponent
|
|
358 |
*/
|
|
359 |
inline void RescheduleNeeded()
|
|
360 |
{TheScheduler.iRescheduleNeededFlag=TRUE;}
|
|
361 |
|
|
362 |
#include <nk_plat.h>
|
|
363 |
|
|
364 |
/**
|
|
365 |
@internalComponent
|
|
366 |
*/
|
|
367 |
inline NThread* NCurrentThread()
|
|
368 |
{ return (NThread*)TheScheduler.iCurrentThread; }
|
|
369 |
|
|
370 |
|
|
371 |
/**
|
|
372 |
@internalComponent
|
|
373 |
*/
|
|
374 |
#define __NK_ASSERT_UNLOCKED __NK_ASSERT_DEBUG(TheScheduler.iKernCSLocked==0)
|
|
375 |
|
|
376 |
/**
|
|
377 |
@internalComponent
|
|
378 |
*/
|
|
379 |
#define __NK_ASSERT_LOCKED __NK_ASSERT_DEBUG(TheScheduler.iKernCSLocked!=0)
|
|
380 |
|
|
381 |
#ifdef _DEBUG
|
|
382 |
/**
|
|
383 |
@publishedPartner
|
|
384 |
@released
|
|
385 |
*/
|
|
386 |
#define __ASSERT_NO_FAST_MUTEX { \
|
|
387 |
NThread* nt=NKern::CurrentThread(); \
|
|
388 |
__NK_ASSERT_DEBUG(!nt->iHeldFastMutex); \
|
|
389 |
}
|
|
390 |
|
|
391 |
/**
|
|
392 |
@publishedPartner
|
|
393 |
@released
|
|
394 |
*/
|
|
395 |
#define __ASSERT_FAST_MUTEX(m) { \
|
|
396 |
NThread* nt=NKern::CurrentThread(); \
|
|
397 |
__NK_ASSERT_DEBUG(nt->iHeldFastMutex==(m) && (m)->iHoldingThread==nt); \
|
|
398 |
}
|
|
399 |
|
|
400 |
/**
|
|
401 |
@publishedPartner
|
|
402 |
@released
|
|
403 |
*/
|
|
404 |
#define __ASSERT_SYSTEM_LOCK { \
|
|
405 |
NThread* nt=NKern::CurrentThread(); \
|
|
406 |
NFastMutex& m=TScheduler::Ptr()->iLock; \
|
|
407 |
__NK_ASSERT_DEBUG(nt->iHeldFastMutex==&m && m.iHoldingThread==nt); \
|
|
408 |
}
|
|
409 |
|
|
410 |
#define __ASSERT_NOT_ISR __NK_ASSERT_DEBUG(NKern::CurrentContext()!=NKern::EInterrupt)
|
|
411 |
|
|
412 |
#else
|
|
413 |
#define __ASSERT_NO_FAST_MUTEX
|
|
414 |
#define __ASSERT_FAST_MUTEX(m)
|
|
415 |
#define __ASSERT_SYSTEM_LOCK
|
|
416 |
#define __ASSERT_NOT_ISR
|
|
417 |
#endif
|
|
418 |
|
|
419 |
/********************************************
|
|
420 |
* System timer queue
|
|
421 |
********************************************/
|
|
422 |
|
|
423 |
/**
|
|
424 |
@publishedPartner
|
|
425 |
@released
|
|
426 |
*/
|
|
427 |
class NTimerQ
|
|
428 |
{
|
|
429 |
friend class NTimer;
|
|
430 |
public:
|
|
431 |
typedef void (*TDebugFn)(TAny* aPtr, TInt aPos); /**< @internalComponent */
|
|
432 |
enum { ETimerQMask=31, ENumTimerQueues=32 }; /**< @internalComponent */ // these are not easily modifiable
|
|
433 |
|
|
434 |
/** @internalComponent */
|
|
435 |
struct STimerQ
|
|
436 |
{
|
|
437 |
SDblQue iIntQ;
|
|
438 |
SDblQue iDfcQ;
|
|
439 |
};
|
|
440 |
public:
|
|
441 |
NTimerQ();
|
|
442 |
static void Init1(TInt aTickPeriod);
|
|
443 |
static void Init3(TDfcQue* aDfcQ);
|
|
444 |
IMPORT_C static TAny* TimerAddress();
|
|
445 |
IMPORT_C void Tick();
|
|
446 |
IMPORT_C static TInt IdleTime();
|
|
447 |
IMPORT_C static void Advance(TInt aTicks);
|
|
448 |
private:
|
|
449 |
static void DfcFn(TAny* aPtr);
|
|
450 |
void Dfc();
|
|
451 |
void Add(NTimer* aTimer);
|
|
452 |
void AddFinal(NTimer* aTimer);
|
|
453 |
public:
|
|
454 |
STimerQ iTickQ[ENumTimerQueues]; /**< @internalComponent */ // NOTE: the order of member data is important
|
|
455 |
TUint32 iPresent; /**< @internalComponent */ // The assembler code relies on it
|
|
456 |
TUint32 iMsCount; /**< @internalComponent */
|
|
457 |
SDblQue iHoldingQ; /**< @internalComponent */
|
|
458 |
SDblQue iOrderedQ; /**< @internalComponent */
|
|
459 |
SDblQue iCompletedQ; /**< @internalComponent */
|
|
460 |
TDfc iDfc; /**< @internalComponent */
|
|
461 |
TUint8 iTransferringCancelled; /**< @internalComponent */
|
|
462 |
TUint8 iCriticalCancelled; /**< @internalComponent */
|
|
463 |
TUint8 iPad1; /**< @internalComponent */
|
|
464 |
TUint8 iPad2; /**< @internalComponent */
|
|
465 |
TDebugFn iDebugFn; /**< @internalComponent */
|
|
466 |
TAny* iDebugPtr; /**< @internalComponent */
|
|
467 |
TInt iTickPeriod; /**< @internalComponent */ // in microseconds
|
|
468 |
/**
|
|
469 |
This member is intended for use by ASSP/variant interrupt code as a convenient
|
|
470 |
location to store rounding error information where hardware interrupts are not
|
|
471 |
exactly one millisecond. The Symbian kernel does not make any use of this member.
|
|
472 |
@publishedPartner
|
|
473 |
@released
|
|
474 |
*/
|
|
475 |
TInt iRounding;
|
|
476 |
};
|
|
477 |
|
|
478 |
GLREF_D NTimerQ TheTimerQ;
|
|
479 |
|
|
480 |
/**
|
|
481 |
@internalComponent
|
|
482 |
*/
|
|
483 |
inline TUint32 NTickCount()
|
|
484 |
{return TheTimerQ.iMsCount;}
|
|
485 |
|
|
486 |
/**
|
|
487 |
@internalComponent
|
|
488 |
*/
|
|
489 |
inline TInt NTickPeriod()
|
|
490 |
{return TheTimerQ.iTickPeriod;}
|
|
491 |
|
|
492 |
|
|
493 |
extern "C" {
|
|
494 |
/**
|
|
495 |
@internalComponent
|
|
496 |
*/
|
|
497 |
extern void NKCrashHandler(TInt aPhase, const TAny* a0, TInt a1);
|
|
498 |
|
|
499 |
/**
|
|
500 |
@internalComponent
|
|
501 |
*/
|
|
502 |
extern TUint32 CrashState;
|
|
503 |
}
|
|
504 |
|
|
505 |
|
|
506 |
#define __ACQUIRE_BTRACE_LOCK()
|
|
507 |
#define __RELEASE_BTRACE_LOCK()
|
|
508 |
|
|
509 |
/**
|
|
510 |
@internalComponent
|
|
511 |
*/
|
|
512 |
TBool InterruptsStatus(TBool aRequest);
|
|
513 |
|
|
514 |
|
|
515 |
//declarations for the checking of kernel precoditions
|
|
516 |
#ifdef _DEBUG
|
|
517 |
|
|
518 |
/**
|
|
519 |
@internalComponent
|
|
520 |
*/
|
|
521 |
#define MASK_NO_FAST_MUTEX 0x1
|
|
522 |
#define MASK_CRITICAL 0x2
|
|
523 |
#define MASK_NO_CRITICAL 0x4
|
|
524 |
#define MASK_KERNEL_LOCKED 0x8
|
|
525 |
#define MASK_KERNEL_UNLOCKED 0x10
|
|
526 |
#define MASK_KERNEL_LOCKED_ONCE 0x20
|
|
527 |
#define MASK_INTERRUPTS_ENABLED 0x40
|
|
528 |
#define MASK_INTERRUPTS_DISABLED 0x80
|
|
529 |
#define MASK_SYSTEM_LOCKED 0x100
|
|
530 |
#define MASK_NOT_ISR 0x400
|
|
531 |
#define MASK_NOT_IDFC 0x800
|
|
532 |
#define MASK_NOT_THREAD 0x1000
|
|
533 |
#define MASK_NO_CRITICAL_IF_USER 0x2000
|
|
534 |
#define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
|
|
535 |
#define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
|
|
536 |
#define MASK_ALWAYS_FAIL 0x4000
|
|
537 |
#define MASK_NO_RESCHED 0x8000
|
|
538 |
|
|
539 |
#if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
|
|
540 |
#define CHECK_PRECONDITIONS(mask,function)
|
|
541 |
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function)
|
|
542 |
|
|
543 |
#else
|
|
544 |
/**
|
|
545 |
@internalComponent
|
|
546 |
*/
|
|
547 |
extern "C" TInt CheckPreconditions(TUint32 aConditionMask, const char* aFunction, TLinAddr aAddr);
|
|
548 |
/**
|
|
549 |
@internalComponent
|
|
550 |
*/
|
|
551 |
#define CHECK_PRECONDITIONS(mask,function) CheckPreconditions(mask,function,0)
|
|
552 |
|
|
553 |
#ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
|
|
554 |
|
|
555 |
/**
|
|
556 |
@internalComponent
|
|
557 |
*/
|
|
558 |
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
|
|
559 |
__ASSERT_DEBUG( (cond), ( \
|
|
560 |
DEBUGPRINT("Assertion failed: %s\nFunction: %s\n",message,function),\
|
|
561 |
NKFault(function, 0)))
|
|
562 |
|
|
563 |
#else//!__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
|
|
564 |
/**
|
|
565 |
@internalComponent
|
|
566 |
*/
|
|
567 |
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
|
|
568 |
__ASSERT_DEBUG( (cond), \
|
|
569 |
DEBUGPRINT("Assertion failed: %s\nFunction: %s\n",message,function))
|
|
570 |
|
|
571 |
|
|
572 |
#endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
|
|
573 |
#endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
|
|
574 |
|
|
575 |
#else//if !DEBUG
|
|
576 |
|
|
577 |
#define CHECK_PRECONDITIONS(mask,function)
|
|
578 |
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function)
|
|
579 |
|
|
580 |
#endif//_DEBUG
|
|
581 |
|
|
582 |
#if (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
|
|
583 |
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function)
|
|
584 |
#else
|
|
585 |
#ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
|
|
586 |
/**
|
|
587 |
@internalComponent
|
|
588 |
*/
|
|
589 |
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
|
|
590 |
__ASSERT_ALWAYS( (cond), ( \
|
|
591 |
DEBUGPRINT("Assertion failed: %s\nFunction: %s\n",message,function),\
|
|
592 |
NKFault(function, 0)))
|
|
593 |
#else
|
|
594 |
/**
|
|
595 |
@internalComponent
|
|
596 |
*/
|
|
597 |
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
|
|
598 |
__ASSERT_ALWAYS( (cond), \
|
|
599 |
DEBUGPRINT("Assertion failed: %s\nFunction: %s\n",message,function))
|
|
600 |
#endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
|
|
601 |
#endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
|
|
602 |
|
|
603 |
#endif
|