• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /*! \addtogroup osclproc OSCL Proc
19  *
20  * @{
21  */
22 
23 
24 
25 /** \file pvscheduler.h
26     \brief Main include file for Oscl Scheduler
27 */
28 
29 
30 #ifndef OSCL_SCHEDULER_H_INCLUDED
31 #define OSCL_SCHEDULER_H_INCLUDED
32 
33 #ifndef OSCL_SCHEDULER_TYPES_H_INCLUDED
34 #include "oscl_scheduler_types.h"
35 #endif
36 
37 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED
38 #include "oscl_scheduler_ao.h"
39 #endif
40 
41 #ifndef OSCL_SCHEDULER_THREADCONTEXT_H_INCLUDED
42 #include "oscl_scheduler_threadcontext.h"
43 #endif
44 
45 #ifndef OSCL_MUTEX_H_INCLUDED
46 #include "oscl_mutex.h"
47 #endif
48 
49 #ifndef OSCL_SEMAPHORE_H_INCLUDED
50 #include "oscl_semaphore.h"
51 #endif
52 
53 #ifndef OSCL_SCHEDULER_READYQ_H_INCLUDED
54 #include "oscl_scheduler_readyq.h"
55 #endif
56 
57 #ifndef OSCL_DEFALLOC_H_INCLUDED
58 #include "oscl_defalloc.h"
59 #endif
60 
61 #ifndef OSCL_MEM_H_INCLUDED
62 #include "oscl_mem.h"
63 #endif
64 
65 class Oscl_DefAlloc;
66 class OsclCoeActiveScheduler;
67 
68 
69 /**
70  * Per-thread scheduler initialization and cleanup.
71  */
72 class OsclScheduler
73 {
74     public:
75         /**
76          * This routine creates and installs a scheduler in
77          * the calling thread.
78          * @param name: (input param) scheduler name.
79          * @param alloc: (input param) optional allocator to use for
80          *   the internal implementation.
81          * @param nreserve: (input param) optional value for ready queue
82          *   reserve size.
83          */
84         OSCL_IMPORT_REF static void Init(const char *name, Oscl_DefAlloc *alloc = NULL, int nreserve = 20);
85 
86 
87         /**
88          * This routine uninstalls and destroys Oscl scheduler
89          * for the calling thread.
90          */
91         OSCL_IMPORT_REF static void Cleanup();
92 };
93 
94 
95 /**
96  * PV Scheduler class
97  */
98 
99 #define PVSCHEDNAMELEN 30
100 
101 class PVSchedulerStopper;
102 class PVJump;
103 class PVLogger;
104 
105 /**
106  * OsclSchedulerObserver is an observer class for use when running scheduler
107  * in non-blocking mode.
108  * The scheduler observer can register for callbacks so it
109  * will be notified when it is necessary to run scheduler again.
110  * Note: non-blocking mode and scheduler callbacks are not supported on Symbian.
111  */
112 class OsclSchedulerObserver
113 {
114     public:
115         /**
116          * OsclSchedulerTimerCallback is called when the front of the timer queue
117          * is updated.  This means the minimum delay has changed and scheduler needs
118          * to be run again after aDelayMsec.  Calling context is in-thread.
119          *
120          * The current observer is cleared before making the callback, so the
121          * observer must call RegisterForCallback again if it wants further
122          * notifications.
123          */
124         virtual void OsclSchedulerTimerCallback(OsclAny* aContext, uint32 aDelayMsec) = 0;
125 
126         /**
127          * OsclSchedulerReadyCallback is called when the ready queue is updated, meaning
128          * an AO is ready to run.  Scheduler needs to be run ASAP.
129          * Calling context may be any thread, so be careful!
130          *
131          * The current observer is cleared before making the callback, so the
132          * observer must call RegisterForCallback again if it wants further
133          * notifications.
134          */
135         virtual void OsclSchedulerReadyCallback(OsclAny* aContext) = 0;
136 
~OsclSchedulerObserver()137         virtual ~OsclSchedulerObserver() {}
138 };
139 
140 
141 /*
142 ** A common base class for variations of OsclExecScheduler
143 **/
144 
145 class OsclExecSchedulerCommonBase
146 {
147     public:
148         /**
149          * Start scheduling.  This call blocks until scheduler
150          * is stopped or an error occurs.
151          * @param sem: optional startup semaphore.  If provied,
152          *    the scheduler will signal this semaphore when
153          *    the startup has progressed to the point that it's
154          *    safe to call StopScheduler or SuspendScheduler
155          *    from another thread.
156          */
157         OSCL_IMPORT_REF void StartScheduler(OsclSemaphore *sem = NULL);
158 
159         /**
160          * Stop scheduling.  This API may be called from the
161          * scheduling thread or some other thread.
162          */
163         OSCL_IMPORT_REF void StopScheduler();
164 
165         /**
166          * Suspend scheduling when the current Run is complete.
167          * This API only applies to a blocking loop scheduler.
168          */
169         OSCL_IMPORT_REF void SuspendScheduler();
170 
171         /**
172          * Resume scheduling immediately.
173          * This API only applies to a blocking loop scheduler.
174          */
175         OSCL_IMPORT_REF void ResumeScheduler();
176 
177         /**
178          * Start the OS native scheduling loop.  This is an alternative
179          * to the PV scheduling loop.
180          * To stop the native scheduler, use the StopScheduler API.
181          */
182         OSCL_IMPORT_REF void StartNativeScheduler();
183 
184         /**
185          * Get name of scheduler for current thread.
186          */
187         OSCL_IMPORT_REF static OsclNameString<PVSCHEDNAMELEN> *GetName();
188 
189         /**
190          * Get numeric ID of current thread.
191          */
192         OSCL_IMPORT_REF static uint32 GetId();
193 
194 
195     protected:
196         /*
197         static OsclExecScheduler *NewL(const char *name,Oscl_DefAlloc *a,int nreserve);
198         */
199         virtual ~OsclExecSchedulerCommonBase();
200         void InstallScheduler();
201         void UninstallScheduler();
202         friend class OsclScheduler;
203 
204     protected:
205         void Error(int32 anError) const;
206 
207     protected:
208         static OsclExecSchedulerCommonBase* GetScheduler();
209         static OsclExecSchedulerCommonBase* SetScheduler(OsclExecSchedulerCommonBase*);
210         friend class PVThreadContext;
211         friend class OsclCoeActiveScheduler;
212 
213     protected:
214         OsclExecSchedulerCommonBase(Oscl_DefAlloc*);
215         virtual void ConstructL(const char *name, int);
216 
217         void BeginScheduling(bool blocking, bool native);
218         void EndScheduling();
219 
220         void BlockingLoopL();
221 
222         bool iBlockingMode;//current blocking mode setting.
223         bool iNativeMode;//current native mode setting.
224 
225         bool IsStarted();
226         inline bool IsInstalled();
227 
228         //Stopper AO is a special PV AO used to implement
229         //the StopScheduler and SuspendScheduler functions.
230         PVSchedulerStopper *iStopper;
231         OsclNoYieldMutex iStopperCrit;
232 
233         //Scheduler thread context
234         PVThreadContext iThreadContext;
235 
236         //Scheduler name
237         OsclNameString<PVSCHEDNAMELEN> iName;
238 
239         //For stop, suspend, and resume commands.
240         bool iDoStop;
241         bool iDoSuspend;
242         bool iSuspended;
243         OsclSemaphore iResumeSem;
244 
245         OsclErrorTrapImp* iErrorTrapImp;
246 
247         //Ready AO queue.  The AOs in this queue are ready to run.
248         OsclReadyQ iReadyQ;
249 
250         //Pending Timer AO queue.  The AOs in this queue are OsclTimerObjects
251         //and have a timeout pending.
252         OsclTimerQ iExecTimerQ;
253         void AddToExecTimerQ(PVActiveBase *active, uint32);
254 
255         void PendComplete(PVActiveBase *, int32 aReason, TPVThreadContext aContext);
256         void RequestCanceled(PVActiveBase*);
257 
258         //Scheduling loop implementation.
259         PVActiveBase* UpdateTimers(uint32 &aDelay);
260         PVActiveBase* UpdateTimersMsec(uint32 &aDelay);
261         PVActiveBase* WaitForReadyAO();
262         void CallRunExec(PVActiveBase*);
263 
264         static const uint32 iTimeCompareThreshold;
265         friend class OsclTimerCompare;
266         friend class OsclReadyQ;
267 
268         friend class OsclError;
269 
270 
271 
272         uint32 iNumAOAdded;//for non-fair-scheduling sorts.
273 
274         //For statistics
275 #if (PV_SCHED_ENABLE_AO_STATS)
276         OsclDoubleList<PVActiveStats> iPVStatQ;//queue of all PV ExecObjs.
277         enum TOtherExecStats
278         {
279             EOtherExecStats_WaitTime //scheduler wait time
280             , EOtherExecStats_QueueTime //scheduler queue operation time
281             , EOtherExecStats_NativeOS //time in symbian native ExecObjs, not added by PV code (symbian only)
282             , EOtherExecStats_ReleaseTime //thread release time (Brew only)
283             , EOtherExecStats_Last
284         };
285         PVActiveStats* iOtherExecStats[EOtherExecStats_Last];//placeholder for stats of all ExecObjs.
286         void ConstructStatQ();
287         void BeginStats();
288         void EndStats();
289         static void ShowStats(PVActiveStats *active);
290         static void ShowSummaryStats(PVActiveStats *active, PVLogger*, int64, int64&, float&);
291         void CleanupStatQ();
292         uint8* iTotalTicksTemp;
293         int64 iGrandTotalTicks;
294         float iTotalPercent;
295         friend class PVActiveStats;
296         uint32 iTime;
297         int32 iDelta;
298         PVActiveStats* iPVStats;
299 #endif //PV_SCHED_ENABLE_AO_STATS
300 
301         //Queue utils.
302         PVActiveBase *FindPVBase(PVActiveBase *active, OsclDoubleList<PVActiveBase> &);
303         void CleanupExecQ();
304         void InitExecQ(int);
305 
306         PVLogger *iLogger;
307         PVLogger* iDebugLogger;
308 
309 #if(PV_SCHED_ENABLE_PERF_LOGGING)
310         //for perf logging
311         char* iLogPerfIndentStr;
312         int32 iLogPerfIndentStrLen;
313         uint32 iLogPerfTotal;
314         void ResetLogPerf();
315         void IncLogPerf(uint32);
316 #endif
317 
318         Oscl_DefAlloc *iAlloc;//allocator for scheduler.
319         // iDefAlloc is static because we need it to still be valid after ~OsclExecSchedulerCommonBase is called */
320         static OsclMemAllocator iDefAlloc;//default allocator
321 
322         friend class OsclActiveObject;
323         friend class OsclTimerObject;
324         friend class PVActiveBase;
325         friend class PVSchedulerStopper;
326 
327 
328         friend class OsclExecScheduler;
329 };
330 
331 class OsclErrorTrapImp;
332 
333 class OsclExecScheduler: public OsclExecSchedulerCommonBase
334         , public OsclExecSchedulerBase
335 {
336     public:
337         /**
338          * Get currently installed scheduler for calling thread,
339          * or NULL if no scheduler is installed.
340          */
341         OSCL_IMPORT_REF static OsclExecScheduler* Current();
342 
343         /**
344          * Non-Blocking scheduler APIs.
345          */
346 
347         /**
348          * Run PV scheduler in non-blocking mode.  This call returns
349          * when the desired number of Run calls have been made,
350          * or when there are no more active objects that are ready
351          * to run.
352          *
353          * @param aTargetCount: (input param) the maximum number of Run calls to make.
354          * @param aReady: (output param) tells the number of active objects that
355          *    are currently ready to run.
356          * @param aDelayMsec: (output param) If no active objects are ready to
357          *   run, but one or more active objects are waiting on timers, this
358          *   parameter will tell the time interval from the current time until the
359          *   first of the pending timer objects will be ready to run, in milliseconds.
360          *
361          * Note: On Symbian, non-blocking mode is not supported and this call will
362          *  leave.
363          *
364          */
365         OSCL_IMPORT_REF void RunSchedulerNonBlocking(int32 aTargetCount, int32 &aReady, uint32 &aDelayMsec);
366 
367         /**
368          * Register for a notification when non-blocking scheduler needs to run
369          * again.
370          *
371          * Note: On Symbian, non-blocking mode is not supported and this call will
372          *  leave.
373          */
374         OSCL_IMPORT_REF void RegisterForCallback(OsclSchedulerObserver* aCallback, OsclAny* aCallbackContext);
375 
376 
377     private:
378         static OsclExecScheduler *NewL(const char *name, Oscl_DefAlloc *a, int nreserve);
379         ~OsclExecScheduler();
380         friend class OsclScheduler;
381 
382 
383         OsclExecScheduler(Oscl_DefAlloc*);
384         void ConstructL(const char *name, int);
385 
386 };
387 
388 
389 /**
390  * Scheduler stopper AO class, for internal use
391  * by scheduler.
392  */
393 class PVSchedulerStopper: public OsclActiveObject
394 {
395     public:
396         PVSchedulerStopper();
397         ~PVSchedulerStopper();
398     private:
399         void Run();
400 };
401 
402 
403 #endif
404 
405 
406 /*! @} */
407