Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// e32\include\nkernsmp\nk_priv.h
//
// WARNING: This file contains some APIs which are internal and are subject
// to change without notice. Such APIs should therefore not be used
// outside the Kernel and Hardware Services package.
//
#ifndef __NK_PRIV_H__
#define __NK_PRIV_H__
#include <cpudefs.h>
#include <nkern.h>
#define __USE_BTRACE_LOCK__
class Monitor;
/********************************************
* Schedulable = thread or thread group
********************************************/
/**
@publishedPartner
@prototype
Base class for a nanokernel thread or group
*/
class NThreadGroup;
class NSchedulable : public TPriListLink
{
public:
enum
{
EReadyGroup=1,
EReadyCpuMask=0x7f,
EReadyOffset=0x80,
};
enum NReadyFlags
{
ENewTimeslice=1,
EPreferSameCpu=2,
EUnPause=4,
};
enum NEventState
{
EEventCountShift=16u,
EEventCountMask=0xffff0000u,
EEventCountInc=0x10000u,
EEventCpuShift=0u,
EEventCpuMask=0x1fu,
EThreadCpuShift=8u,
EThreadCpuMask=0x1f00u,
EDeferredReady=0x4000u,
EEventParent=0x8000u,
};
public:
NSchedulable();
void AcqSLock();
void RelSLock();
void LAcqSLock();
void RelSLockU();
void ReadyT(TUint aMode); // make ready, assumes lock held
TInt BeginTiedEvent();
void EndTiedEvent();
TInt AddTiedEvent(NEventHandler* aEvent);
TBool TiedEventReadyInterlock(TInt aCpu);
void UnPauseT(); // decrement pause count and make ready if necessary
static void DeferredReadyIDfcFn(TAny*);
void DetachTiedEvents();
public:
inline TBool IsGroup() {return !iParent;}
inline TBool IsLoneThread() {return iParent==this;}
inline TBool IsGroupThread() {return iParent && iParent!=this;}
public:
// TUint8 iReady; /**< @internalComponent */ // flag indicating thread on ready list = cpu number | EReadyOffset
// TUint8 iCurrent; /**< @internalComponent */ // flag indicating thread is running
// TUint8 iLastCpu; /**< @internalComponent */ // CPU on which this thread last ran
TUint8 iPauseCount; /**< @internalComponent */ // count of externally requested pauses extending a voluntary wait
TUint8 iSuspended; /**< @internalComponent */ // flag indicating active external suspend (Not used for groups)
TUint8 iNSchedulableSpare1; /**< @internalComponent */
TUint8 iNSchedulableSpare2; /**< @internalComponent */
TUint8 iCpuChange; /**< @internalComponent */ // flag showing CPU migration outstanding
TUint8 iStopping; /**< @internalComponent */ // thread is exiting, thread group is being destroyed
TUint16 iFreezeCpu; /**< @internalComponent */ // flag set if CPU frozen - count for groups
NSchedulable* iParent; /**< @internalComponent */ // Pointer to group containing thread, =this for normal thread, =0 for group
TUint32 iCpuAffinity; /**< @internalComponent */
volatile TUint32 iEventState; /**< @internalComponent */ // bits 16-31=count, 0-4=event CPU, 5-9=thread CPU, 10=defer, 11=parent
TSpinLock iSSpinLock; /**< @internalComponent */
SDblQue iEvents; /**< @internalComponent */ // doubly-linked list of tied events
TUint32 i_IDfcMem[sizeof(TDfc)/sizeof(TUint32)]; /**< @internalComponent */ // IDFC used to make thread ready after last tied event completes
// TDfc iDeferredReadyIDfc; /**< @internalComponent */ // IDFC used to make thread ready after last tied event completes
union
{
TUint64 iRunCount64;
TUint32 iRunCount32[2];
};
union
{
TUint64 iTotalCpuTime64; /**< @internalComponent */ // total time spent running, in hi-res timer ticks
TUint32 iTotalCpuTime32[2]; /**< @internalComponent */ // total time spent running, in hi-res timer ticks
};
};
__ASSERT_COMPILE(!(_FOFF(NSchedulable,iSSpinLock)&7));
__ASSERT_COMPILE(!(_FOFF(NSchedulable,iRunCount64)&7));
__ASSERT_COMPILE(!(_FOFF(NSchedulable,iTotalCpuTime64)&7));
__ASSERT_COMPILE(!(sizeof(NSchedulable)&7));
/**
@internalComponent
*/
inline TBool TDfc::IsValid()
{
if (iHType < KNumDfcPriorities)
return TRUE;
if (iHType != EEventHandlerIDFC)
return FALSE;
return !iTied || !iTied->iStopping;
}
/********************************************
* Thread
********************************************/
/**
@internalComponent
*/
class NThreadWaitState
{
private:
enum TWtStFlags
{
EWtStWaitPending =0x01u, // thread is about to wait
EWtStWaitActive =0x02u, // thread is actually blocked
EWtStTimeout =0x04u, // timeout is active on this wait
EWtStObstructed =0x08u, // wait is due to obstruction (e.g. mutex) rather than lack of work to do
EWtStDead =0x80u, // thread is dead
};
private:
NThreadWaitState();
void SetUpWait(TUint aType, TUint aFlags, TAny* aWaitObj);
void SetUpWait(TUint aType, TUint aFlags, TAny* aWaitObj, TUint32 aTimeout);
void SetDead(TDfc* aKillDfc);
void CancelWait();
TInt DoWait();
static void TimerExpired(TAny*);
TInt UnBlockT(TUint aType, TAny* aWaitObj, TInt aReturnValue);
TUint32 ReleaseT(TAny*& aWaitObj, TInt aReturnValue);
void CancelTimerT();
private:
inline NThreadBase* Thread();
inline TBool WaitPending()
{ return iWtC.iWtStFlags & (EWtStWaitPending|EWtStDead); }
inline TBool ThreadIsBlocked()
{ return iWtC.iWtStFlags & (EWtStWaitActive|EWtStDead); }
inline TBool ThreadIsDead()
{ return iWtC.iWtStFlags & EWtStDead; }
private:
struct S
{
volatile TUint8 iWtStFlags;
volatile TUint8 iWtObjType;
volatile TUint8 iWtStSpare1;
volatile TUint8 iWtStSpare2;
union
{
TAny* volatile iWtObj;
volatile TInt iRetVal;
TDfc* volatile iKillDfc;
};
};
union
{
S iWtC;
volatile TUint32 iWtSt32[2];
volatile TUint64 iWtSt64;
};
NTimer iTimer;
private:
friend class NSchedulable;
friend class NThreadBase;
friend class NThread;
friend class TScheduler;
friend class TSubScheduler;
friend class TDfc;
friend class TDfcQue;
friend class NFastSemaphore;
friend class NFastMutex;
friend class NTimer;
friend class NTimerQ;
friend class NKern;
friend class Monitor;
friend class NKTest;
};
/**
@publishedPartner
@prototype
Base class for a nanokernel thread.
*/
class TSubScheduler;
class NThreadBase : public NSchedulable
{
public:
/**
Defines the possible types of wait object
*/
enum NThreadWaitType
{
EWaitNone,
EWaitFastSemaphore,
EWaitFastMutex,
EWaitSleep,
EWaitBlocked,
EWaitDfc,
ENumWaitTypes
};
/**
@internalComponent
*/
enum NThreadCSFunction
{
ECSExitPending=-1,
ECSExitInProgress=-2,
ECSDivertPending=-3,
};
/**
@internalComponent
*/
enum NThreadTimeoutOp
{
ETimeoutPreamble=0,
ETimeoutPostamble=1,
ETimeoutSpurious=2,
};
public:
NThreadBase();
TInt Create(SNThreadCreateInfo& anInfo, TBool aInitial);
void UnReadyT();
TBool SuspendOrKill(TInt aCount);
TBool DoSuspendOrKillT(TInt aCount, TSubScheduler* aS);
TBool CancelTimerT();
void DoReleaseT(TInt aReturnCode, TUint aMode);
TBool CheckFastMutexDefer();
void DoCsFunctionT();
TBool Resume(TBool aForce);
IMPORT_C TBool Suspend(TInt aCount); /**< @internalComponent */
IMPORT_C TBool Resume(); /**< @internalComponent */
IMPORT_C TBool ForceResume(); /**< @internalComponent */
IMPORT_C void Release(TInt aReturnCode, TUint aMode); /**< @internalComponent */
IMPORT_C void RequestSignal(); /**< @internalComponent */
IMPORT_C void SetPriority(TInt aPriority); /**< @internalComponent */
void SetMutexPriority(NFastMutex* aMutex);
void LoseInheritedPriorityT();
void ChangeReadyThreadPriority();
TUint32 SetCpuAffinity(TUint32 aAffinity);
TBool TiedEventLeaveInterlock();
TBool TiedEventJoinInterlock();
IMPORT_C void Kill(); /**< @internalComponent */
void Exit();
// hooks for platform-specific code
void OnKill();
void OnExit();
public:
static void TimerExpired(TAny* aPtr);
/** @internalComponent */
inline void UnknownState(TInt aOp, TInt aParam)
{ (*iHandlers->iStateHandler)((NThread*)this,aOp,aParam); }
/** @internalComponent */
inline TUint8 Attributes()
{ return i_ThrdAttr; }
/** @internalComponent */
inline TUint8 SetAttributes(TUint8 aNewAtt)
{ return __e32_atomic_swp_ord8(&i_ThrdAttr, aNewAtt); }
/** @internalComponent */
inline TUint8 ModifyAttributes(TUint8 aClearMask, TUint8 aSetMask)
{ return __e32_atomic_axo_ord8(&i_ThrdAttr, (TUint8)~(aClearMask|aSetMask), aSetMask); }
/** @internalComponent */
inline void SetAddressSpace(TAny* a)
{ iAddressSpace=a; }
/** @internalComponent */
inline void SetExtraContext(TAny* a, TInt aSize)
{ iExtraContext = a; iExtraContextSize = aSize; }
/** @internalTechnology */
inline TBool IsDead()
{ return iWaitState.ThreadIsDead(); }
public:
TPriListLink iWaitLink; /**< @internalComponent */ // used to link thread into a wait queue
// TUint8 iBasePri; /**< @internalComponent */ // priority with no fast mutex held
// TUint8 iMutexPri; /**< @internalComponent */ // priority from held fast mutex
// TUint8 iInitial; /**< @internalComponent */ // TRUE if this is an initial thread
TUint8 iLinkedObjType;
TUint8 i_ThrdAttr; /**< @internalComponent */
TUint8 iNThreadBaseSpare10;
TUint8 iFastMutexDefer; /**< @internalComponent */
NFastSemaphore iRequestSemaphore; /**< @internalComponent */
TInt iTime; /**< @internalComponent */ // time remaining, 0 if expired
TInt iTimeslice; /**< @internalComponent */ // timeslice for this thread, -ve = no timeslicing
TLinAddr iSavedSP; /**< @internalComponent */
TAny* iAddressSpace; /**< @internalComponent */
NFastMutex* volatile iHeldFastMutex; /**< @internalComponent */ // fast mutex held by this thread
TUserModeCallback* volatile iUserModeCallbacks; /**< @internalComponent */ // Head of singly-linked list of callbacks
TAny* volatile iLinkedObj; /**< @internalComponent */ // object to which this thread is linked
NThreadGroup* iNewParent; /**< @internalComponent */ // group to join
const SFastExecTable* iFastExecTable; /**< @internalComponent */
const SSlowExecEntry* iSlowExecTable; /**< @internalComponent */ // points to first entry iEntries[0]
volatile TInt iCsCount; /**< @internalComponent */ // critical section count
volatile TInt iCsFunction; /**< @internalComponent */ // what to do on leaving CS: +n=suspend n times, 0=nothing, -1=exit
NThreadWaitState iWaitState; /**< @internalComponent */
const SNThreadHandlers* iHandlers; /**< @internalComponent */ // additional thread event handlers
TInt iSuspendCount; /**< @internalComponent */ // -how many times we have been suspended
TLinAddr iStackBase; /**< @internalComponent */
TInt iStackSize; /**< @internalComponent */
TAny* iExtraContext; /**< @internalComponent */ // parent FPSCR value (iExtraContextSize == -1), coprocessor context (iExtraContextSize > 0) or NULL
TInt iExtraContextSize; /**< @internalComponent */ // +ve=dynamically allocated, 0=none, -1=iExtraContext stores parent FPSCR value
TUint32 iNThreadBaseSpare6; /**< @internalComponent */ // spare to allow growth while preserving BC
TUint32 iNThreadBaseSpare7; /**< @internalComponent */ // spare to allow growth while preserving BC
TUint32 iNThreadBaseSpare8; /**< @internalComponent */ // spare to allow growth while preserving BC
TUint32 iNThreadBaseSpare9; /**< @internalComponent */ // spare to allow growth while preserving BC
// For EMI support - HOPEFULLY THIS CAN DIE
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.
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.
};
__ASSERT_COMPILE(!(_FOFF(NThreadBase,iWaitLink)&7));
__ASSERT_COMPILE(!(sizeof(NThreadBase)&7));
#ifdef __INCLUDE_NTHREADBASE_DEFINES__
#define iReady iSpare1 /**< @internalComponent */
#define iCurrent iSpare2 /**< @internalComponent */
#define iLastCpu iSpare3 /**< @internalComponent */
#define iBasePri iWaitLink.iSpare1 /**< @internalComponent */
#define iMutexPri iWaitLink.iSpare2 /**< @internalComponent */
#define i_NThread_Initial iWaitLink.iSpare3 /**< @internalComponent */
#endif
/** @internalComponent */
#define i_NThread_BasePri iWaitLink.iSpare1
/** @internalComponent */
#define NTHREADBASE_CPU_AFFINITY_MASK 0x80000000
/** @internalComponent */
inline NThreadBase* NThreadWaitState::Thread()
{ return _LOFF(this, NThreadBase, iWaitState); }
/********************************************
* Thread group
********************************************/
/**
@publishedPartner
@prototype
Base class for a nanokernel thread or group
*/
class NThreadGroup : public NSchedulable
{
public:
NThreadGroup();
public:
TInt iThreadCount; /**< @internalComponent */
TPriList<NThreadBase, KNumPriorities> iNThreadList; /**< @internalComponent */
};
/********************************************
* Scheduler
********************************************/
/**
@internalComponent
*/
class TScheduler;
class NThread;
class NIrqHandler;
class TSubScheduler : public TPriListBase
{
public:
TSubScheduler();
void QueueDfcs();
void RotateReadyList(TInt aPriority);
NThread* SelectNextThread();
TBool QueueEvent(NEventHandler* aEvent);
void QueueEventAndKick(NEventHandler* aEvent);
void SaveTimesliceTimer(NThreadBase* aThread);
void UpdateThreadTimes(NThreadBase* aOld, NThreadBase* aNew);
private:
SDblQueLink* iExtraQueues[KNumPriorities-1];
public:
TSpinLock iExIDfcLock; // lock to protect exogenous IDFC queue
SDblQue iExIDfcs; // list of pending exogenous IDFCs (i.e. ones punted over from another CPU)
SDblQue iDfcs; // normal IDFC/DFC pending queue (only accessed by this CPU)
TDfc* volatile iCurrentIDFC; // pointer to IDFC currently running on this CPU
NThread* iCurrentThread; // the thread currently running on this CPU
TUint32 iCpuNum;
TUint32 iCpuMask;
TSpinLock iReadyListLock;
volatile TUint8 iRescheduleNeededFlag; // TRUE if a thread reschedule is pending
TUint8 iSubSchedulerSBZ1; // always zero
volatile TUint8 iDfcPendingFlag; // TRUE if a normal IDFC is pending
volatile TUint8 iExIDfcPendingFlag; // TRUE if an exogenous IDFC is pending
TInt iKernLockCount; // how many times the current CPU has locked the kernel
TUint8 iInIDFC; // TRUE if IDFCs are currently being run on this CPU
volatile TUint8 iEventHandlersPending; // TRUE if an event handler is pending on this CPU
TUint8 iSubSchedulerSpare4;
TUint8 iSubSchedulerSpare5;
TAny* iAddressSpace;
TUint32 iReschedIPIs;
TScheduler* iScheduler;
union
{
TUint64 iLastTimestamp64; // NKern::Timestamp() value at last reschedule or timestamp sync
TUint32 iLastTimestamp32[2];
};
union
{
TUint64 iReschedCount64;
TUint32 iReschedCount32[2];
};
TAny* iExtras[24]; // Space for platform-specific extras
TGenericIPI* iNextIPI; // next generic IPI to run on this CPU
NThread* iInitialThread; // Initial (idle) thread on this CPU
TSpinLock iEventHandlerLock; // lock to protect event handler queue
SDblQue iEventHandlers; // queue of pending event handlers on this CPU
TUint64 iSpinLockOrderCheck; // bitmask showing which spinlock orders currently held
TUint32 iSubSchedulerPadding[8];
};
__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iExIDfcLock)&7));
__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iEventHandlerLock)&7));
__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReadyListLock)&7));
__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iLastTimestamp64)&7));
__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReschedCount64)&7));
__ASSERT_COMPILE(sizeof(TSubScheduler)==512); // make it a nice power of 2 size for easy indexing
/**
@internalComponent
*/
class TScheduler
{
public:
TScheduler();
static void Reschedule();
IMPORT_C static TScheduler* Ptr();
inline void SetProcessHandler(TLinAddr aHandler) {iProcessHandler=aHandler;}
public:
TLinAddr iMonitorExceptionHandler;
TLinAddr iProcessHandler;
TLinAddr iRescheduleHook;
TUint32 iActiveCpus1; // bit n set if CPU n is accepting unlocked threads
TUint32 iActiveCpus2; // bit n set if CPU n is accepting generic IPIs
TInt iNumCpus; // number of CPUs under the kernel's control
TSubScheduler* iSub[KMaxCpus]; // one subscheduler per CPU
TAny* iExtras[24]; // Space for platform-specific extras
NFastMutex iLock; // the 'system lock' fast mutex
TSpinLock iIdleSpinLock; // lock to protect list of DFCs to be run on idle
SDblQue iIdleDfcs; // list of DFCs to run when all CPUs go idle
TUint32 iCpusNotIdle; // bitmask - Bit n set => CPU n is not idle
TUint8 iIdleGeneration; // Toggles between 0 and 1 each time iIdleDfcs list is spilled to a CPU IDFC queue
TUint8 iIdleSpillCpu; // Which CPU last spilled the iIdleDfcs list to its IDFC queue
TUint8 iTSchedulerSpare1;
TUint8 iTSchedulerSpare2;
TUint32 iIdleGenerationCount; // Incremented each time iIdleDfcs list is spilled to a CPU IDFC queue
TUint32 i_Scheduler_Padding[3];
// For EMI support - HOPEFULLY THIS CAN DIE
NThread* iSigma;
TDfc* iEmiDfc;
TUint32 iEmiMask;
TUint32 iEmiState;
TUint32 iEmiDfcTrigger;
TBool iLogging;
TAny* iBufferStart;
TAny* iBufferEnd;
TAny* iBufferTail;
TAny* iBufferHead;
};
__ASSERT_COMPILE(!(_FOFF(TScheduler,iIdleSpinLock)&7));
__ASSERT_COMPILE(sizeof(TScheduler)==512);
extern TScheduler TheScheduler;
extern TSubScheduler TheSubSchedulers[KMaxCpus];
#ifdef __USE_BTRACE_LOCK__
extern TSpinLock BTraceLock;
#define __ACQUIRE_BTRACE_LOCK() TInt _btrace_irq = BTraceLock.LockIrqSave()
#define __RELEASE_BTRACE_LOCK() BTraceLock.UnlockIrqRestore(_btrace_irq)
#else
#define __ACQUIRE_BTRACE_LOCK()
#define __RELEASE_BTRACE_LOCK()
#endif
/**
@internalComponent
*/
extern "C" TSubScheduler& SubScheduler();
/**
@internalComponent
*/
extern "C" void send_resched_ipis(TUint32 aMask);
/**
@internalComponent
*/
extern "C" void send_resched_ipi(TInt aCpu);
/**
@internalComponent
*/
extern "C" void send_resched_ipi_and_wait(TInt aCpu);
#include <nk_plat.h>
/**
Call with kernel locked
@internalComponent
*/
inline void RescheduleNeeded()
{ SubScheduler().iRescheduleNeededFlag = 1; }
/**
@internalComponent
*/
#define NCurrentThread() NKern::CurrentThread()
/** Optimised current thread function which can only be called from places where
CPU migration is not possible - i.e. with interrupts disabled or preemption
disabled.
@internalComponent
*/
extern "C" NThread* NCurrentThreadL();
/** @internalComponent */
inline TBool CheckCpuAgainstAffinity(TInt aCpu, TUint32 aAffinity)
{
if (aAffinity & NTHREADBASE_CPU_AFFINITY_MASK)
return aAffinity & (1<<aCpu);
return aAffinity==(TUint32)aCpu;
}
/**
@internalComponent
*/
#define __NK_ASSERT_UNLOCKED __NK_ASSERT_DEBUG(!NKern::KernelLocked())
/**
@internalComponent
*/
#define __NK_ASSERT_LOCKED __NK_ASSERT_DEBUG(NKern::KernelLocked())
#ifdef _DEBUG
/**
@publishedPartner
@released
*/
#define __ASSERT_NO_FAST_MUTEX __NK_ASSERT_DEBUG(!NKern::HeldFastMutex());
/**
@publishedPartner
@released
*/
#define __ASSERT_FAST_MUTEX(m) __NK_ASSERT_DEBUG((m)->HeldByCurrentThread());
/**
@publishedPartner
@released
*/
#define __ASSERT_SYSTEM_LOCK __NK_ASSERT_DEBUG(TScheduler::Ptr()->iLock.HeldByCurrentThread());
#define __ASSERT_NOT_ISR __NK_ASSERT_DEBUG(NKern::CurrentContext()!=NKern::EInterrupt)
#else
#define __ASSERT_NO_FAST_MUTEX
#define __ASSERT_FAST_MUTEX(m)
#define __ASSERT_SYSTEM_LOCK
#define __ASSERT_NOT_ISR
#endif
/********************************************
* System timer queue
********************************************/
/**
@publishedPartner
@prototype
*/
class NTimerQ
{
friend class NTimer;
public:
typedef void (*TDebugFn)(TAny* aPtr, TInt aPos); /**< @internalComponent */
enum { ETimerQMask=31, ENumTimerQueues=32 }; /**< @internalComponent */ // these are not easily modifiable
/** @internalComponent */
struct STimerQ
{
SDblQue iIntQ;
SDblQue iDfcQ;
};
public:
NTimerQ();
static void Init1(TInt aTickPeriod);
static void Init3(TDfcQue* aDfcQ);
IMPORT_C static TAny* TimerAddress();
IMPORT_C void Tick();
IMPORT_C static TInt IdleTime();
IMPORT_C static void Advance(TInt aTicks);
private:
static void DfcFn(TAny* aPtr);
void Dfc();
void Add(NTimer* aTimer);
void AddFinal(NTimer* aTimer);
public:
STimerQ iTickQ[ENumTimerQueues]; /**< @internalComponent */ // NOTE: the order of member data is important
TUint32 iPresent; /**< @internalComponent */ // The assembler code relies on it
TUint32 iMsCount; /**< @internalComponent */
SDblQue iHoldingQ; /**< @internalComponent */
SDblQue iOrderedQ; /**< @internalComponent */
SDblQue iCompletedQ; /**< @internalComponent */
TDfc iDfc; /**< @internalComponent */
TUint8 iTransferringCancelled; /**< @internalComponent */
TUint8 iCriticalCancelled; /**< @internalComponent */
TUint8 iPad1; /**< @internalComponent */
TUint8 iPad2; /**< @internalComponent */
TDebugFn iDebugFn; /**< @internalComponent */
TAny* iDebugPtr; /**< @internalComponent */
TInt iTickPeriod; /**< @internalComponent */ // in microseconds
/**
This member is intended for use by ASSP/variant interrupt code as a convenient
location to store rounding error information where hardware interrupts are not
exactly one millisecond. The Symbian kernel does not make any use of this member.
@publishedPartner
@prototype
*/
TInt iRounding;
TInt iDfcCompleteCount; /**< @internalComponent */
TSpinLock iTimerSpinLock; /**< @internalComponent */
};
__ASSERT_COMPILE(!(_FOFF(NTimerQ,iTimerSpinLock)&7));
GLREF_D NTimerQ TheTimerQ;
/**
@internalComponent
*/
inline TUint32 NTickCount()
{return TheTimerQ.iMsCount;}
/**
@internalComponent
*/
inline TInt NTickPeriod()
{return TheTimerQ.iTickPeriod;}
extern "C" {
/**
@internalComponent
*/
extern void NKCrashHandler(TInt aPhase, const TAny* a0, TInt a1);
/**
@internalComponent
*/
extern TUint32 CrashState;
}
/**
@internalComponent
*/
class TGenIPIList : public SDblQue
{
public:
TGenIPIList();
public:
TSpinLock iGenIPILock;
};
/**
@internalComponent
*/
class TCancelIPI : public TGenericIPI
{
public:
void Send(TDfc* aDfc, TInt aCpu);
static void Isr(TGenericIPI*);
public:
TDfc* volatile iDfc;
};
/**
@internalComponent
*/
TBool InterruptsStatus(TBool aRequest);
//declarations for the checking of kernel preconditions
/**
@internalComponent
PRECOND_FUNCTION_CALLER is needed for __ASSERT_WITH_MESSAGE_ALWAYS(),
so is outside the #ifdef _DEBUG.
*/
#ifndef PRECOND_FUNCTION_CALLER
#define PRECOND_FUNCTION_CALLER 0
#endif
#ifdef _DEBUG
/**
@internalComponent
*/
#define MASK_NO_FAST_MUTEX 0x1
#define MASK_CRITICAL 0x2
#define MASK_NO_CRITICAL 0x4
#define MASK_KERNEL_LOCKED 0x8
#define MASK_KERNEL_UNLOCKED 0x10
#define MASK_KERNEL_LOCKED_ONCE 0x20
#define MASK_INTERRUPTS_ENABLED 0x40
#define MASK_INTERRUPTS_DISABLED 0x80
#define MASK_SYSTEM_LOCKED 0x100
#define MASK_NOT_ISR 0x400
#define MASK_NOT_IDFC 0x800
#define MASK_NOT_THREAD 0x1000
#define MASK_NO_CRITICAL_IF_USER 0x2000
#define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
#define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
#define MASK_ALWAYS_FAIL 0x4000
#define MASK_NO_RESCHED 0x8000
#if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
#define CHECK_PRECONDITIONS(mask,function)
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function)
#else
/**
@internalComponent
*/
extern "C" TInt CheckPreconditions(TUint32 aConditionMask, const char* aFunction, TLinAddr aAddr);
/**
@internalComponent
*/
#define CHECK_PRECONDITIONS(mask,function) CheckPreconditions(mask,function,PRECOND_FUNCTION_CALLER)
#ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
/**
@internalComponent
*/
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
__ASSERT_DEBUG( (cond), ( \
DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
NKFault(function, 0)))
#else//!__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
/**
@internalComponent
*/
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function) \
__ASSERT_DEBUG( (cond), \
DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
#endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
#endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
#else//if !DEBUG
#define CHECK_PRECONDITIONS(mask,function)
#define __ASSERT_WITH_MESSAGE_DEBUG(cond,message,function )
#endif//_DEBUG
#if (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function )
#else
#ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
/**
@internalComponent
*/
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
__ASSERT_ALWAYS( (cond), ( \
DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER),\
NKFault(function, 0)))
#else
/**
@internalComponent
*/
#define __ASSERT_WITH_MESSAGE_ALWAYS(cond,message,function) \
__ASSERT_ALWAYS( (cond), \
DEBUGPRINT("Assertion failed: %s\nFunction: %s; called from: %08x\n",message,function,PRECOND_FUNCTION_CALLER))
#endif//__KERNEL_APIS_CONTEXT_CHECKS_FAULT__
#endif//(!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
#endif