os/kernelhwsrv/kernel/eka/include/nkern/nk_priv.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 //declarations for the checking of kernel preconditions
   515 
   516 /**
   517 @internalComponent
   518 
   519 PRECOND_FUNCTION_CALLER is needed for __ASSERT_WITH_MESSAGE_ALWAYS(),
   520 so is outside the #ifdef _DEBUG.
   521 */
   522 #ifndef PRECOND_FUNCTION_CALLER
   523 #define PRECOND_FUNCTION_CALLER		0
   524 #endif
   525 
   526 #ifdef _DEBUG
   527 
   528 /**
   529 @internalComponent
   530 */
   531 #define MASK_NO_FAST_MUTEX 0x1
   532 #define MASK_CRITICAL 0x2
   533 #define MASK_NO_CRITICAL 0x4
   534 #define MASK_KERNEL_LOCKED 0x8
   535 #define MASK_KERNEL_UNLOCKED 0x10
   536 #define MASK_KERNEL_LOCKED_ONCE 0x20
   537 #define MASK_INTERRUPTS_ENABLED 0x40
   538 #define MASK_INTERRUPTS_DISABLED 0x80
   539 #define MASK_SYSTEM_LOCKED 0x100
   540 #define MASK_NOT_ISR 0x400
   541 #define MASK_NOT_IDFC 0x800 
   542 #define MASK_NOT_THREAD 0x1000
   543 #define MASK_NO_CRITICAL_IF_USER 0x2000
   544 #define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
   545 #define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
   546 #define MASK_ALWAYS_FAIL 0x4000
   547 #define	MASK_NO_RESCHED 0x8000
   548 
   549 #if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
   550 #define CHECK_PRECONDITIONS(mask,function)
   551 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) 
   552 
   553 #else
   554 /**
   555 @internalComponent
   556 */
   557 extern "C" TInt CheckPreconditions(TUint32 aConditionMask, const char* aFunction, TLinAddr aAddr);
   558 /**
   559 @internalComponent
   560 */
   561 #define CHECK_PRECONDITIONS(mask,function) CheckPreconditions(mask,function,PRECOND_FUNCTION_CALLER)
   562 
   563 #ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
   564 
   565 /**
   566 @internalComponent
   567 */
   568 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
   569 			__ASSERT_DEBUG( (cond), ( \
   570 			DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
   571 			NKFault(function, 0)))
   572 
   573 #else//!__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
   574 /**
   575 @internalComponent
   576 */
   577 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
   578 			__ASSERT_DEBUG( (cond), \
   579 			DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
   580 
   581 
   582 #endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
   583 #endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
   584 
   585 #else//if !DEBUG
   586 
   587 #define CHECK_PRECONDITIONS(mask,function)
   588 #define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function)
   589 
   590 #endif//_DEBUG
   591 
   592 #if (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
   593 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function)
   594 #else
   595 #ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
   596 /**
   597 @internalComponent
   598 */
   599 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
   600 			__ASSERT_ALWAYS( (cond), ( \
   601 			DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
   602 			NKFault(function, 0)))
   603 #else
   604 /**
   605 @internalComponent
   606 */
   607 #define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
   608 			__ASSERT_ALWAYS( (cond), \
   609 			DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
   610 #endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
   611 #endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
   612 
   613 #endif