kernel/eka/include/nkern/nkern.h
changeset 0 a41df078684a
child 90 947f0dc9f7a8
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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\nkern.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 __NKERN_H__
       
    22 #define __NKERN_H__
       
    23 
       
    24 #ifdef	__STANDALONE_NANOKERNEL__
       
    25 #undef	__IN_KERNEL__
       
    26 #define	__IN_KERNEL__
       
    27 #endif
       
    28 
       
    29 #include <e32const.h>
       
    30 #include <nklib.h>
       
    31 #include <dfcs.h>
       
    32 #include <nk_trace.h>
       
    33 #include <e32atomics.h>
       
    34 
       
    35 extern "C" {
       
    36 /** @internalComponent */
       
    37 IMPORT_C void NKFault(const char* file, TInt line);
       
    38 /** @internalComponent */
       
    39 void NKIdle(TInt aStage);
       
    40 }
       
    41 
       
    42 /**
       
    43 @publishedPartner
       
    44 @released
       
    45 */
       
    46 #define FAULT()		NKFault(__FILE__,__LINE__)
       
    47 
       
    48 #ifdef _DEBUG
       
    49 
       
    50 /**
       
    51 @publishedPartner
       
    52 @released
       
    53 */
       
    54 #define __NK_ASSERT_DEBUG(c)	((void) ((c)||(FAULT(),0)) )
       
    55 
       
    56 #else
       
    57 
       
    58 #define __NK_ASSERT_DEBUG(c)
       
    59 
       
    60 #endif
       
    61 
       
    62 /**
       
    63 @publishedPartner
       
    64 @released
       
    65 */
       
    66 #define __NK_ASSERT_ALWAYS(c)	((void) ((c)||(FAULT(),0)) )
       
    67 
       
    68 /**
       
    69 	@publishedPartner
       
    70 	@released
       
    71 */
       
    72 const TInt KNumPriorities=64;
       
    73 
       
    74 const TInt KMaxCpus=8;
       
    75 
       
    76 class NThread;
       
    77 
       
    78 
       
    79 /** Spin lock
       
    80 
       
    81 	Used for protecting a code fragment against both interrupts and concurrent
       
    82 	execution on another processor.
       
    83 	
       
    84 	@internalComponent
       
    85 */
       
    86 class TSpinLock
       
    87 	{
       
    88 public:
       
    89 	enum TOrder
       
    90 		{
       
    91 		// Bit 7 of order clear for locks used with interrupts disabled
       
    92 		EOrderGenericIrqLow0	=0x00u,	// Device driver spin locks, low range
       
    93 		EOrderGenericIrqLow1	=0x01u,	// Device driver spin locks, low range
       
    94 		EOrderGenericIrqLow2	=0x02u,	// Device driver spin locks, low range
       
    95 		EOrderGenericIrqLow3	=0x03u,	// Device driver spin locks, low range
       
    96 		EOrderGenericIrqHigh0	=0x18u,	// Device driver spin locks, high range
       
    97 		EOrderGenericIrqHigh1	=0x19u,	// Device driver spin locks, high range
       
    98 		EOrderGenericIrqHigh2	=0x1Au,	// Device driver spin locks, high range
       
    99 		EOrderGenericIrqHigh3	=0x1Bu,	// Device driver spin locks, high range
       
   100 
       
   101 		// Bit 7 of order set for locks used with interrupts enabled, preemption disabled
       
   102 		EOrderGenericPreLow0	=0x80u,		// Device driver spin locks, low range
       
   103 		EOrderGenericPreLow1	=0x81u,		// Device driver spin locks, low range
       
   104 		EOrderGenericPreHigh0	=0x9Eu,		// Device driver spin locks, high range
       
   105 		EOrderGenericPreHigh1	=0x9Fu,		// Device driver spin locks, high range
       
   106 
       
   107 		EOrderNone				=0xFFu	// No order check required (e.g. for dynamic ordering)
       
   108 		};
       
   109 public:
       
   110 	IMPORT_C TSpinLock(TUint aOrder);
       
   111 private:
       
   112 	volatile TUint64 iLock;
       
   113 	};
       
   114 
       
   115 /** Macro to disable interrupts and acquire the lock.
       
   116 
       
   117 @publishedPartner
       
   118 @prototype
       
   119 */
       
   120 #define __SPIN_LOCK_IRQ(lock)					((void)NKern::DisableAllInterrupts())
       
   121 
       
   122 /** Macro to release the lock and enable interrupts.
       
   123 
       
   124 @publishedPartner
       
   125 @prototype
       
   126 */
       
   127 #define __SPIN_UNLOCK_IRQ(lock)					(NKern::EnableAllInterrupts())
       
   128 
       
   129 /** Macro to see if someone else is waiting for the lock, enabling IRQs 
       
   130     then disabling IRQs again.
       
   131 
       
   132 @publishedPartner
       
   133 @prototype
       
   134 */
       
   135 #define __SPIN_FLASH_IRQ(lock)					(NKern::EnableAllInterrupts(),(void)NKern::DisableAllInterrupts(),((TBool)TRUE))
       
   136 
       
   137 /** Macro to remember original interrupt state then disable interrupts 
       
   138     and acquire the lock.
       
   139     
       
   140 @publishedPartner
       
   141 @prototype
       
   142 */
       
   143 #define __SPIN_LOCK_IRQSAVE(lock)				(NKern::DisableAllInterrupts())
       
   144 
       
   145 /** Macro to release the lock then restore original interrupt state to that 
       
   146 	supplied.
       
   147 	
       
   148 @publishedPartner
       
   149 @prototype
       
   150 */
       
   151 #define __SPIN_UNLOCK_IRQRESTORE(lock,irq)		(NKern::RestoreInterrupts(irq))
       
   152 
       
   153 /** Macro to see if someone else is waiting for the lock, enabling IRQs to
       
   154 	the original state supplied then disabling IRQs again.
       
   155     
       
   156 @publishedPartner
       
   157 @prototype
       
   158 */
       
   159 #define __SPIN_FLASH_IRQRESTORE(lock,irq)		(NKern::RestoreInterrupts(irq),((void)NKern::DisableAllInterrupts()),((TBool)TRUE))
       
   160 
       
   161 /** Macro to acquire the lock. This assumes the caller has already disabled 
       
   162     interrupts/preemption. 
       
   163 	
       
   164 	If interrupts/preemption is not disabled a run-time assert will occur
       
   165 	This is to protect against unsafe code that might lead to same core 
       
   166 	deadlock.
       
   167 	
       
   168     In device driver code it is safer to use __SPIN_LOCK_IRQSAVE() instead, 
       
   169 	although not as efficient should interrupts aleady be disabled for the 
       
   170 	duration the lock is held.
       
   171     
       
   172 @publishedPartner
       
   173 @prototype
       
   174 */
       
   175 #define __SPIN_LOCK(lock)
       
   176 
       
   177 /** Macro to release the lock, don't change interrupt/preemption state.
       
   178 
       
   179 @publishedPartner
       
   180 @prototype
       
   181 */
       
   182 #define __SPIN_UNLOCK(lock)
       
   183 
       
   184 /**
       
   185 @internalComponent
       
   186 */
       
   187 #define __SPIN_FLASH(lock)						((TBool)FALSE)
       
   188 
       
   189 /** Macro to see if someone else is waiting for the lock, enabling preemption 
       
   190     then disabling it again.
       
   191 
       
   192 @publishedPartner
       
   193 @prototype
       
   194 */
       
   195 #define __SPIN_FLASH_PREEMPT(lock)				((TBool)NKern::PreemptionPoint())
       
   196 
       
   197 
       
   198 /** Read/Write Spin lock
       
   199 
       
   200 	@internalComponent
       
   201 */
       
   202 class TRWSpinLock
       
   203 	{
       
   204 public:
       
   205 	IMPORT_C TRWSpinLock(TUint aOrder);		// Uses same order space as TSpinLock
       
   206 private:
       
   207 	volatile TUint64 iLock;
       
   208 	};
       
   209 
       
   210 
       
   211 /**
       
   212 @publishedPartner
       
   213 @prototype
       
   214 */
       
   215 #define __SPIN_LOCK_IRQ_R(lock)					((void)NKern::DisableAllInterrupts())
       
   216 
       
   217 /**
       
   218 @publishedPartner
       
   219 @prototype
       
   220 */
       
   221 #define __SPIN_UNLOCK_IRQ_R(lock)				(NKern::EnableAllInterrupts())
       
   222 
       
   223 /**
       
   224 @publishedPartner
       
   225 @prototype
       
   226 */
       
   227 #define __SPIN_FLASH_IRQ_R(lock)				(NKern::EnableAllInterrupts(),(void)NKern::DisableAllInterrupts(),((TBool)TRUE))
       
   228 
       
   229 /**
       
   230 @publishedPartner
       
   231 @prototype
       
   232 */
       
   233 #define __SPIN_LOCK_IRQ_W(lock)					((void)NKern::DisableAllInterrupts())
       
   234 
       
   235 /**
       
   236 @publishedPartner
       
   237 @prototype
       
   238 */
       
   239 #define __SPIN_UNLOCK_IRQ_W(lock)				(NKern::EnableAllInterrupts())
       
   240 
       
   241 /**
       
   242 @publishedPartner
       
   243 @prototype
       
   244 */
       
   245 #define __SPIN_FLASH_IRQ_W(lock)				(NKern::EnableAllInterrupts(),(void)NKern::DisableAllInterrupts(),((TBool)TRUE))
       
   246 
       
   247 
       
   248 /**
       
   249 @publishedPartner
       
   250 @prototype
       
   251 */
       
   252 #define __SPIN_LOCK_R(lock)						
       
   253 
       
   254 /**
       
   255 @publishedPartner
       
   256 @prototype
       
   257 */
       
   258 #define __SPIN_UNLOCK_R(lock)					
       
   259 
       
   260 /**
       
   261 @internalComponent
       
   262 */
       
   263 #define __SPIN_FLASH_R(lock)					((TBool)FALSE)
       
   264 
       
   265 /**
       
   266 @publishedPartner
       
   267 @prototype
       
   268 */
       
   269 #define __SPIN_LOCK_W(lock)						
       
   270 
       
   271 /**
       
   272 @publishedPartner
       
   273 @prototype
       
   274 */
       
   275 #define __SPIN_UNLOCK_W(lock)					
       
   276 
       
   277 /**
       
   278 @internalComponent
       
   279 */
       
   280 #define __SPIN_FLASH_W(lock)					((TBool)FALSE)
       
   281 
       
   282 
       
   283 /**
       
   284 @publishedPartner
       
   285 @prototype
       
   286 */
       
   287 #define __SPIN_LOCK_IRQSAVE_R(lock)				(NKern::DisableAllInterrupts())
       
   288 
       
   289 /**
       
   290 @publishedPartner
       
   291 @prototype
       
   292 */
       
   293 #define __SPIN_UNLOCK_IRQRESTORE_R(lock,irq)	(NKern::RestoreInterrupts(irq))
       
   294 
       
   295 /**
       
   296 @publishedPartner
       
   297 @prototype
       
   298 */
       
   299 #define __SPIN_FLASH_IRQRESTORE_R(lock,irq)		(NKern::RestoreInterrupts(irq),((void)NKern::DisableAllInterrupts()),((TBool)TRUE))
       
   300 
       
   301 /**
       
   302 @publishedPartner
       
   303 @prototype
       
   304 */
       
   305 #define __SPIN_LOCK_IRQSAVE_W(lock)				(NKern::DisableAllInterrupts())
       
   306 
       
   307 /**
       
   308 @publishedPartner
       
   309 @prototype
       
   310 */
       
   311 #define __SPIN_UNLOCK_IRQRESTORE_W(lock,irq)	(NKern::RestoreInterrupts(irq))
       
   312 
       
   313 /**
       
   314 @publishedPartner
       
   315 @prototype
       
   316 */
       
   317 #define __SPIN_FLASH_IRQRESTORE_W(lock,irq)		(NKern::RestoreInterrupts(irq),((void)NKern::DisableAllInterrupts()),((TBool)TRUE))
       
   318 
       
   319 
       
   320 /**
       
   321 @publishedPartner
       
   322 @prototype
       
   323 */
       
   324 #define __SPIN_FLASH_PREEMPT_R(lock)			((TBool)NKern::PreemptionPoint())
       
   325 
       
   326 /**
       
   327 @publishedPartner
       
   328 @prototype
       
   329 */
       
   330 #define __SPIN_FLASH_PREEMPT_W(lock)			((TBool)NKern::PreemptionPoint())
       
   331 
       
   332 
       
   333 /** Nanokernel fast semaphore
       
   334 
       
   335 	A light-weight semaphore class that only supports a single waiting thread,
       
   336 	suitable for the Symbian OS thread I/O semaphore.
       
   337 	
       
   338 	Initialising a NFastSemaphore involves two steps:
       
   339 	
       
   340 	- Constructing the semaphore
       
   341 	- Setting the semaphore owning thread (the one allowed to wait on it)
       
   342 	
       
   343 	For example, creating one for the current thread to wait on:
       
   344 	
       
   345 	@code
       
   346 	NFastSemaphore sem;
       
   347 	sem.iOwningThread = NKern::CurrentThread();
       
   348 	@endcode
       
   349 	
       
   350 	@publishedPartner
       
   351 	@released
       
   352 */
       
   353 class NFastSemaphore
       
   354 	{
       
   355 public:
       
   356 	inline NFastSemaphore();
       
   357 	inline NFastSemaphore(NThreadBase* aThread);
       
   358 	IMPORT_C void SetOwner(NThreadBase* aThread);
       
   359 	IMPORT_C void Wait();
       
   360 	IMPORT_C void Signal();
       
   361 	IMPORT_C void SignalN(TInt aCount);
       
   362 	IMPORT_C void Reset();
       
   363 	void WaitCancel();
       
   364 public:
       
   365 	TInt iCount;				/**< @internalComponent */
       
   366 
       
   367 	/** The thread allowed to wait on the semaphore
       
   368 		@internalComponent
       
   369 	*/
       
   370 	NThreadBase* iOwningThread;	
       
   371 	};
       
   372 
       
   373 /** Create a fast semaphore
       
   374 
       
   375 	@publishedPartner
       
   376 	@released
       
   377 */
       
   378 inline NFastSemaphore::NFastSemaphore()
       
   379 	: iCount(0), iOwningThread(NULL)
       
   380 	{}
       
   381 
       
   382 /** Nanokernel fast mutex
       
   383 
       
   384 	A light-weight priority-inheritance mutex that can be used if the following
       
   385 	conditions apply:
       
   386 	
       
   387 	- Threads that hold the mutex never block.
       
   388 	- The mutex is never acquired in a nested fashion
       
   389 	
       
   390 	If either of these conditions is not met, a DMutex object is more appropriate.
       
   391 	
       
   392 	@publishedPartner
       
   393 	@released
       
   394 */
       
   395 class NFastMutex
       
   396 	{
       
   397 public:
       
   398 	IMPORT_C NFastMutex();
       
   399 	IMPORT_C void Wait();
       
   400 	IMPORT_C void Signal();
       
   401 	IMPORT_C TBool HeldByCurrentThread();	/**< @internalComponent */
       
   402 public:
       
   403 	NThreadBase* iHoldingThread;	/**< @internalComponent */
       
   404 
       
   405 	/** MUST ALWAYS BE 0 or 1
       
   406 		@internalComponent
       
   407 	*/
       
   408 	TInt iWaiting;
       
   409 	};
       
   410 
       
   411 
       
   412 /**
       
   413 @publishedPartner
       
   414 @released
       
   415 
       
   416 The type of the callback function used by the nanokernel timer. 
       
   417 
       
   418 @see NTimer
       
   419 */
       
   420 typedef void (*NTimerFn)(TAny*);
       
   421 
       
   422 
       
   423 
       
   424 
       
   425 /**
       
   426 @publishedPartner
       
   427 @released
       
   428 
       
   429 A basic relative timer provided by the nanokernel.
       
   430 
       
   431 It can generate either a one-shot interrupt or periodic interrupts.
       
   432 
       
   433 A timeout handler is called when the timer expires, either:
       
   434 - from the timer ISR - if the timer is queued via OneShot(TInt aTime) or OneShot(TInt aTime, TBool EFalse), or
       
   435 - from the nanokernel timer dfc1 thread - if the timer is queued via OneShot(TInt aTime, TBool ETrue) call, or
       
   436 - from any other dfc thread that provided DFC belongs to - if the timer is queued via OneShot(TInt aTime, TDfc& aDfc) call.
       
   437 Call-back mechanism cannot be changed in the life time of a timer.
       
   438 
       
   439 These timer objects may be manipulated from any context.
       
   440 The timers are driven from a periodic system tick interrupt,
       
   441 usually a 1ms period.
       
   442 
       
   443 @see NTimerFn
       
   444 */
       
   445 class NTimer : public SDblQueLink
       
   446 	{
       
   447 public:
       
   448 	/**
       
   449 	Default constructor.
       
   450 	*/
       
   451 	inline NTimer()
       
   452 		: iState(EIdle)
       
   453 		{}
       
   454 	/**
       
   455 	Constructor taking a callback function and a pointer to be passed
       
   456 	to the callback function.
       
   457 	
       
   458 	@param aFunction The callback function.
       
   459 	@param aPtr      A pointer to be passed to the callback function 
       
   460 	                 when called.
       
   461 	*/
       
   462 	inline NTimer(NTimerFn aFunction, TAny* aPtr)
       
   463 		: iPtr(aPtr), iFunction(aFunction), iState(EIdle)
       
   464 		{}
       
   465 	IMPORT_C TInt OneShot(TInt aTime);
       
   466 	IMPORT_C TInt OneShot(TInt aTime, TBool aDfc);
       
   467 	IMPORT_C TInt OneShot(TInt aTime, TDfc& aDfc);
       
   468 	IMPORT_C TInt Again(TInt aTime);
       
   469 	IMPORT_C TBool Cancel();
       
   470 	IMPORT_C TBool IsPending();
       
   471 public:
       
   472 /**
       
   473 	@internalComponent
       
   474 */
       
   475 	enum TState
       
   476 		{
       
   477 		EIdle=0,			// not queued
       
   478 		ETransferring=1,	// being transferred from holding to ordered queue
       
   479 		EHolding=2,			// on holding queue
       
   480 		EOrdered=3,			// on ordered queue
       
   481 		ECritical=4,		// on ordered queue and in use by queue walk routine
       
   482 		EFinal=5,			// on final queue
       
   483 		};
       
   484 public:
       
   485 	/** Argument for callback function or the pointer to TDfc */
       
   486 	TAny* iPtr;				/**< @internalComponent */
       
   487 
       
   488 	/** Pointer to callback function. NULL value indicates that queuing of provided Dfc queue will be done
       
   489 	instead of calling callback function on completion */
       
   490 	NTimerFn iFunction;		/**< @internalComponent */
       
   491 
       
   492 	TUint32 iTriggerTime;	/**< @internalComponent */
       
   493 	TUint8 iCompleteInDfc;	/**< @internalComponent */
       
   494 	TUint8 iState;			/**< @internalComponent */
       
   495 	TUint8 iPad1;			/**< @internalComponent */
       
   496 
       
   497 	/** Available for timer client to use.
       
   498 		@internalTechnology */
       
   499 	TUint8 iUserFlags;
       
   500 	};
       
   501 
       
   502 /**
       
   503 @internalTechnology
       
   504 */
       
   505 #define	i_NTimer_iUserFlags	iUserFlags
       
   506 
       
   507 /**
       
   508 @internalComponent
       
   509 */
       
   510 #define	i_NTimer_iState		iState
       
   511 
       
   512 /**
       
   513 	@publishedPartner
       
   514 	@released
       
   515 */
       
   516 typedef void (*NThreadFunction)(TAny*);
       
   517 
       
   518 /**
       
   519 	@publishedPartner
       
   520 	@released
       
   521 */
       
   522 typedef TDfc* (*NThreadExitHandler)(NThread*);
       
   523 
       
   524 /**
       
   525 	@publishedPartner
       
   526 	@released
       
   527 */
       
   528 typedef void (*NThreadStateHandler)(NThread*,TInt,TInt);
       
   529 
       
   530 /**
       
   531 	@publishedPartner
       
   532 	@released
       
   533 */
       
   534 typedef void (*NThreadExceptionHandler)(TAny*,NThread*);
       
   535 
       
   536 /**
       
   537 	@publishedPartner
       
   538 	@released
       
   539 */
       
   540 typedef void (*NThreadTimeoutHandler)(NThread*,TInt);
       
   541 
       
   542 /**
       
   543 	@publishedPartner
       
   544 	@released
       
   545 */
       
   546 struct SNThreadHandlers
       
   547 	{
       
   548 	NThreadExitHandler iExitHandler;
       
   549 	NThreadStateHandler iStateHandler;
       
   550 	NThreadExceptionHandler iExceptionHandler;
       
   551 	NThreadTimeoutHandler iTimeoutHandler;
       
   552 	};
       
   553 
       
   554 /** @internalComponent */
       
   555 extern void NThread_Default_State_Handler(NThread*, TInt, TInt);
       
   556 
       
   557 /** @internalComponent */
       
   558 extern void NThread_Default_Exception_Handler(TAny*, NThread*);
       
   559 
       
   560 /** @internalComponent */
       
   561 #define NTHREAD_DEFAULT_EXIT_HANDLER		((NThreadExitHandler)0)
       
   562 
       
   563 /** @internalComponent */
       
   564 #define	NTHREAD_DEFAULT_STATE_HANDLER		(&NThread_Default_State_Handler)
       
   565 
       
   566 /** @internalComponent */
       
   567 #define	NTHREAD_DEFAULT_EXCEPTION_HANDLER	(&NThread_Default_Exception_Handler)
       
   568 
       
   569 /** @internalComponent */
       
   570 #define	NTHREAD_DEFAULT_TIMEOUT_HANDLER		((NThreadTimeoutHandler)0)
       
   571 
       
   572 
       
   573 /**
       
   574 	@publishedPartner
       
   575 	@released
       
   576 */
       
   577 struct SFastExecTable
       
   578 	{
       
   579 	TInt iFastExecCount;			// includes implicit function#0
       
   580 	TLinAddr iFunction[1];			// first entry is for call number 1
       
   581 	};
       
   582 
       
   583 /**
       
   584 	@publishedPartner
       
   585 	@released
       
   586 */
       
   587 const TUint32 KExecFlagClaim=0x80000000;		// claim system lock
       
   588 
       
   589 /**
       
   590 	@publishedPartner
       
   591 	@released
       
   592 */
       
   593 const TUint32 KExecFlagRelease=0x40000000;		// release system lock
       
   594 
       
   595 /**
       
   596 	@publishedPartner
       
   597 	@released
       
   598 */
       
   599 const TUint32 KExecFlagPreprocess=0x20000000;	// preprocess
       
   600 
       
   601 /**
       
   602 	@publishedPartner
       
   603 	@released
       
   604 */
       
   605 const TUint32 KExecFlagExtraArgMask=0x1C000000;	// 3 bits indicating additional arguments
       
   606 
       
   607 /**
       
   608 	@publishedPartner
       
   609 	@released
       
   610 */
       
   611 const TUint32 KExecFlagExtraArgs2=0x04000000;	// 2 additional arguments
       
   612 
       
   613 /**
       
   614 	@publishedPartner
       
   615 	@released
       
   616 */
       
   617 const TUint32 KExecFlagExtraArgs3=0x08000000;	// 3 additional arguments
       
   618 
       
   619 /**
       
   620 	@publishedPartner
       
   621 	@released
       
   622 */
       
   623 const TUint32 KExecFlagExtraArgs4=0x0C000000;	// 4 additional arguments
       
   624 
       
   625 /**
       
   626 	@publishedPartner
       
   627 	@released
       
   628 */
       
   629 const TUint32 KExecFlagExtraArgs5=0x10000000;	// 5 additional arguments
       
   630 
       
   631 /**
       
   632 	@publishedPartner
       
   633 	@released
       
   634 */
       
   635 const TUint32 KExecFlagExtraArgs6=0x14000000;	// 6 additional arguments
       
   636 
       
   637 /**
       
   638 	@publishedPartner
       
   639 	@released
       
   640 */
       
   641 const TUint32 KExecFlagExtraArgs7=0x18000000;	// 7 additional arguments
       
   642 
       
   643 /**
       
   644 	@publishedPartner
       
   645 	@released
       
   646 */
       
   647 const TUint32 KExecFlagExtraArgs8=0x1C000000;	// 8 additional arguments
       
   648 
       
   649 
       
   650 /**
       
   651 	@publishedPartner
       
   652 	@released
       
   653 */
       
   654 struct SSlowExecEntry
       
   655 	{
       
   656 	TUint32 iFlags;					// information about call
       
   657 	TLinAddr iFunction;				// address of function to be called
       
   658 	};
       
   659 
       
   660 
       
   661 /**
       
   662 	@publishedPartner
       
   663 	@released
       
   664 */
       
   665 struct SSlowExecTable
       
   666 	{
       
   667 	TInt iSlowExecCount;
       
   668 	TLinAddr iInvalidExecHandler;	// used if call number invalid
       
   669 	TLinAddr iPreprocessHandler;	// used for handle lookups
       
   670 	SSlowExecEntry iEntries[1];		// first entry is for call number 0
       
   671 	};
       
   672 
       
   673 // Thread iAttributes Constants
       
   674 const TUint8 KThreadAttImplicitSystemLock=1;	/**< @internalComponent */
       
   675 const TUint8 KThreadAttAddressSpace=2;			/**< @internalComponent */
       
   676 const TUint8 KThreadAttLoggable=4;				/**< @internalComponent */
       
   677 const TUint8 KThreadAttDelayed=8;				/**< @internalComponent */
       
   678 
       
   679 
       
   680 // Thread CPU
       
   681 const TUint32 KCpuAffinityAny=0xffffffffu;		/**< @internalComponent */
       
   682 
       
   683 /** Information needed for creating a nanothread.
       
   684 
       
   685 	@publishedPartner
       
   686 	@released
       
   687 */
       
   688 struct SNThreadCreateInfo
       
   689 	{
       
   690 	NThreadFunction iFunction;
       
   691 	TAny* iStackBase;
       
   692 	TInt iStackSize;
       
   693 	TInt iPriority;
       
   694 	TInt iTimeslice;
       
   695 	TUint8 iAttributes;
       
   696 	TUint32 iCpuAffinity;
       
   697 	const SNThreadHandlers* iHandlers;
       
   698 	const SFastExecTable* iFastExecTable;
       
   699 	const SSlowExecTable* iSlowExecTable;
       
   700 	const TUint32* iParameterBlock;
       
   701 	TInt iParameterBlockSize;		// if zero, iParameterBlock _is_ the initial data
       
   702 									// otherwise it points to n bytes of initial data
       
   703 	};
       
   704 
       
   705 /**	Constant for use with NKern:: functions which release a fast mutex as well
       
   706 	as performing some other operations.
       
   707 
       
   708 	@publishedPartner
       
   709 	@released
       
   710 */
       
   711 #define	SYSTEM_LOCK		(NFastMutex*)0
       
   712 
       
   713 
       
   714 /** Idle handler function
       
   715 	Pointer to a function which is called whenever a CPU goes idle
       
   716 
       
   717 	@param	aPtr	The iPtr stored in the SCpuIdleHandler structure
       
   718 	@param	aStage	If positive, the number of processors still active
       
   719 					If zero, indicates all processors are now idle
       
   720 					-1 indicates that postamble processing is required after waking up
       
   721 
       
   722 	@internalComponent
       
   723 */
       
   724 typedef void (*TCpuIdleHandlerFn)(TAny* aPtr, TInt aStage);
       
   725 
       
   726 /** Idle handler structure
       
   727 
       
   728 	@internalComponent
       
   729 */
       
   730 struct SCpuIdleHandler
       
   731 	{
       
   732 	TCpuIdleHandlerFn	iHandler;
       
   733 	TAny*				iPtr;
       
   734 	volatile TBool		iPostambleRequired;
       
   735 	};
       
   736 
       
   737 
       
   738 /**
       
   739 @internalComponent
       
   740 */
       
   741 enum TUserModeCallbackReason
       
   742 	{
       
   743 	EUserModeCallbackRun,
       
   744 	EUserModeCallbackCancel,
       
   745 	};
       
   746 
       
   747 
       
   748 /**
       
   749 A callback function executed when a thread returns to user mode.
       
   750 
       
   751 @internalComponent
       
   752 */
       
   753 typedef void (*TUserModeCallbackFunc)(TAny* aThisPtr, TUserModeCallbackReason aReasonCode);
       
   754 
       
   755 
       
   756 /**
       
   757 An object representing a queued callback to be executed when a thread returns to user mode.
       
   758 
       
   759 @internalComponent
       
   760 */
       
   761 class TUserModeCallback
       
   762 	{
       
   763 public:
       
   764 	TUserModeCallback(TUserModeCallbackFunc);
       
   765 	~TUserModeCallback();
       
   766 
       
   767 public:
       
   768 	TUserModeCallback* volatile iNext;
       
   769 	TUserModeCallbackFunc iFunc;
       
   770 	};
       
   771 
       
   772 TUserModeCallback* const KUserModeCallbackUnqueued = ((TUserModeCallback*)1);
       
   773 
       
   774 
       
   775 /** Nanokernel functions
       
   776 
       
   777 	@publishedPartner
       
   778 	@released
       
   779 */
       
   780 class NKern
       
   781 	{
       
   782 public:
       
   783 	/** Bitmask values used when blocking a nanothread.
       
   784 		@see NKern::Block()
       
   785 	 */
       
   786 	enum TBlockMode 
       
   787 		{
       
   788 		EEnterCS=1,		/**< Enter thread critical section before blocking */
       
   789 		ERelease=2,		/**< Release specified fast mutex before blocking */
       
   790 		EClaim=4,		/**< Re-acquire specified fast mutex when unblocked */
       
   791 		EObstruct=8,	/**< Signifies obstruction of thread rather than lack of work to do */
       
   792 		};
       
   793 
       
   794 	/** Values that specify the context of the processor.
       
   795 		@see NKern::CurrentContext()
       
   796 	*/
       
   797 	enum TContext
       
   798 		{
       
   799 		EThread=0,			/**< The processor is in a thread context*/
       
   800 		EIDFC=1,			/**< The processor is in an IDFC context*/
       
   801 		EInterrupt=2,		/**< The processor is in an interrupt context*/
       
   802 		EEscaped=KMaxTInt	/**< Not valid a process context on target hardware*/
       
   803 		};
       
   804 
       
   805 public:
       
   806 	// Threads
       
   807 	IMPORT_C static TInt ThreadCreate(NThread* aThread, SNThreadCreateInfo& anInfo);
       
   808 	IMPORT_C static TBool ThreadSuspend(NThread* aThread, TInt aCount);
       
   809 	IMPORT_C static TBool ThreadResume(NThread* aThread);
       
   810 	IMPORT_C static TBool ThreadResume(NThread* aThread, NFastMutex* aMutex);
       
   811 	IMPORT_C static TBool ThreadForceResume(NThread* aThread);
       
   812 	IMPORT_C static TBool ThreadForceResume(NThread* aThread, NFastMutex* aMutex);
       
   813 	IMPORT_C static void ThreadRelease(NThread* aThread, TInt aReturnValue);
       
   814 	IMPORT_C static void ThreadRelease(NThread* aThread, TInt aReturnValue, NFastMutex* aMutex);
       
   815 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority);
       
   816 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority, NFastMutex* aMutex);
       
   817 	IMPORT_C static void ThreadRequestSignal(NThread* aThread);
       
   818 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, NFastMutex* aMutex);
       
   819 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, TInt aCount);
       
   820 	IMPORT_C static void ThreadKill(NThread* aThread);
       
   821 	IMPORT_C static void ThreadKill(NThread* aThread, NFastMutex* aMutex);
       
   822 	IMPORT_C static void ThreadEnterCS();
       
   823 	IMPORT_C static void ThreadLeaveCS();
       
   824 	static NThread* _ThreadEnterCS();		/**< @internalComponent */
       
   825 	static void _ThreadLeaveCS();			/**< @internalComponent */
       
   826 	IMPORT_C static TInt Block(TUint32 aTimeout, TUint aMode, NFastMutex* aMutex);
       
   827 	IMPORT_C static TInt Block(TUint32 aTimeout, TUint aMode);
       
   828 	IMPORT_C static void NanoBlock(TUint32 aTimeout, TUint aState, TAny* aWaitObj);
       
   829 	IMPORT_C static void ThreadGetUserContext(NThread* aThread, TAny* aContext, TUint32& aAvailRegistersMask);
       
   830 	IMPORT_C static void ThreadSetUserContext(NThread* aThread, TAny* aContext);
       
   831 	IMPORT_C static void ThreadGetSystemContext(NThread* aThread, TAny* aContext, TUint32& aAvailRegistersMask);
       
   832 	static void ThreadModifyUsp(NThread* aThread, TLinAddr aUsp);
       
   833 	IMPORT_C static TInt FreezeCpu();													/**< @internalComponent */
       
   834 	IMPORT_C static void EndFreezeCpu(TInt aCookie);									/**< @internalComponent */
       
   835 	IMPORT_C static TUint32 ThreadSetCpuAffinity(NThread* aThread, TUint32 aAffinity);	/**< @internalComponent */
       
   836 	IMPORT_C static void ThreadSetTimeslice(NThread* aThread, TInt aTimeslice);			/**< @internalComponent */
       
   837 	IMPORT_C static TUint64 ThreadCpuTime(NThread* aThread);							/**< @internalComponent */
       
   838 	IMPORT_C static TUint32 CpuTimeMeasFreq();											/**< @internalComponent */
       
   839 	static TInt QueueUserModeCallback(NThreadBase* aThread, TUserModeCallback* aCallback);	/**< @internalComponent */
       
   840 	static void MoveUserModeCallbacks(NThreadBase* aSrcThread, NThreadBase* aDestThread);	/**< @internalComponent */
       
   841 	static void CancelUserModeCallbacks();												/**< @internalComponent */
       
   842 
       
   843 	// Fast semaphores
       
   844 	IMPORT_C static void FSSetOwner(NFastSemaphore* aSem,NThreadBase* aThread);
       
   845 	IMPORT_C static void FSWait(NFastSemaphore* aSem);
       
   846 	IMPORT_C static void FSSignal(NFastSemaphore* aSem);
       
   847 	IMPORT_C static void FSSignal(NFastSemaphore* aSem, NFastMutex* aMutex);
       
   848 	IMPORT_C static void FSSignalN(NFastSemaphore* aSem, TInt aCount);
       
   849 	IMPORT_C static void FSSignalN(NFastSemaphore* aSem, TInt aCount, NFastMutex* aMutex);
       
   850 
       
   851 	// Fast mutexes
       
   852 	IMPORT_C static void FMWait(NFastMutex* aMutex);
       
   853 	IMPORT_C static void FMSignal(NFastMutex* aMutex);
       
   854 	IMPORT_C static TBool FMFlash(NFastMutex* aMutex);
       
   855 
       
   856 	// Scheduler
       
   857 	IMPORT_C static void Lock();
       
   858 	IMPORT_C static NThread* LockC();	
       
   859 	IMPORT_C static void Unlock();
       
   860 	IMPORT_C static TInt PreemptionPoint();
       
   861 
       
   862 	// Interrupts
       
   863 	IMPORT_C static TInt DisableAllInterrupts();
       
   864 	IMPORT_C static TInt DisableInterrupts(TInt aLevel);
       
   865 	IMPORT_C static void RestoreInterrupts(TInt aRestoreData);
       
   866 	IMPORT_C static void EnableAllInterrupts();
       
   867 
       
   868 	// Read-modify-write
       
   869 	inline static TInt LockedInc(TInt& aCount)
       
   870 		{ return __e32_atomic_add_ord32(&aCount,1); }
       
   871 	inline static TInt LockedDec(TInt& aCount)
       
   872 		{ return __e32_atomic_add_ord32(&aCount,0xffffffff); }
       
   873 	inline static TInt LockedAdd(TInt& aDest, TInt aSrc)
       
   874 		{ return __e32_atomic_add_ord32(&aDest,aSrc); }
       
   875 	inline static TInt64 LockedInc(TInt64& aCount)
       
   876 		{ return __e32_atomic_add_ord64(&aCount,1); }
       
   877 	inline static TInt64 LockedDec(TInt64& aCount)
       
   878 		{ return __e32_atomic_add_ord64(&aCount,TUint64(TInt64(-1))); }
       
   879 	inline static TInt64 LockedAdd(TInt64& aDest, TInt64 aSrc)		/**< @internalComponent */
       
   880 		{ return __e32_atomic_add_ord64(&aDest,aSrc); }
       
   881 	inline static TUint32 LockedSetClear(TUint32& aDest, TUint32 aClearMask, TUint32 aSetMask)
       
   882 		{ return __e32_atomic_axo_ord32(&aDest,~(aClearMask|aSetMask),aSetMask); }
       
   883 	inline static TUint16 LockedSetClear16(TUint16& aDest, TUint16 aClearMask, TUint16 aSetMask)	/**< @internalComponent */
       
   884 		{ return __e32_atomic_axo_ord16(&aDest,TUint16(~(aClearMask|aSetMask)),aSetMask); }
       
   885 	inline static TUint8 LockedSetClear8(TUint8& aDest, TUint8 aClearMask, TUint8 aSetMask)
       
   886 		{ return __e32_atomic_axo_ord8(&aDest,TUint8(~(aClearMask|aSetMask)),aSetMask); }
       
   887 	inline static TInt SafeInc(TInt& aCount)
       
   888 		{ return __e32_atomic_tas_ord32(&aCount,1,1,0); }
       
   889 	inline static TInt SafeDec(TInt& aCount)
       
   890 		{ return __e32_atomic_tas_ord32(&aCount,1,-1,0); }
       
   891 	inline static TInt AddIfGe(TInt& aCount, TInt aLimit, TInt aInc)	/**< @internalComponent */
       
   892 		{ return __e32_atomic_tas_ord32(&aCount,aLimit,aInc,0); }
       
   893 	inline static TInt AddIfLt(TInt& aCount, TInt aLimit, TInt aInc)	/**< @internalComponent */
       
   894 		{ return __e32_atomic_tas_ord32(&aCount,aLimit,0,aInc); }
       
   895 	inline static TAny* SafeSwap(TAny* aNewValue, TAny*& aPtr)
       
   896 		{ return __e32_atomic_swp_ord_ptr(&aPtr, aNewValue); }
       
   897 	inline static TUint8 SafeSwap8(TUint8 aNewValue, TUint8& aPtr)
       
   898 		{ return __e32_atomic_swp_ord8(&aPtr, aNewValue); }
       
   899 	inline static TUint16 SafeSwap16(TUint16 aNewValue, TUint16& aPtr)						/**< @internalComponent */
       
   900 		{ return __e32_atomic_swp_ord16(&aPtr, aNewValue); }
       
   901 	inline static TBool CompareAndSwap(TAny*& aPtr, TAny* aExpected, TAny* aNew)			/**< @internalComponent */
       
   902 		{ return __e32_atomic_cas_ord_ptr(&aPtr, &aExpected, aNew); }
       
   903 	inline static TBool CompareAndSwap8(TUint8& aPtr, TUint8 aExpected, TUint8 aNew)		/**< @internalComponent */
       
   904 		{ return __e32_atomic_cas_ord8(&aPtr, (TUint8*)&aExpected, (TUint8)aNew); }
       
   905 	inline static TBool CompareAndSwap16(TUint16& aPtr, TUint16 aExpected, TUint16 aNew)	/**< @internalComponent */
       
   906 		{ return __e32_atomic_cas_ord16(&aPtr, (TUint16*)&aExpected, (TUint16)aNew); }
       
   907 	inline static TUint32 SafeSwap(TUint32 aNewValue, TUint32& aPtr)						/**< @internalComponent */
       
   908 		{ return __e32_atomic_swp_ord32(&aPtr, aNewValue); }
       
   909 	inline static TUint SafeSwap(TUint aNewValue, TUint& aPtr)								/**< @internalComponent */
       
   910 		{ return __e32_atomic_swp_ord32(&aPtr, aNewValue); }
       
   911 	inline static TInt SafeSwap(TInt aNewValue, TInt& aPtr)									/**< @internalComponent */
       
   912 		{ return __e32_atomic_swp_ord32(&aPtr, aNewValue); }
       
   913 	inline static TBool CompareAndSwap(TUint32& aPtr, TUint32 aExpected, TUint32 aNew)		/**< @internalComponent */
       
   914 		{ return __e32_atomic_cas_ord32(&aPtr, &aExpected, aNew); }
       
   915 	inline static TBool CompareAndSwap(TUint& aPtr, TUint aExpected, TUint aNew)			/**< @internalComponent */
       
   916 		{ return __e32_atomic_cas_ord32(&aPtr, (TUint32*)&aExpected, (TUint32)aNew); }
       
   917 	inline static TBool CompareAndSwap(TInt& aPtr, TInt aExpected, TInt aNew)				/**< @internalComponent */
       
   918 		{ return __e32_atomic_cas_ord32(&aPtr, (TUint32*)&aExpected, (TUint32)aNew); }
       
   919 
       
   920 
       
   921 	// Miscellaneous
       
   922 	IMPORT_C static NThread* CurrentThread();
       
   923 	IMPORT_C static TInt CurrentCpu();										/**< @internalComponent */
       
   924 	IMPORT_C static TInt NumberOfCpus();									/**< @internalComponent */
       
   925 	IMPORT_C static void LockSystem();
       
   926 	IMPORT_C static void UnlockSystem();
       
   927 	IMPORT_C static TBool FlashSystem();
       
   928 	IMPORT_C static void WaitForAnyRequest();
       
   929 	IMPORT_C static void Sleep(TUint32 aTime);
       
   930 	IMPORT_C static void Exit();
       
   931 	IMPORT_C static void DeferredExit();
       
   932 	IMPORT_C static void YieldTimeslice();									/**< @internalComponent */
       
   933 	IMPORT_C static void RotateReadyList(TInt aPriority);					
       
   934 	IMPORT_C static void RotateReadyList(TInt aPriority, TInt aCpu);		/**< @internalTechnology */
       
   935 	IMPORT_C static void RecordIntLatency(TInt aLatency, TInt aIntMask);	/**< @internalTechnology */
       
   936 	IMPORT_C static void RecordThreadLatency(TInt aLatency);				/**< @internalTechnology */
       
   937 	IMPORT_C static TUint32 TickCount();
       
   938 	IMPORT_C static TInt TickPeriod();
       
   939 	IMPORT_C static TInt TimerTicks(TInt aMilliseconds);
       
   940 	IMPORT_C static TInt TimesliceTicks(TUint32 aMicroseconds);				/**< @internalTechnology */
       
   941 	IMPORT_C static TInt CurrentContext();
       
   942 	IMPORT_C static TUint32 FastCounter();
       
   943 	IMPORT_C static TInt FastCounterFrequency();
       
   944 	static void Init0(TAny* aVariantData);
       
   945 	static void Init(NThread* aThread, SNThreadCreateInfo& anInfo);
       
   946 	IMPORT_C static TBool KernelLocked(TInt aCount=0);						/**< @internalTechnology */
       
   947 	IMPORT_C static NFastMutex* HeldFastMutex();							/**< @internalTechnology */
       
   948 	static void Idle();	
       
   949 	IMPORT_C static SCpuIdleHandler* CpuIdleHandler();						/**< @internalTechnology */
       
   950 	static void NotifyCrash(const TAny* a0, TInt a1);						/**< @internalTechnology */
       
   951 	IMPORT_C static TBool Crashed();
       
   952 	static TUint32 IdleGenerationCount();
       
   953 
       
   954 	// Debugger support
       
   955 	typedef void (*TRescheduleCallback)(NThread*);
       
   956 	IMPORT_C static void SchedulerHooks(TLinAddr& aStart, TLinAddr& aEnd);
       
   957 	IMPORT_C static void InsertSchedulerHooks();
       
   958 	IMPORT_C static void RemoveSchedulerHooks();
       
   959 	IMPORT_C static void SetRescheduleCallback(TRescheduleCallback aCallback);
       
   960 	};
       
   961 
       
   962 
       
   963 /** Create a fast semaphore
       
   964 
       
   965 	@publishedPartner
       
   966 	@released
       
   967 */
       
   968 inline NFastSemaphore::NFastSemaphore(NThreadBase* aThread)
       
   969 	:	iCount(0),
       
   970 		iOwningThread(aThread ? aThread : (NThreadBase*)NKern::CurrentThread())
       
   971 	{
       
   972 	}
       
   973 
       
   974 
       
   975 #endif