1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/nkern/dfcs.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,238 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\include\nkern\dfcs.h
1.18 +//
1.19 +// WARNING: This file contains some APIs which are internal and are subject
1.20 +// to change without notice. Such APIs should therefore not be used
1.21 +// outside the Kernel and Hardware Services package.
1.22 +//
1.23 +
1.24 +#ifndef __DFCS_H__
1.25 +#define __DFCS_H__
1.26 +
1.27 +#include <nklib.h>
1.28 +
1.29 +class NThreadBase;
1.30 +class NThread;
1.31 +class NFastSemaphore;
1.32 +class NFastMutex;
1.33 +
1.34 +/********************************************
1.35 + * Delayed function call queue
1.36 + ********************************************/
1.37 +
1.38 +/**
1.39 +@publishedPartner
1.40 +@released
1.41 +
1.42 +The number of DFC priorities the system has, which range from 0
1.43 +to KNumDfcPriorities - 1.
1.44 +*/
1.45 +const TInt KNumDfcPriorities=8;
1.46 +
1.47 +/**
1.48 +@publishedPartner
1.49 +@released
1.50 +
1.51 +The highest priority level for a DFC, which is equal to KNumDfcPriorities + 1.
1.52 +*/
1.53 +const TInt KMaxDfcPriority=KNumDfcPriorities-1;
1.54 +
1.55 +class TDfc;
1.56 +/**
1.57 +@publishedPartner
1.58 +@released
1.59 +
1.60 +Defines a DFC queue.
1.61 +
1.62 +Each DFC queue is associated with a thread.
1.63 +
1.64 +@see TDfc
1.65 +*/
1.66 +class TDfcQue : public TPriList<TDfc,KNumDfcPriorities>
1.67 + {
1.68 +public:
1.69 + IMPORT_C TDfcQue();
1.70 +
1.71 + inline TBool IsEmpty(); /**< @internalComponent */
1.72 + static void ThreadFunction(TAny* aDfcQ);
1.73 +public:
1.74 + NThreadBase* iThread; /**< @internalComponent */
1.75 + };
1.76 +
1.77 +/**
1.78 +@internalComponent
1.79 +*/
1.80 +inline TBool TDfcQue::IsEmpty()
1.81 + { return (iPresent[0]==0); }
1.82 +
1.83 +/********************************************
1.84 + * Delayed function call
1.85 + ********************************************/
1.86 +
1.87 +/**
1.88 +@publishedPartner
1.89 +@released
1.90 +
1.91 +The function type that can be set to run as a DFC or IDFC.
1.92 +
1.93 +@see TDfc
1.94 +*/
1.95 +typedef void (*TDfcFn)(TAny*);
1.96 +
1.97 +/**
1.98 +@publishedPartner
1.99 +@released
1.100 +
1.101 +Defines a Deferred Function Call (DFC) or Immediate Deferred Function Call (IDFC).
1.102 +
1.103 +A DFC is a kernel object that specifies a function to be run in a thread,
1.104 +which is processing a DFC queue. A DFC is added to a DFC queue that is
1.105 +associated with a given thread, where it is cooperatively scheduled with other
1.106 +DFCs on that queue. Queued DFCs are run in order of their priority, followed
1.107 +by the order they where queued. When the DFC gets to run, the function is run
1.108 +kernel side, and no other DFC in this queue will get to run until it
1.109 +completes. A DFC can be queued from any context.
1.110 +
1.111 +An IDFC is run as soon as the scheduler is next run, which is during the IRQ
1.112 +postamble if queued from an ISR; when the currently-running IDFC completes if
1.113 +queued from an IDFC; or when the kernel is next unlocked if queued from thread
1.114 +context. Unlike a DFC, the IDFC is not run from a thread context, and its
1.115 +execution time must be much smaller. For these reasons, IDFCs are rarely used
1.116 +directly, but are used for implementation of the kernel and RTOS personality
1.117 +layers. An important use of IDFCs is in the implementation of queuing DFCs from
1.118 +an ISR context. IDFCs are run with interrupts enabled but the kernel locked.
1.119 +*/
1.120 +class TDfc : public TPriListLink
1.121 + {
1.122 + // iPriority<KNumDfcPriorities => DFC, otherwise IDFC
1.123 + // iSpare2!=0 if on final queue, 0 if not queued or on pending queue
1.124 + // iSpare3!=0 if on pending or final queue, 0 if not queued
1.125 +public:
1.126 + IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr); // create IDFC
1.127 + IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TInt aPriority); // create DFC, queue to be set later
1.128 + IMPORT_C TDfc(TDfcFn aFunction, TAny* aPtr, TDfcQue* aDfcQ, TInt aPriority); // create DFC
1.129 + IMPORT_C TBool Add(); // call from ISR or IDFC or thread with kernel locked
1.130 + IMPORT_C TBool Cancel(); // call from anywhere except ISR
1.131 + IMPORT_C TBool Enque(); // call from thread
1.132 + IMPORT_C TBool Enque(NFastMutex* aMutex); // call from thread, signal fast mutex (anti-thrash)
1.133 + IMPORT_C TBool DoEnque(); // call from IDFC or thread with kernel locked
1.134 + IMPORT_C TBool RawAdd(); // same as Add() but without checks for 'correct' usage or other instrumentation
1.135 + IMPORT_C TBool QueueOnIdle(); // queue the DFC to be run when the system goes idle
1.136 + IMPORT_C NThreadBase* Thread(); // thread on which DFC runs, NULL for IDFC
1.137 + void DoEnqueFinal();
1.138 + inline TBool Queued();
1.139 + inline TBool IsIDFC();
1.140 + inline TBool TestAndSetQueued(); /**< @internalComponent */
1.141 + inline void SetDfcQ(TDfcQue* aDfcQ);
1.142 + inline void SetFunction(TDfcFn aDfcFn);
1.143 + inline void SetPriority(TInt aPriority); /**< @internalComponent */
1.144 +public:
1.145 + TAny* iPtr; /**< @internalComponent */
1.146 + TDfcFn iFunction; /**< @internalComponent */
1.147 + TDfcQue *iDfcQ; /**< @internalComponent */
1.148 + };
1.149 +
1.150 +/**
1.151 +@publishedPartner
1.152 +@released
1.153 +
1.154 +Used to find out if the DFC/IDFC is queued on either the pending or final DFC queue.
1.155 +
1.156 +@return TRUE if the DFC/IDFC is queued, otherwise FALSE.
1.157 +
1.158 +*/
1.159 +inline TBool TDfc::Queued()
1.160 + { return iSpare3; }
1.161 +
1.162 +/**
1.163 +@publishedPartner
1.164 +@released
1.165 +
1.166 +Determines if the object represents a DFC or an IDFC.
1.167 +
1.168 +@return TRUE if this represents an IDFC, otherwise FALSE meaning it is a DFC.
1.169 +*/
1.170 +inline TBool TDfc::IsIDFC()
1.171 + { return iPriority>=KNumDfcPriorities; }
1.172 +
1.173 +/**
1.174 +@publishedPartner
1.175 +@released
1.176 +
1.177 +Sets the DFC queue that the DFC is to added to and executed by.
1.178 +
1.179 +Note that this function should only be used in the initialisation of the DFC,
1.180 +when it is not on any queue. This function does not move the DFC from one
1.181 +queue to another.
1.182 +
1.183 +@param aDfcQ
1.184 +
1.185 + The DFC queue that the DFC is to be added to and executed by.
1.186 +
1.187 +*/
1.188 +inline void TDfc::SetDfcQ(TDfcQue* aDfcQ)
1.189 + { iDfcQ=aDfcQ; }
1.190 +
1.191 +/**
1.192 +@publishedPartner
1.193 +@released
1.194 +
1.195 +Sets the function that is run when the DFC/IDFC is scheduled.
1.196 +
1.197 +@param aDfcFn
1.198 +
1.199 + The function that the DFC/IDFC runs when it is scheduled.
1.200 +
1.201 +*/
1.202 +inline void TDfc::SetFunction(TDfcFn aDfcFn)
1.203 + { iFunction=aDfcFn; }
1.204 +
1.205 +/**
1.206 +@internalComponent
1.207 +*/
1.208 +inline void TDfc::SetPriority(TInt aPriority)
1.209 + { iPriority = (TUint8)aPriority; }
1.210 +
1.211 +#ifdef __INCLUDE_TDFC_DEFINES__
1.212 +#define iOnFinalQ iSpare2
1.213 +#define iQueued iSpare3
1.214 +#endif
1.215 +
1.216 +
1.217 +/********************************************
1.218 + * Kernel-side asynchronous request,
1.219 + * based on DFC queueing
1.220 + ********************************************/
1.221 +
1.222 +class TAsyncRequest : protected TDfc
1.223 + {
1.224 +public:
1.225 + IMPORT_C void Send(TDfc* aCompletionDfc);
1.226 + IMPORT_C void Send(NFastSemaphore* aCompletionSemaphore);
1.227 + IMPORT_C TInt SendReceive();
1.228 + IMPORT_C void Cancel();
1.229 + IMPORT_C void Complete(TInt aResult);
1.230 + inline TBool PollForCancel()
1.231 + { return iCancel; }
1.232 +protected:
1.233 + IMPORT_C TAsyncRequest(TDfcFn aFunction, TDfcQue* aDfcQ, TInt aPriority);
1.234 +protected:
1.235 + TAny* iCompletionObject;
1.236 + volatile TBool iCancel;
1.237 + TInt iResult;
1.238 + };
1.239 +
1.240 +
1.241 +#endif