kernel/eka/include/nkern/dfcs.h
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     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\dfcs.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 __DFCS_H__
       
    22 #define __DFCS_H__
       
    23 
       
    24 #include <nklib.h>
       
    25 
       
    26 class NThreadBase;
       
    27 class NThread;
       
    28 class NFastSemaphore;
       
    29 class NFastMutex;
       
    30 
       
    31 /********************************************
       
    32  * Delayed function call queue
       
    33  ********************************************/
       
    34 
       
    35 /**
       
    36 @publishedPartner
       
    37 @released
       
    38 
       
    39 The number of DFC priorities the system has, which range from 0
       
    40 to KNumDfcPriorities - 1.
       
    41 */
       
    42 const TInt KNumDfcPriorities=8;
       
    43 
       
    44 /**
       
    45 @publishedPartner
       
    46 @released
       
    47 
       
    48 The highest priority level for a DFC, which is equal to KNumDfcPriorities + 1.
       
    49 */
       
    50 const TInt KMaxDfcPriority=KNumDfcPriorities-1;
       
    51 
       
    52 class TDfc;
       
    53 /**
       
    54 @publishedPartner
       
    55 @released
       
    56 
       
    57 Defines a DFC queue.
       
    58 
       
    59 Each DFC queue is associated with a thread.
       
    60 
       
    61 @see TDfc
       
    62 */
       
    63 class TDfcQue : public TPriList<TDfc,KNumDfcPriorities>
       
    64 	{
       
    65 public:
       
    66 	IMPORT_C TDfcQue();
       
    67 
       
    68 	inline TBool IsEmpty();		/**< @internalComponent */
       
    69 	static void ThreadFunction(TAny* aDfcQ);
       
    70 public:
       
    71 	NThreadBase* iThread;		/**< @internalComponent */
       
    72 	};
       
    73 
       
    74 /**
       
    75 @internalComponent
       
    76 */
       
    77 inline TBool TDfcQue::IsEmpty()
       
    78 	{ return (iPresent[0]==0); }
       
    79 
       
    80 /********************************************
       
    81  * Delayed function call
       
    82  ********************************************/
       
    83 
       
    84 /**
       
    85 @publishedPartner
       
    86 @released
       
    87 
       
    88 The function type that can be set to run as a DFC or IDFC.
       
    89 
       
    90 @see TDfc
       
    91 */
       
    92 typedef void (*TDfcFn)(TAny*);
       
    93 
       
    94 /**
       
    95 @publishedPartner
       
    96 @released
       
    97 
       
    98 Defines a Deferred Function Call (DFC) or Immediate Deferred Function Call (IDFC).
       
    99 
       
   100 A DFC is a kernel object that specifies a function to be run in a thread,
       
   101 which is processing a DFC queue. A DFC is added to a DFC queue that is 
       
   102 associated with a given thread, where it is cooperatively scheduled with other
       
   103 DFCs on that queue.  Queued DFCs are run in order of their priority, followed
       
   104 by the order they where queued.  When the DFC gets to run, the function is run
       
   105 kernel side, and no other DFC in this queue will get to run until it 
       
   106 completes. A DFC can be queued from any context.
       
   107 
       
   108 An IDFC is run as soon as the scheduler is next run, which is during the IRQ
       
   109 postamble if queued from an ISR; when the currently-running IDFC completes if
       
   110 queued from an IDFC; or when the kernel is next unlocked if queued from thread
       
   111 context.  Unlike a DFC, the IDFC is not run from a thread context, and its
       
   112 execution time must be much smaller.  For these reasons, IDFCs are rarely used
       
   113 directly, but are used for implementation of the kernel and RTOS personality
       
   114 layers.  An important use of IDFCs is in the implementation of queuing DFCs from
       
   115 an ISR context.  IDFCs are run with interrupts enabled but the kernel locked.
       
   116 */
       
   117 class TDfc : public TPriListLink
       
   118 	{
       
   119 	// iPriority<KNumDfcPriorities => DFC, otherwise IDFC
       
   120 	// iSpare2!=0 if on final queue, 0 if not queued or on pending queue
       
   121 	// iSpare3!=0 if on pending or final queue, 0 if not queued
       
   122 public:
       
   123 	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr);									// create IDFC
       
   124 	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TInt aPriority);					// create DFC, queue to be set later
       
   125 	IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority);	// create DFC
       
   126 	IMPORT_C TBool Add();						// call from ISR or IDFC or thread with kernel locked
       
   127 	IMPORT_C TBool Cancel();					// call from anywhere except ISR
       
   128 	IMPORT_C TBool Enque();						// call from thread
       
   129 	IMPORT_C TBool Enque(NFastMutex* aMutex);	// call from thread, signal fast mutex (anti-thrash)
       
   130 	IMPORT_C TBool DoEnque();					// call from IDFC or thread with kernel locked
       
   131 	IMPORT_C TBool RawAdd();					// same as Add() but without checks for 'correct' usage or other instrumentation
       
   132 	IMPORT_C TBool QueueOnIdle();				// queue the DFC to be run when the system goes idle
       
   133 	IMPORT_C NThreadBase* Thread();				// thread on which DFC runs, NULL for IDFC
       
   134 	void DoEnqueFinal();
       
   135 	inline TBool Queued();
       
   136 	inline TBool IsIDFC();
       
   137 	inline TBool TestAndSetQueued();			/**< @internalComponent */
       
   138 	inline void SetDfcQ(TDfcQue* aDfcQ);
       
   139 	inline void SetFunction(TDfcFn aDfcFn);
       
   140 	inline void SetPriority(TInt aPriority);	/**< @internalComponent */
       
   141 public:
       
   142 	TAny* iPtr;			/**< @internalComponent */
       
   143 	TDfcFn iFunction;	/**< @internalComponent */
       
   144 	TDfcQue *iDfcQ;		/**< @internalComponent */
       
   145 	};
       
   146 
       
   147 /**
       
   148 @publishedPartner
       
   149 @released
       
   150 
       
   151 Used to find out if the DFC/IDFC is queued on either the pending or final DFC queue.
       
   152 
       
   153 @return TRUE if the DFC/IDFC is queued, otherwise FALSE.
       
   154 
       
   155 */
       
   156 inline TBool TDfc::Queued()
       
   157 	{ return iSpare3; }
       
   158 
       
   159 /**
       
   160 @publishedPartner
       
   161 @released
       
   162 
       
   163 Determines if the object represents a DFC or an IDFC.
       
   164 
       
   165 @return TRUE if this represents an IDFC, otherwise FALSE meaning it is a DFC.
       
   166 */
       
   167 inline TBool TDfc::IsIDFC()
       
   168 	{ return iPriority>=KNumDfcPriorities; }
       
   169 
       
   170 /**
       
   171 @publishedPartner
       
   172 @released
       
   173 
       
   174 Sets the DFC queue that the DFC is to added to and executed by.
       
   175 
       
   176 Note that this function should only be used in the initialisation of the DFC, 
       
   177 when it is not on any queue.  This function does not move the DFC from one 
       
   178 queue to another.
       
   179 
       
   180 @param aDfcQ
       
   181 
       
   182 	The DFC queue that the DFC is to be added to and executed by.
       
   183 
       
   184 */
       
   185 inline void TDfc::SetDfcQ(TDfcQue* aDfcQ)
       
   186 	{ iDfcQ=aDfcQ; }
       
   187 
       
   188 /**
       
   189 @publishedPartner
       
   190 @released
       
   191 
       
   192 Sets the function that is run when the DFC/IDFC is scheduled.
       
   193 
       
   194 @param aDfcFn
       
   195 
       
   196 	The function that the DFC/IDFC runs when it is scheduled.
       
   197 
       
   198 */
       
   199 inline void TDfc::SetFunction(TDfcFn aDfcFn)
       
   200 	{ iFunction=aDfcFn; }
       
   201 
       
   202 /**
       
   203 @internalComponent
       
   204 */
       
   205 inline void TDfc::SetPriority(TInt aPriority)
       
   206 	{ iPriority = (TUint8)aPriority; }
       
   207 
       
   208 #ifdef __INCLUDE_TDFC_DEFINES__
       
   209 #define	iOnFinalQ		iSpare2
       
   210 #define	iQueued			iSpare3
       
   211 #endif
       
   212 
       
   213 
       
   214 /********************************************
       
   215  * Kernel-side asynchronous request,
       
   216  * based on DFC queueing
       
   217  ********************************************/
       
   218 
       
   219 class TAsyncRequest : protected TDfc
       
   220 	{
       
   221 public:
       
   222 	IMPORT_C void Send(TDfc* aCompletionDfc);
       
   223 	IMPORT_C void Send(NFastSemaphore* aCompletionSemaphore);
       
   224 	IMPORT_C TInt SendReceive();
       
   225 	IMPORT_C void Cancel();
       
   226 	IMPORT_C void Complete(TInt aResult);
       
   227 	inline TBool PollForCancel()
       
   228 		{ return iCancel; }
       
   229 protected:
       
   230 	IMPORT_C TAsyncRequest(TDfcFn aFunction, TDfcQue* aDfcQ, TInt aPriority);
       
   231 protected:
       
   232 	TAny*	iCompletionObject;
       
   233 	volatile TBool	iCancel;
       
   234 	TInt	iResult;
       
   235 	};
       
   236 
       
   237 
       
   238 #endif