|
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 |