include/nucleus/pod.h

Go to the documentation of this file.
00001 
00028 #ifndef _XENO_NUCLEUS_POD_H
00029 #define _XENO_NUCLEUS_POD_H
00030 
00034 #include <nucleus/thread.h>
00035 #include <nucleus/intr.h>
00036 
00037 /* Creation flags */
00038 #define XNREUSE  0x00000001     /* Reuse pod with identical properties */
00039 
00040 /* Pod status flags */
00041 #define XNRPRIO  0x00000002     /* Reverse priority scheme */
00042 #define XNTIMED  0x00000004     /* Timer started */
00043 #define XNTMSET  0x00000008     /* Pod time has been set */
00044 #define XNTMPER  0x00000010     /* Periodic timing */
00045 #define XNFATAL  0x00000020     /* Pod encountered a fatal error */
00046 #define XNPIDLE  0x00000040     /* Pod is unavailable (initializing/shutting down) */
00047 #define XNTLOCK  0x00000080     /* Timer lock pending */
00048 
00049 /* Sched status flags */
00050 #define XNKCOUT  0x80000000     /* Sched callout context */
00051 #define XNHTICK  0x40000000     /* Host tick pending  */
00052 
00053 /* These flags are available to the real-time interfaces */
00054 #define XNPOD_SPARE0  0x01000000
00055 #define XNPOD_SPARE1  0x02000000
00056 #define XNPOD_SPARE2  0x04000000
00057 #define XNPOD_SPARE3  0x08000000
00058 #define XNPOD_SPARE4  0x10000000
00059 #define XNPOD_SPARE5  0x20000000
00060 #define XNPOD_SPARE6  0x40000000
00061 #define XNPOD_SPARE7  0x80000000
00062 
00063 /* Flags for context checking */
00064 #define XNPOD_THREAD_CONTEXT     0x1    /* Regular thread */
00065 #define XNPOD_INTERRUPT_CONTEXT  0x2    /* Interrupt service thread */
00066 #define XNPOD_HOOK_CONTEXT       0x4    /* Nanokernel hook */
00067 #define XNPOD_ROOT_CONTEXT       0x8    /* Root thread */
00068 
00069 #define XNPOD_NORMAL_EXIT  0x0
00070 #define XNPOD_FATAL_EXIT   0x1
00071 
00072 #define XNPOD_DEFAULT_TICKHANDLER  (&xnpod_announce_tick)
00073 
00074 #define XNPOD_ALL_CPUS  XNARCH_CPU_MASK_ALL
00075 
00076 #define XNPOD_HEAPSIZE  (CONFIG_XENO_OPT_SYS_HEAPSZ * 1024)
00077 #define XNPOD_PAGESIZE  512
00078 #define XNPOD_RUNPRIO   0x80000000      /* Placeholder for "stdthread priority" */
00079 
00080 /* Flags for xnpod_schedule_runnable() */
00081 #define XNPOD_SCHEDFIFO 0x0
00082 #define XNPOD_SCHEDLIFO 0x1
00083 #define XNPOD_NOSWITCH  0x2
00084 
00085 /* Normal root thread priority == min_std_prio - 1 */
00086 #define XNPOD_ROOT_PRIO_BASE   ((nkpod)->root_prio_base)
00087 
00088 #ifdef CONFIG_XENO_OPT_SCALABLE_SCHED
00089 typedef xnmlqueue_t xnsched_queue_t;
00090 #define sched_initpq    initmlq
00091 #define sched_emptypq_p emptymlq_p
00092 #define sched_insertpql insertmlql
00093 #define sched_insertpqf insertmlqf
00094 #define sched_appendpq  appendmlq
00095 #define sched_prependpq prependmlq
00096 #define sched_removepq  removemlq
00097 #define sched_getheadpq getheadmlq
00098 #define sched_getpq     getmlq
00099 #define sched_findpqh   findmlqh
00100 #else /* ! CONFIG_XENO_OPT_SCALABLE_SCHED */
00101 typedef xnpqueue_t xnsched_queue_t;
00102 #define sched_initpq    initpq
00103 #define sched_emptypq_p emptypq_p
00104 #define sched_insertpql insertpql
00105 #define sched_insertpqf insertpqf
00106 #define sched_appendpq  appendpq
00107 #define sched_prependpq prependpq
00108 #define sched_removepq  removepq
00109 #define sched_getheadpq getheadpq
00110 #define sched_getpq     getpq
00111 #define sched_findpqh   findpqh
00112 #endif /* !CONFIG_XENO_OPT_SCALABLE_SCHED */
00113 
00114 #define XNPOD_FATAL_BUFSZ  16384
00115 
00120 typedef struct xnsched {
00121 
00122         xnflags_t status;       
00124         xnthread_t *runthread;  
00126         xnarch_cpumask_t resched;       
00128         xnsched_queue_t readyq; 
00130         xntimerq_t timerqueue;
00131 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00132         xnqueue_t timerwheel[XNTIMER_WHEELSIZE];        
00133 #endif                          /* CONFIG_XENO_OPT_TIMING_PERIODIC */
00134 
00135         volatile unsigned inesting;     
00137 #ifdef CONFIG_XENO_HW_FPU
00138         xnthread_t *fpuholder;  
00139 #endif                          /* CONFIG_XENO_HW_FPU */
00140 
00141 #ifdef CONFIG_XENO_OPT_WATCHDOG
00142         xntimer_t wd_timer;     
00143         int wd_count;           
00144 #endif                          /* CONFIG_XENO_OPT_WATCHDOG */
00145 
00146         xnthread_t rootcb;      
00148 #ifdef CONFIG_XENO_OPT_STATS
00149         xnticks_t last_account_switch;  
00151         xnstat_runtime_t *current_account;      
00152 #endif                          /* CONFIG_XENO_OPT_STATS */
00153 
00154 } xnsched_t;
00155 
00156 #ifdef CONFIG_SMP
00157 #define xnsched_cpu(__sched__)                  \
00158     ((__sched__) - &nkpod->sched[0])
00159 #else /* !CONFIG_SMP */
00160 #define xnsched_cpu(__sched__) (0)
00161 #endif /* CONFIG_SMP */
00162 
00163 #define xnsched_resched_mask() \
00164     (xnpod_current_sched()->resched)
00165 
00166 #define xnsched_resched_p()                     \
00167     (!xnarch_cpus_empty(xnsched_resched_mask()))
00168 
00169 #define xnsched_tst_resched(__sched__) \
00170     xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00171 
00172 #define xnsched_set_resched(__sched__) \
00173     xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00174 
00175 #define xnsched_clr_resched(__sched__) \
00176     xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00177 
00178 #define xnsched_clr_mask(__sched__) \
00179     xnarch_cpus_clear((__sched__)->resched)
00180 
00181 struct xnsynch;
00182 struct xnintr;
00183 
00190 struct xnpod {
00191 
00192         xnflags_t status;       
00194         xnticks_t jiffies;      
00196         xnticks_t wallclock_offset;     
00199         xntimer_t htimer;       
00201         xnsched_t sched[XNARCH_NR_CPUS];        
00203         xnqueue_t threadq;      
00204         int threadq_rev;        
00206         volatile u_long schedlck;       
00208         xnqueue_t tstartq,      
00209          tswitchq,              
00210          tdeleteq;              
00212         int minpri,             
00213          maxpri;                
00215         int root_prio_base;     
00217         u_long tickvalue;       
00219         u_long ticks2sec;       
00222         int refcnt;             
00224 #ifdef __KERNEL__
00225         atomic_counter_t timerlck;      
00226 #endif                          /* __KERNEL__ */
00227 
00228         struct {
00229                 void (*settime) (xnticks_t newtime);    
00230                 int (*faulthandler) (xnarch_fltinfo_t *fltinfo);        
00231                 int (*unload) (void);   
00232         } svctable;             
00234 #ifdef __XENO_SIM__
00235         void (*schedhook) (xnthread_t *thread, xnflags_t mask); 
00236 #endif                          /* __XENO_SIM__ */
00237 };
00238 
00239 typedef struct xnpod xnpod_t;
00240 
00241 extern xnpod_t *nkpod;
00242 
00243 #ifdef CONFIG_SMP
00244 extern xnlock_t nklock;
00245 #endif /* CONFIG_SMP */
00246 
00247 extern u_long nkschedlat;
00248 
00249 extern u_long nktimerlat;
00250 
00251 extern u_long nktickdef;
00252 
00253 extern char *nkmsgbuf;
00254 
00255 #ifdef __cplusplus
00256 extern "C" {
00257 #endif
00258 
00259 void xnpod_schedule_runnable(xnthread_t *thread, int flags);
00260 
00261 void xnpod_renice_thread_inner(xnthread_t *thread, int prio, int propagate);
00262 
00263 #ifdef CONFIG_XENO_HW_FPU
00264 void xnpod_switch_fpu(xnsched_t *sched);
00265 #endif /* CONFIG_XENO_HW_FPU */
00266 
00267 #ifdef CONFIG_XENO_OPT_WATCHDOG
00268 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00269 {
00270         sched->wd_count = 0;
00271 }
00272 #else /* !CONFIG_XENO_OPT_WATCHDOG */
00273 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00274 {
00275 }
00276 #endif /* CONFIG_XENO_OPT_WATCHDOG */
00277 static inline int xnpod_get_qdir(xnpod_t *pod)
00278 {
00279         /* Returns the queuing direction of threads for a given pod */
00280         return testbits(pod->status, XNRPRIO) ? xnqueue_up : xnqueue_down;
00281 }
00282 
00283 static inline int xnpod_get_minprio(xnpod_t *pod, int incr)
00284 {
00285         return xnpod_get_qdir(pod) == xnqueue_up ?
00286             pod->minpri + incr : pod->minpri - incr;
00287 }
00288 
00289 static inline int xnpod_get_maxprio(xnpod_t *pod, int incr)
00290 {
00291         return xnpod_get_qdir(pod) == xnqueue_up ?
00292             pod->maxpri - incr : pod->maxpri + incr;
00293 }
00294 
00295 static inline int xnpod_compare_prio(int inprio, int outprio)
00296 {
00297         /* Returns a negative, null or positive value whether inprio is
00298            lower than, equal to or greater than outprio. */
00299         int delta = inprio - outprio;
00300         return testbits(nkpod->status, XNRPRIO) ? -delta : delta;
00301 }
00302 
00303 static inline int xnpod_rescale_prio(int prio)
00304 {
00305         return xnpod_get_qdir(nkpod) == xnqueue_up ?
00306             nkpod->minpri - prio : nkpod->maxpri - prio - 1;
00307 }
00308 
00309 static inline void xnpod_renice_root(int prio)
00310 {
00311         xnthread_t *rootcb;
00312         spl_t s;
00313 
00314         xnlock_get_irqsave(&nklock, s);
00315         rootcb = &nkpod->sched[xnarch_current_cpu()].rootcb;
00316         rootcb->cprio = prio;
00317         xnpod_schedule_runnable(rootcb, XNPOD_SCHEDLIFO | XNPOD_NOSWITCH);
00318         xnlock_put_irqrestore(&nklock, s);
00319 }
00320 
00321         /* -- Beginning of the exported interface */
00322 
00323 #define xnpod_sched_slot(cpu) \
00324     (&nkpod->sched[cpu])
00325 
00326 #define xnpod_current_sched() \
00327     xnpod_sched_slot(xnarch_current_cpu())
00328 
00329 #define xnpod_interrupt_p() \
00330     (xnpod_current_sched()->inesting > 0)
00331 
00332 #define xnpod_callout_p() \
00333     (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00334 
00335 #define xnpod_asynch_p() \
00336     (xnpod_interrupt_p() || xnpod_callout_p())
00337 
00338 #define xnpod_current_thread() \
00339     (xnpod_current_sched()->runthread)
00340 
00341 #define xnpod_current_root() \
00342     (&xnpod_current_sched()->rootcb)
00343 
00344 #define xnpod_current_p(thread) \
00345     (xnpod_current_thread() == (thread))
00346 
00347 #define xnpod_locked_p() \
00348     (!!xnthread_test_state(xnpod_current_thread(),XNLOCK))
00349 
00350 #define xnpod_unblockable_p() \
00351     (xnpod_asynch_p() || xnthread_test_state(xnpod_current_thread(),XNLOCK|XNROOT))
00352 
00353 #define xnpod_root_p() \
00354     (!!xnthread_test_state(xnpod_current_thread(),XNROOT))
00355 
00356 #define xnpod_shadow_p() \
00357     (!!xnthread_test_state(xnpod_current_thread(),XNSHADOW))
00358 
00359 #define xnpod_userspace_p() \
00360     (!!xnthread_test_state(xnpod_current_thread(),XNROOT|XNSHADOW))
00361 
00362 #define xnpod_primary_p() \
00363     (!(xnpod_asynch_p() || xnpod_root_p()))
00364 
00365 #define xnpod_secondary_p()     xnpod_root_p()
00366 
00367 #define xnpod_idle_p()  xnpod_root_p()
00368 
00369 #define xnpod_timeset_p()       (!!testbits(nkpod->status,XNTMSET))
00370 
00371 static inline u_long xnpod_get_ticks2sec(void)
00372 {
00373         return nkpod->ticks2sec;
00374 }
00375 
00376 static inline u_long xnpod_get_tickval(void)
00377 {
00378         /* Returns the duration of a tick in nanoseconds */
00379         return nkpod->tickvalue;
00380 }
00381 
00382 static inline xntime_t xnpod_ticks2ns(xnticks_t ticks)
00383 {
00384         /* Convert a count of ticks in nanoseconds */
00385 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00386         return ticks * xnpod_get_tickval();
00387 #else /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00388         return ticks;
00389 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00390 }
00391 
00392 static inline xnticks_t xnpod_ns2ticks(xntime_t t)
00393 {
00394 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00395         return xnarch_ulldiv(t, xnpod_get_tickval(), NULL);
00396 #else /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00397         return t;
00398 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00399 }
00400 
00401 int xnpod_init(xnpod_t *pod, int minpri, int maxpri, xnflags_t flags);
00402 
00403 int xnpod_start_timer(u_long nstick, xnisr_t tickhandler);
00404 
00405 void xnpod_stop_timer(void);
00406 
00407 int xnpod_reset_timer(void);
00408 
00409 void xnpod_shutdown(int xtype);
00410 
00411 int xnpod_init_thread(xnthread_t *thread,
00412                       const char *name,
00413                       int prio, xnflags_t flags, unsigned stacksize);
00414 
00415 int xnpod_start_thread(xnthread_t *thread,
00416                        xnflags_t mode,
00417                        int imask,
00418                        xnarch_cpumask_t affinity,
00419                        void (*entry) (void *cookie), void *cookie);
00420 
00421 void xnpod_restart_thread(xnthread_t *thread);
00422 
00423 void xnpod_delete_thread(xnthread_t *thread);
00424 
00425 xnflags_t xnpod_set_thread_mode(xnthread_t *thread,
00426                                 xnflags_t clrmask, xnflags_t setmask);
00427 
00428 void xnpod_suspend_thread(xnthread_t *thread,
00429                           xnflags_t mask,
00430                           xnticks_t timeout, struct xnsynch *resource);
00431 
00432 void xnpod_resume_thread(xnthread_t *thread, xnflags_t mask);
00433 
00434 int xnpod_unblock_thread(xnthread_t *thread);
00435 
00436 void xnpod_renice_thread(xnthread_t *thread, int prio);
00437 
00438 int xnpod_migrate_thread(int cpu);
00439 
00440 void xnpod_rotate_readyq(int prio);
00441 
00442 void xnpod_schedule(void);
00443 
00444 void xnpod_dispatch_signals(void);
00445 
00446 static inline void xnpod_lock_sched(void)
00447 {
00448         spl_t s;
00449 
00450         xnlock_get_irqsave(&nklock, s);
00451 
00452         if (nkpod->schedlck++ == 0)
00453                 xnthread_set_state(xnpod_current_sched()->runthread, XNLOCK);
00454 
00455         xnlock_put_irqrestore(&nklock, s);
00456 }
00457 
00458 static inline void xnpod_unlock_sched(void)
00459 {
00460         spl_t s;
00461 
00462         xnlock_get_irqsave(&nklock, s);
00463 
00464         if (--nkpod->schedlck == 0) {
00465                 xnthread_clear_state(xnpod_current_sched()->runthread, XNLOCK);
00466                 xnpod_schedule();
00467         }
00468 
00469         xnlock_put_irqrestore(&nklock, s);
00470 }
00471 
00472 int xnpod_announce_tick(struct xnintr *intr);
00473 
00474 void xnpod_activate_rr(xnticks_t quantum);
00475 
00476 void xnpod_deactivate_rr(void);
00477 
00478 void xnpod_set_time(xnticks_t newtime);
00479 
00480 int xnpod_set_thread_periodic(xnthread_t *thread,
00481                               xnticks_t idate, xnticks_t period);
00482 
00483 int xnpod_wait_thread_period(unsigned long *overruns_r);
00484 
00485 xnticks_t xnpod_get_time(void);
00486 
00487 static inline xntime_t xnpod_get_cpu_time(void)
00488 {
00489         return xnarch_get_cpu_time();
00490 }
00491 
00492 int xnpod_add_hook(int type, void (*routine) (xnthread_t *));
00493 
00494 int xnpod_remove_hook(int type, void (*routine) (xnthread_t *));
00495 
00496 void xnpod_check_context(int mask);
00497 
00498 static inline void xnpod_yield(void)
00499 {
00500         xnpod_resume_thread(xnpod_current_thread(), 0);
00501         xnpod_schedule();
00502 }
00503 
00504 static inline void xnpod_delay(xnticks_t timeout)
00505 {
00506         xnpod_suspend_thread(xnpod_current_thread(), XNDELAY, timeout, NULL);
00507 }
00508 
00509 static inline void xnpod_suspend_self(void)
00510 {
00511         xnpod_suspend_thread(xnpod_current_thread(), XNSUSP, XN_INFINITE, NULL);
00512 }
00513 
00514 static inline void xnpod_delete_self(void)
00515 {
00516         xnpod_delete_thread(xnpod_current_thread());
00517 }
00518 
00519 #ifdef __cplusplus
00520 }
00521 #endif
00522 
00525 #endif /* !_XENO_NUCLEUS_POD_H */

Generated on Mon Dec 25 13:57:10 2006 for Xenomai API by  doxygen 1.4.6