Update contrib.
1 // Copyright (c) 2007-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\include\nkernsmp\nk_priv.h
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.
26 #define __USE_BTRACE_LOCK__
30 /********************************************
31 * Schedulable = thread or thread group
32 ********************************************/
38 Base class for a nanokernel thread or group
41 class NSchedulable : public TPriListLink
61 EEventCountMask=0xffff0000u,
62 EEventCountInc=0x10000u,
66 EThreadCpuMask=0x1f00u,
67 EDeferredReady=0x4000u,
76 void ReadyT(TUint aMode); // make ready, assumes lock held
77 TInt BeginTiedEvent();
79 TInt AddTiedEvent(NEventHandler* aEvent);
80 TBool TiedEventReadyInterlock(TInt aCpu);
81 void UnPauseT(); // decrement pause count and make ready if necessary
82 static void DeferredReadyIDfcFn(TAny*);
83 void DetachTiedEvents();
85 inline TBool IsGroup() {return !iParent;}
86 inline TBool IsLoneThread() {return iParent==this;}
87 inline TBool IsGroupThread() {return iParent && iParent!=this;}
89 // TUint8 iReady; /**< @internalComponent */ // flag indicating thread on ready list = cpu number | EReadyOffset
90 // TUint8 iCurrent; /**< @internalComponent */ // flag indicating thread is running
91 // TUint8 iLastCpu; /**< @internalComponent */ // CPU on which this thread last ran
92 TUint8 iPauseCount; /**< @internalComponent */ // count of externally requested pauses extending a voluntary wait
93 TUint8 iSuspended; /**< @internalComponent */ // flag indicating active external suspend (Not used for groups)
94 TUint8 iNSchedulableSpare1; /**< @internalComponent */
95 TUint8 iNSchedulableSpare2; /**< @internalComponent */
97 TUint8 iCpuChange; /**< @internalComponent */ // flag showing CPU migration outstanding
98 TUint8 iStopping; /**< @internalComponent */ // thread is exiting, thread group is being destroyed
99 TUint16 iFreezeCpu; /**< @internalComponent */ // flag set if CPU frozen - count for groups
100 NSchedulable* iParent; /**< @internalComponent */ // Pointer to group containing thread, =this for normal thread, =0 for group
102 TUint32 iCpuAffinity; /**< @internalComponent */
103 volatile TUint32 iEventState; /**< @internalComponent */ // bits 16-31=count, 0-4=event CPU, 5-9=thread CPU, 10=defer, 11=parent
105 TSpinLock iSSpinLock; /**< @internalComponent */
107 SDblQue iEvents; /**< @internalComponent */ // doubly-linked list of tied events
109 TUint32 i_IDfcMem[sizeof(TDfc)/sizeof(TUint32)]; /**< @internalComponent */ // IDFC used to make thread ready after last tied event completes
110 // TDfc iDeferredReadyIDfc; /**< @internalComponent */ // IDFC used to make thread ready after last tied event completes
115 TUint32 iRunCount32[2];
119 TUint64 iTotalCpuTime64; /**< @internalComponent */ // total time spent running, in hi-res timer ticks
120 TUint32 iTotalCpuTime32[2]; /**< @internalComponent */ // total time spent running, in hi-res timer ticks
124 __ASSERT_COMPILE(!(_FOFF(NSchedulable,iSSpinLock)&7));
125 __ASSERT_COMPILE(!(_FOFF(NSchedulable,iRunCount64)&7));
126 __ASSERT_COMPILE(!(_FOFF(NSchedulable,iTotalCpuTime64)&7));
127 __ASSERT_COMPILE(!(sizeof(NSchedulable)&7));
133 inline TBool TDfc::IsValid()
135 if (iHType < KNumDfcPriorities)
137 if (iHType != EEventHandlerIDFC)
139 return !iTied || !iTied->iStopping;
142 /********************************************
144 ********************************************/
149 class NThreadWaitState
154 EWtStWaitPending =0x01u, // thread is about to wait
155 EWtStWaitActive =0x02u, // thread is actually blocked
156 EWtStTimeout =0x04u, // timeout is active on this wait
157 EWtStObstructed =0x08u, // wait is due to obstruction (e.g. mutex) rather than lack of work to do
158 EWtStDead =0x80u, // thread is dead
162 void SetUpWait(TUint aType, TUint aFlags, TAny* aWaitObj);
163 void SetUpWait(TUint aType, TUint aFlags, TAny* aWaitObj, TUint32 aTimeout);
164 void SetDead(TDfc* aKillDfc);
167 static void TimerExpired(TAny*);
168 TInt UnBlockT(TUint aType, TAny* aWaitObj, TInt aReturnValue);
169 TUint32 ReleaseT(TAny*& aWaitObj, TInt aReturnValue);
172 inline NThreadBase* Thread();
173 inline TBool WaitPending()
174 { return iWtC.iWtStFlags & (EWtStWaitPending|EWtStDead); }
175 inline TBool ThreadIsBlocked()
176 { return iWtC.iWtStFlags & (EWtStWaitActive|EWtStDead); }
177 inline TBool ThreadIsDead()
178 { return iWtC.iWtStFlags & EWtStDead; }
182 volatile TUint8 iWtStFlags;
183 volatile TUint8 iWtObjType;
184 volatile TUint8 iWtStSpare1;
185 volatile TUint8 iWtStSpare2;
188 TAny* volatile iWtObj;
189 volatile TInt iRetVal;
190 TDfc* volatile iKillDfc;
196 volatile TUint32 iWtSt32[2];
197 volatile TUint64 iWtSt64;
201 friend class NSchedulable;
202 friend class NThreadBase;
203 friend class NThread;
204 friend class TScheduler;
205 friend class TSubScheduler;
207 friend class TDfcQue;
208 friend class NFastSemaphore;
209 friend class NFastMutex;
211 friend class NTimerQ;
213 friend class Monitor;
221 Base class for a nanokernel thread.
224 class NThreadBase : public NSchedulable
228 Defines the possible types of wait object
246 enum NThreadCSFunction
249 ECSExitInProgress=-2,
256 enum NThreadTimeoutOp
264 TInt Create(SNThreadCreateInfo& anInfo, TBool aInitial);
266 TBool SuspendOrKill(TInt aCount);
267 TBool DoSuspendOrKillT(TInt aCount, TSubScheduler* aS);
268 TBool CancelTimerT();
269 void DoReleaseT(TInt aReturnCode, TUint aMode);
270 TBool CheckFastMutexDefer();
271 void DoCsFunctionT();
272 TBool Resume(TBool aForce);
273 IMPORT_C TBool Suspend(TInt aCount); /**< @internalComponent */
274 IMPORT_C TBool Resume(); /**< @internalComponent */
275 IMPORT_C TBool ForceResume(); /**< @internalComponent */
276 IMPORT_C void Release(TInt aReturnCode, TUint aMode); /**< @internalComponent */
277 IMPORT_C void RequestSignal(); /**< @internalComponent */
278 IMPORT_C void SetPriority(TInt aPriority); /**< @internalComponent */
279 void SetMutexPriority(NFastMutex* aMutex);
280 void LoseInheritedPriorityT();
281 void ChangeReadyThreadPriority();
282 TUint32 SetCpuAffinity(TUint32 aAffinity);
283 TBool TiedEventLeaveInterlock();
284 TBool TiedEventJoinInterlock();
285 IMPORT_C void Kill(); /**< @internalComponent */
287 // hooks for platform-specific code
291 static void TimerExpired(TAny* aPtr);
293 /** @internalComponent */
294 inline void UnknownState(TInt aOp, TInt aParam)
295 { (*iHandlers->iStateHandler)((NThread*)this,aOp,aParam); }
297 /** @internalComponent */
298 inline TUint8 Attributes()
299 { return i_ThrdAttr; }
301 /** @internalComponent */
302 inline TUint8 SetAttributes(TUint8 aNewAtt)
303 { return __e32_atomic_swp_ord8(&i_ThrdAttr, aNewAtt); }
305 /** @internalComponent */
306 inline TUint8 ModifyAttributes(TUint8 aClearMask, TUint8 aSetMask)
307 { return __e32_atomic_axo_ord8(&i_ThrdAttr, (TUint8)~(aClearMask|aSetMask), aSetMask); }
309 /** @internalComponent */
310 inline void SetAddressSpace(TAny* a)
313 /** @internalComponent */
314 inline void SetExtraContext(TAny* a, TInt aSize)
315 { iExtraContext = a; iExtraContextSize = aSize; }
317 /** @internalTechnology */
318 inline TBool IsDead()
319 { return iWaitState.ThreadIsDead(); }
321 TPriListLink iWaitLink; /**< @internalComponent */ // used to link thread into a wait queue
322 // TUint8 iBasePri; /**< @internalComponent */ // priority with no fast mutex held
323 // TUint8 iMutexPri; /**< @internalComponent */ // priority from held fast mutex
324 // TUint8 iInitial; /**< @internalComponent */ // TRUE if this is an initial thread
325 TUint8 iLinkedObjType;
326 TUint8 i_ThrdAttr; /**< @internalComponent */
327 TUint8 iNThreadBaseSpare10;
328 TUint8 iFastMutexDefer; /**< @internalComponent */
330 NFastSemaphore iRequestSemaphore; /**< @internalComponent */
332 TInt iTime; /**< @internalComponent */ // time remaining, 0 if expired
333 TInt iTimeslice; /**< @internalComponent */ // timeslice for this thread, -ve = no timeslicing
335 TLinAddr iSavedSP; /**< @internalComponent */
336 TAny* iAddressSpace; /**< @internalComponent */
338 NFastMutex* volatile iHeldFastMutex; /**< @internalComponent */ // fast mutex held by this thread
339 TUserModeCallback* volatile iUserModeCallbacks; /**< @internalComponent */ // Head of singly-linked list of callbacks
340 TAny* volatile iLinkedObj; /**< @internalComponent */ // object to which this thread is linked
341 NThreadGroup* iNewParent; /**< @internalComponent */ // group to join
343 const SFastExecTable* iFastExecTable; /**< @internalComponent */
344 const SSlowExecEntry* iSlowExecTable; /**< @internalComponent */ // points to first entry iEntries[0]
346 volatile TInt iCsCount; /**< @internalComponent */ // critical section count
347 volatile TInt iCsFunction; /**< @internalComponent */ // what to do on leaving CS: +n=suspend n times, 0=nothing, -1=exit
349 NThreadWaitState iWaitState; /**< @internalComponent */
351 const SNThreadHandlers* iHandlers; /**< @internalComponent */ // additional thread event handlers
352 TInt iSuspendCount; /**< @internalComponent */ // -how many times we have been suspended
354 TLinAddr iStackBase; /**< @internalComponent */
355 TInt iStackSize; /**< @internalComponent */
357 TAny* iExtraContext; /**< @internalComponent */ // parent FPSCR value (iExtraContextSize == -1), coprocessor context (iExtraContextSize > 0) or NULL
358 TInt iExtraContextSize; /**< @internalComponent */ // +ve=dynamically allocated, 0=none, -1=iExtraContext stores parent FPSCR value
360 TUint32 iNThreadBaseSpare6; /**< @internalComponent */ // spare to allow growth while preserving BC
361 TUint32 iNThreadBaseSpare7; /**< @internalComponent */ // spare to allow growth while preserving BC
362 TUint32 iNThreadBaseSpare8; /**< @internalComponent */ // spare to allow growth while preserving BC
363 TUint32 iNThreadBaseSpare9; /**< @internalComponent */ // spare to allow growth while preserving BC
365 // For EMI support - HOPEFULLY THIS CAN DIE
366 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.
367 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.
370 __ASSERT_COMPILE(!(_FOFF(NThreadBase,iWaitLink)&7));
371 __ASSERT_COMPILE(!(sizeof(NThreadBase)&7));
373 #ifdef __INCLUDE_NTHREADBASE_DEFINES__
374 #define iReady iSpare1 /**< @internalComponent */
375 #define iCurrent iSpare2 /**< @internalComponent */
376 #define iLastCpu iSpare3 /**< @internalComponent */
378 #define iBasePri iWaitLink.iSpare1 /**< @internalComponent */
379 #define iMutexPri iWaitLink.iSpare2 /**< @internalComponent */
380 #define i_NThread_Initial iWaitLink.iSpare3 /**< @internalComponent */
384 /** @internalComponent */
385 #define i_NThread_BasePri iWaitLink.iSpare1
387 /** @internalComponent */
388 #define NTHREADBASE_CPU_AFFINITY_MASK 0x80000000
390 /** @internalComponent */
391 inline NThreadBase* NThreadWaitState::Thread()
392 { return _LOFF(this, NThreadBase, iWaitState); }
394 /********************************************
396 ********************************************/
402 Base class for a nanokernel thread or group
404 class NThreadGroup : public NSchedulable
409 TInt iThreadCount; /**< @internalComponent */
410 TPriList<NThreadBase, KNumPriorities> iNThreadList; /**< @internalComponent */
413 /********************************************
415 ********************************************/
423 class TSubScheduler : public TPriListBase
428 void RotateReadyList(TInt aPriority);
429 NThread* SelectNextThread();
430 TBool QueueEvent(NEventHandler* aEvent);
431 void QueueEventAndKick(NEventHandler* aEvent);
432 void SaveTimesliceTimer(NThreadBase* aThread);
433 void UpdateThreadTimes(NThreadBase* aOld, NThreadBase* aNew);
435 SDblQueLink* iExtraQueues[KNumPriorities-1];
437 TSpinLock iExIDfcLock; // lock to protect exogenous IDFC queue
439 SDblQue iExIDfcs; // list of pending exogenous IDFCs (i.e. ones punted over from another CPU)
441 SDblQue iDfcs; // normal IDFC/DFC pending queue (only accessed by this CPU)
443 TDfc* volatile iCurrentIDFC; // pointer to IDFC currently running on this CPU
444 NThread* iCurrentThread; // the thread currently running on this CPU
449 TSpinLock iReadyListLock;
451 volatile TUint8 iRescheduleNeededFlag; // TRUE if a thread reschedule is pending
452 TUint8 iSubSchedulerSBZ1; // always zero
453 volatile TUint8 iDfcPendingFlag; // TRUE if a normal IDFC is pending
454 volatile TUint8 iExIDfcPendingFlag; // TRUE if an exogenous IDFC is pending
455 TInt iKernLockCount; // how many times the current CPU has locked the kernel
457 TUint8 iInIDFC; // TRUE if IDFCs are currently being run on this CPU
458 volatile TUint8 iEventHandlersPending; // TRUE if an event handler is pending on this CPU
459 TUint8 iSubSchedulerSpare4;
460 TUint8 iSubSchedulerSpare5;
463 TUint32 iReschedIPIs;
464 TScheduler* iScheduler;
468 TUint64 iLastTimestamp64; // NKern::Timestamp() value at last reschedule or timestamp sync
469 TUint32 iLastTimestamp32[2];
473 TUint64 iReschedCount64;
474 TUint32 iReschedCount32[2];
477 TAny* iExtras[24]; // Space for platform-specific extras
479 TGenericIPI* iNextIPI; // next generic IPI to run on this CPU
480 NThread* iInitialThread; // Initial (idle) thread on this CPU
482 TSpinLock iEventHandlerLock; // lock to protect event handler queue
484 SDblQue iEventHandlers; // queue of pending event handlers on this CPU
486 TUint64 iSpinLockOrderCheck; // bitmask showing which spinlock orders currently held
488 TUint32 iSubSchedulerPadding[8];
491 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iExIDfcLock)&7));
492 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iEventHandlerLock)&7));
493 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReadyListLock)&7));
494 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iLastTimestamp64)&7));
495 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReschedCount64)&7));
496 __ASSERT_COMPILE(sizeof(TSubScheduler)==512); // make it a nice power of 2 size for easy indexing
505 static void Reschedule();
506 IMPORT_C static TScheduler* Ptr();
507 inline void SetProcessHandler(TLinAddr aHandler) {iProcessHandler=aHandler;}
509 TLinAddr iMonitorExceptionHandler;
510 TLinAddr iProcessHandler;
512 TLinAddr iRescheduleHook;
513 TUint32 iActiveCpus1; // bit n set if CPU n is accepting unlocked threads
515 TUint32 iActiveCpus2; // bit n set if CPU n is accepting generic IPIs
516 TInt iNumCpus; // number of CPUs under the kernel's control
518 TSubScheduler* iSub[KMaxCpus]; // one subscheduler per CPU
520 TAny* iExtras[24]; // Space for platform-specific extras
522 NFastMutex iLock; // the 'system lock' fast mutex
524 TSpinLock iIdleSpinLock; // lock to protect list of DFCs to be run on idle
526 SDblQue iIdleDfcs; // list of DFCs to run when all CPUs go idle
528 TUint32 iCpusNotIdle; // bitmask - Bit n set => CPU n is not idle
529 TUint8 iIdleGeneration; // Toggles between 0 and 1 each time iIdleDfcs list is spilled to a CPU IDFC queue
530 TUint8 iIdleSpillCpu; // Which CPU last spilled the iIdleDfcs list to its IDFC queue
531 TUint8 iTSchedulerSpare1;
532 TUint8 iTSchedulerSpare2;
534 TUint32 iIdleGenerationCount; // Incremented each time iIdleDfcs list is spilled to a CPU IDFC queue
535 TUint32 i_Scheduler_Padding[3];
537 // For EMI support - HOPEFULLY THIS CAN DIE
542 TUint32 iEmiDfcTrigger;
550 __ASSERT_COMPILE(!(_FOFF(TScheduler,iIdleSpinLock)&7));
551 __ASSERT_COMPILE(sizeof(TScheduler)==512);
553 extern TScheduler TheScheduler;
554 extern TSubScheduler TheSubSchedulers[KMaxCpus];
556 #ifdef __USE_BTRACE_LOCK__
557 extern TSpinLock BTraceLock;
559 #define __ACQUIRE_BTRACE_LOCK() TInt _btrace_irq = BTraceLock.LockIrqSave()
560 #define __RELEASE_BTRACE_LOCK() BTraceLock.UnlockIrqRestore(_btrace_irq)
564 #define __ACQUIRE_BTRACE_LOCK()
565 #define __RELEASE_BTRACE_LOCK()
572 extern "C" TSubScheduler& SubScheduler();
577 extern "C" void send_resched_ipis(TUint32 aMask);
582 extern "C" void send_resched_ipi(TInt aCpu);
587 extern "C" void send_resched_ipi_and_wait(TInt aCpu);
593 Call with kernel locked
597 inline void RescheduleNeeded()
598 { SubScheduler().iRescheduleNeededFlag = 1; }
604 #define NCurrentThread() NKern::CurrentThread()
606 /** Optimised current thread function which can only be called from places where
607 CPU migration is not possible - i.e. with interrupts disabled or preemption
612 extern "C" NThread* NCurrentThreadL();
614 /** @internalComponent */
615 inline TBool CheckCpuAgainstAffinity(TInt aCpu, TUint32 aAffinity)
617 if (aAffinity & NTHREADBASE_CPU_AFFINITY_MASK)
618 return aAffinity & (1<<aCpu);
619 return aAffinity==(TUint32)aCpu;
625 #define __NK_ASSERT_UNLOCKED __NK_ASSERT_DEBUG(!NKern::KernelLocked())
630 #define __NK_ASSERT_LOCKED __NK_ASSERT_DEBUG(NKern::KernelLocked())
637 #define __ASSERT_NO_FAST_MUTEX __NK_ASSERT_DEBUG(!NKern::HeldFastMutex());
643 #define __ASSERT_FAST_MUTEX(m) __NK_ASSERT_DEBUG((m)->HeldByCurrentThread());
649 #define __ASSERT_SYSTEM_LOCK __NK_ASSERT_DEBUG(TScheduler::Ptr()->iLock.HeldByCurrentThread());
651 #define __ASSERT_NOT_ISR __NK_ASSERT_DEBUG(NKern::CurrentContext()!=NKern::EInterrupt)
654 #define __ASSERT_NO_FAST_MUTEX
655 #define __ASSERT_FAST_MUTEX(m)
656 #define __ASSERT_SYSTEM_LOCK
657 #define __ASSERT_NOT_ISR
660 /********************************************
662 ********************************************/
672 typedef void (*TDebugFn)(TAny* aPtr, TInt aPos); /**< @internalComponent */
673 enum { ETimerQMask=31, ENumTimerQueues=32 }; /**< @internalComponent */ // these are not easily modifiable
675 /** @internalComponent */
683 static void Init1(TInt aTickPeriod);
684 static void Init3(TDfcQue* aDfcQ);
685 IMPORT_C static TAny* TimerAddress();
686 IMPORT_C void Tick();
687 IMPORT_C static TInt IdleTime();
688 IMPORT_C static void Advance(TInt aTicks);
690 static void DfcFn(TAny* aPtr);
692 void Add(NTimer* aTimer);
693 void AddFinal(NTimer* aTimer);
695 STimerQ iTickQ[ENumTimerQueues]; /**< @internalComponent */ // NOTE: the order of member data is important
696 TUint32 iPresent; /**< @internalComponent */ // The assembler code relies on it
697 TUint32 iMsCount; /**< @internalComponent */
698 SDblQue iHoldingQ; /**< @internalComponent */
699 SDblQue iOrderedQ; /**< @internalComponent */
700 SDblQue iCompletedQ; /**< @internalComponent */
701 TDfc iDfc; /**< @internalComponent */
702 TUint8 iTransferringCancelled; /**< @internalComponent */
703 TUint8 iCriticalCancelled; /**< @internalComponent */
704 TUint8 iPad1; /**< @internalComponent */
705 TUint8 iPad2; /**< @internalComponent */
706 TDebugFn iDebugFn; /**< @internalComponent */
707 TAny* iDebugPtr; /**< @internalComponent */
708 TInt iTickPeriod; /**< @internalComponent */ // in microseconds
711 This member is intended for use by ASSP/variant interrupt code as a convenient
712 location to store rounding error information where hardware interrupts are not
713 exactly one millisecond. The Symbian kernel does not make any use of this member.
718 TInt iDfcCompleteCount; /**< @internalComponent */
719 TSpinLock iTimerSpinLock; /**< @internalComponent */
722 __ASSERT_COMPILE(!(_FOFF(NTimerQ,iTimerSpinLock)&7));
725 GLREF_D NTimerQ TheTimerQ;
730 inline TUint32 NTickCount()
731 {return TheTimerQ.iMsCount;}
736 inline TInt NTickPeriod()
737 {return TheTimerQ.iTickPeriod;}
744 extern void NKCrashHandler(TInt aPhase, const TAny* a0, TInt a1);
749 extern TUint32 CrashState;
756 class TGenIPIList : public SDblQue
761 TSpinLock iGenIPILock;
767 class TCancelIPI : public TGenericIPI
770 void Send(TDfc* aDfc, TInt aCpu);
771 static void Isr(TGenericIPI*);
780 TBool InterruptsStatus(TBool aRequest);
783 //declarations for the checking of kernel preconditions
788 PRECOND_FUNCTION_CALLER is needed for __ASSERT_WITH_MESSAGE_ALWAYS(),
789 so is outside the #ifdef _DEBUG.
791 #ifndef PRECOND_FUNCTION_CALLER
792 #define PRECOND_FUNCTION_CALLER 0
800 #define MASK_NO_FAST_MUTEX 0x1
801 #define MASK_CRITICAL 0x2
802 #define MASK_NO_CRITICAL 0x4
803 #define MASK_KERNEL_LOCKED 0x8
804 #define MASK_KERNEL_UNLOCKED 0x10
805 #define MASK_KERNEL_LOCKED_ONCE 0x20
806 #define MASK_INTERRUPTS_ENABLED 0x40
807 #define MASK_INTERRUPTS_DISABLED 0x80
808 #define MASK_SYSTEM_LOCKED 0x100
809 #define MASK_NOT_ISR 0x400
810 #define MASK_NOT_IDFC 0x800
811 #define MASK_NOT_THREAD 0x1000
812 #define MASK_NO_CRITICAL_IF_USER 0x2000
813 #define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
814 #define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
815 #define MASK_ALWAYS_FAIL 0x4000
816 #define MASK_NO_RESCHED 0x8000
818 #if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
819 #define CHECK_PRECONDITIONS(mask,function)
820 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function)
826 extern "C" TInt CheckPreconditions(TUint32 aConditionMask, const char* aFunction, TLinAddr aAddr);
830 #define CHECK_PRECONDITIONS(mask,function) CheckPreconditions(mask,function,PRECOND_FUNCTION_CALLER)
832 #ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
837 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
838 __ASSERT_DEBUG( (cond), ( \
839 DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
840 NKFault(function, 0)))
842 #else//!__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
846 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
847 __ASSERT_DEBUG( (cond), \
848 DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
851 #endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
852 #endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
856 #define CHECK_PRECONDITIONS(mask,function)
857 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function )
861 #if (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
862 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function )
864 #ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
868 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
869 __ASSERT_ALWAYS( (cond), ( \
870 DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
871 NKFault(function, 0)))
876 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
877 __ASSERT_ALWAYS( (cond), \
878 DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
879 #endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
880 #endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))