pod.h

Go to the documentation of this file.
00001 
00027 #ifndef _RTAI_NUCLEUS_POD_H
00028 #define _RTAI_NUCLEUS_POD_H
00029 
00033 #include <nucleus/thread.h>
00034 #include <nucleus/intr.h>
00035 
00036 /* Creation flags */
00037 #define XNDREORD 0x00000001     /* Don't reorder pend queues upon prio change */
00038 
00039 /* Pod status flags */
00040 #define XNRPRIO  0x00000002     /* Reverse priority scheme */
00041 #define XNTIMED  0x00000004     /* Timer started */
00042 #define XNTMSET  0x00000008     /* Pod time has been set */
00043 #define XNTMPER  0x00000010     /* Periodic timing */
00044 #define XNFATAL  0x00000020     /* Pod encountered a fatal error */
00045 #define XNPIDLE  0x00000040     /* Pod is unavailable (initializing/shutting down) */
00046 #define XNTLOCK  0x00000080     /* Timer lock pending */
00047 
00048 /* Sched status flags */
00049 #define XNKCOUT  0x80000000     /* Sched callout context */
00050 #define XNHTICK  0x40000000     /* Host tick pending  */
00051 
00052 /* These flags are available to the real-time interfaces */
00053 #define XNPOD_SPARE0  0x01000000
00054 #define XNPOD_SPARE1  0x02000000
00055 #define XNPOD_SPARE2  0x04000000
00056 #define XNPOD_SPARE3  0x08000000
00057 #define XNPOD_SPARE4  0x10000000
00058 #define XNPOD_SPARE5  0x20000000
00059 #define XNPOD_SPARE6  0x40000000
00060 #define XNPOD_SPARE7  0x80000000
00061 
00062 /* Flags for context checking */
00063 #define XNPOD_THREAD_CONTEXT     0x1 /* Regular thread */
00064 #define XNPOD_INTERRUPT_CONTEXT  0x2 /* Interrupt service thread */
00065 #define XNPOD_HOOK_CONTEXT       0x4 /* Nanokernel hook */
00066 #define XNPOD_ROOT_CONTEXT       0x8 /* Root thread */
00067 
00068 #define XNPOD_NORMAL_EXIT  0x0
00069 #define XNPOD_FATAL_EXIT   0x1
00070 
00071 #define XNPOD_DEFAULT_TICK         XNARCH_DEFAULT_TICK
00072 #define XNPOD_DEFAULT_TICKHANDLER  (&xnpod_announce_tick)
00073 
00074 #define XNPOD_ALL_CPUS  XNARCH_CPU_MASK_ALL
00075 
00076 #define XNPOD_HEAPSIZE  (CONFIG_RTAI_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_RTAI_OPT_SCALABLE_SCHED
00089 typedef xnspqueue_t xnsched_queue_t;
00090 #define sched_initpq    initspq
00091 #define sched_countpq   countspq
00092 #define sched_insertpql insertspql
00093 #define sched_insertpqf insertspqf
00094 #define sched_appendpq  appendspq
00095 #define sched_prependpq prependspq
00096 #define sched_removepq  removespq
00097 #define sched_getheadpq getheadspq
00098 #define sched_getpq     getspq
00099 #define sched_findpqh   findspqh
00100 #else /* ! CONFIG_RTAI_OPT_SCALABLE_SCHED */
00101 typedef xnpqueue_t xnsched_queue_t;
00102 #define sched_initpq    initpq
00103 #define sched_countpq   countpq
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_RTAI_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     xnqueue_t timerwheel[XNTIMER_WHEELSIZE]; 
00132     volatile unsigned inesting; 
00134 #ifdef CONFIG_RTAI_HW_FPU
00135     xnthread_t *fpuholder;      
00136 #endif /* CONFIG_RTAI_HW_FPU */
00137 
00138     xnthread_t rootcb;          
00140 } xnsched_t;
00141 
00142 #ifdef CONFIG_SMP
00143 #define xnsched_cpu(__sched__)                  \
00144     ((__sched__) - &nkpod->sched[0])
00145 #else /* !CONFIG_SMP */
00146 #define xnsched_cpu(__sched__) (0)
00147 #endif /* CONFIG_SMP */
00148 
00149 #define xnsched_resched_mask() \
00150     (xnpod_current_sched()->resched)
00151 
00152 #define xnsched_resched_p()                     \
00153     (!xnarch_cpus_empty(xnsched_resched_mask()))
00154 
00155 #define xnsched_tst_resched(__sched__) \
00156     xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00157 
00158 #define xnsched_set_resched(__sched__) \
00159     xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00160 
00161 #define xnsched_clr_resched(__sched__) \
00162     xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00163 
00164 #define xnsched_clr_mask(__sched__) \
00165     xnarch_cpus_clear((__sched__)->resched)
00166 
00167 struct xnsynch;
00168 struct xnintr;
00169 
00176 struct xnpod {
00177 
00178     xnflags_t status;           
00180     xnticks_t jiffies;          
00182     xnticks_t wallclock_offset; 
00185     xntimer_t htimer;           
00187     xnsched_t sched[XNARCH_NR_CPUS]; 
00189     xnqueue_t suspendq;         
00191     xnqueue_t threadq;          
00193     atomic_counter_t schedlck;  
00195     xnqueue_t tstartq,          
00196               tswitchq,         
00197               tdeleteq;         
00199     int minpri,                 
00200         maxpri;                 
00202     int root_prio_base;         
00204     u_long tickvalue;           
00206     u_long ticks2sec;           
00209     int refcnt;                 
00211     atomic_counter_t timerlck;  
00213     struct {
00214         void (*settime)(xnticks_t newtime); 
00215         int (*faulthandler)(xnarch_fltinfo_t *fltinfo); 
00216         int (*unload)(void);    
00217     } svctable;                 
00219 #ifdef CONFIG_RTAI_OPT_WATCHDOG
00220     xnticks_t watchdog_trigger; /* !< Watchdog trigger value. */
00221     xnticks_t watchdog_reload;  /* !< Watchdog reload value. */
00222     int watchdog_armed;         /* !< Watchdog state. */
00223 #endif /* CONFIG_RTAI_OPT_WATCHDOG */
00224 
00225 #ifdef __RTAI_SIM__
00226     void (*schedhook)(xnthread_t *thread,
00227                       xnflags_t mask); 
00228 #endif /* __RTAI_SIM__ */
00229 };
00230 
00231 typedef struct xnpod xnpod_t;
00232 
00233 extern xnpod_t *nkpod;
00234 
00235 #ifdef CONFIG_SMP
00236 extern xnlock_t nklock;
00237 #endif /* CONFIG_SMP */
00238 
00239 extern u_long nkschedlat;
00240 
00241 extern u_long nktimerlat;
00242 
00243 extern char *nkmsgbuf;
00244 
00245 #define xnprintf(fmt,args...)  xnarch_printf(fmt , ##args)
00246 #define xnloginfo(fmt,args...) xnarch_loginfo(fmt , ##args)
00247 #define xnlogwarn(fmt,args...) xnarch_logwarn(fmt , ##args)
00248 #define xnlogerr(fmt,args...)  xnarch_logerr(fmt , ##args)
00249 
00250 #ifdef __cplusplus
00251 extern "C" {
00252 #endif
00253 
00254 void xnpod_schedule_runnable(xnthread_t *thread,
00255                              int flags);
00256 
00257 void xnpod_renice_thread_inner(xnthread_t *thread,
00258                                int prio,
00259                                int propagate);
00260 
00261 #ifdef CONFIG_RTAI_HW_FPU
00262 void xnpod_switch_fpu(xnsched_t *sched);
00263 #endif /* CONFIG_RTAI_HW_FPU */
00264 
00265 #ifdef CONFIG_RTAI_OPT_WATCHDOG
00266 static inline void xnpod_reset_watchdog (void)
00267 {
00268     nkpod->watchdog_trigger = xnarch_get_cpu_tsc() + nkpod->watchdog_reload;
00269     nkpod->watchdog_armed = 0;
00270 }
00271 #else /* !CONFIG_RTAI_OPT_WATCHDOG */
00272 static inline void xnpod_reset_watchdog (void)
00273 {
00274 }
00275 #endif /* CONFIG_RTAI_OPT_WATCHDOG */
00276 
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 :
00287         pod->minpri - incr;
00288 }
00289 
00290 static inline int xnpod_get_maxprio (xnpod_t *pod, int incr)
00291 {
00292     return xnpod_get_qdir(pod) == xnqueue_up ?
00293         pod->maxpri - incr :
00294         pod->maxpri + incr;
00295 }
00296 
00297 static inline int xnpod_priocompare (int inprio, int outprio)
00298 {
00299     /* Returns a negative, null or positive value whether inprio is
00300        lower than, equal to or greater than outprio. */
00301     int delta = inprio - outprio;
00302     return testbits(nkpod->status,XNRPRIO) ? -delta : delta;
00303 }
00304 
00305 static inline void xnpod_renice_root (int prio)
00306 
00307 {
00308     xnthread_t *rootcb;
00309     spl_t s;
00310 
00311     xnlock_get_irqsave(&nklock,s);
00312     rootcb = &nkpod->sched[xnarch_current_cpu()].rootcb;
00313     rootcb->cprio = prio;
00314     xnpod_schedule_runnable(rootcb,XNPOD_SCHEDLIFO|XNPOD_NOSWITCH);
00315     xnlock_put_irqrestore(&nklock,s);
00316 }
00317 
00318     /* -- Beginning of the exported interface */
00319 
00320 #define xnpod_sched_slot(cpu) \
00321     (&nkpod->sched[cpu])
00322 
00323 #define xnpod_current_sched() \
00324     xnpod_sched_slot(xnarch_current_cpu())
00325 
00326 #define xnpod_interrupt_p() \
00327     (xnpod_current_sched()->inesting > 0)
00328 
00329 #define xnpod_callout_p() \
00330     (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00331 
00332 #define xnpod_asynch_p() \
00333     (xnpod_interrupt_p() || xnpod_callout_p())
00334 
00335 #define xnpod_current_thread() \
00336     (xnpod_current_sched()->runthread)
00337 
00338 #define xnpod_current_root() \
00339     (&xnpod_current_sched()->rootcb)
00340 
00341 #define xnpod_current_p(thread) \
00342     (xnpod_current_thread() == (thread))
00343 
00344 #define xnpod_locked_p() \
00345     (!!testbits(xnpod_current_thread()->status,XNLOCK))
00346 
00347 #define xnpod_unblockable_p() \
00348     (xnpod_asynch_p() || testbits(xnpod_current_thread()->status,XNLOCK|XNROOT))
00349 
00350 #define xnpod_root_p() \
00351     (!!testbits(xnpod_current_thread()->status,XNROOT))
00352 
00353 #define xnpod_shadow_p() \
00354     (!!testbits(xnpod_current_thread()->status,XNSHADOW))
00355 
00356 #define xnpod_userspace_p() \
00357     (!!testbits(xnpod_current_thread()->status,XNROOT|XNSHADOW))
00358 
00359 #define xnpod_primary_p() \
00360     (!(xnpod_asynch_p() || xnpod_root_p()))
00361 
00362 #define xnpod_secondary_p() \
00363     (xnpod_root_p())
00364 
00365 #define xnpod_idle_p() xnpod_root_p()
00366 
00367 #define xnpod_timeset_p() \
00368     (!!testbits(nkpod->status,XNTMSET))
00369 
00370 static inline u_long xnpod_get_ticks2sec (void) {
00371     return nkpod->ticks2sec;
00372 }
00373 
00374 static inline u_long xnpod_get_tickval (void) {
00375     /* Returns the duration of a tick in nanoseconds */
00376     return nkpod->tickvalue;
00377 }
00378 
00379 static inline xntime_t xnpod_ticks2ns (xnticks_t ticks) {
00380     /* Convert a count of ticks in nanoseconds */
00381 #ifdef CONFIG_RTAI_HW_PERIODIC_TIMER
00382     return ticks * xnpod_get_tickval();
00383 #else /* !CONFIG_RTAI_HW_PERIODIC_TIMER */
00384     return ticks;
00385 #endif /* !CONFIG_RTAI_HW_PERIODIC_TIMER */
00386 }
00387 
00388 static inline xnticks_t xnpod_ns2ticks (xntime_t t) {
00389 #ifdef CONFIG_RTAI_HW_PERIODIC_TIMER
00390     return xnarch_ulldiv(t,xnpod_get_tickval(),NULL);
00391 #else /* !CONFIG_RTAI_HW_PERIODIC_TIMER */
00392     return t;
00393 #endif /* !CONFIG_RTAI_HW_PERIODIC_TIMER */
00394 }
00395 
00396 int xnpod_init(xnpod_t *pod,
00397                int minpri,
00398                int maxpri,
00399                xnflags_t flags);
00400 
00401 int xnpod_start_timer(u_long nstick,
00402                       xnisr_t tickhandler);
00403 
00404 void xnpod_stop_timer(void);
00405 
00406 void xnpod_shutdown(int xtype);
00407 
00408 int xnpod_init_thread(xnthread_t *thread,
00409                       const char *name,
00410                       int prio,
00411                       xnflags_t flags,
00412                       unsigned stacksize);
00413 
00414 int xnpod_start_thread(xnthread_t *thread,
00415                        xnflags_t mode,
00416                        int imask,
00417                        xnarch_cpumask_t affinity,
00418                        void (*entry)(void *cookie),
00419                        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,
00427                                 xnflags_t setmask);
00428 
00429 void xnpod_suspend_thread(xnthread_t *thread,
00430                           xnflags_t mask,
00431                           xnticks_t timeout,
00432                           struct xnsynch *resource);
00433 
00434 void xnpod_resume_thread(xnthread_t *thread,
00435                          xnflags_t mask);
00436 
00437 int xnpod_unblock_thread(xnthread_t *thread);
00438 
00439 void xnpod_renice_thread(xnthread_t *thread,
00440                          int prio);
00441 
00442 int xnpod_migrate_thread(int cpu);
00443 
00444 void xnpod_rotate_readyq(int prio);
00445 
00446 void xnpod_schedule(void);
00447 
00448 void xnpod_dispatch_signals(void);
00449 
00450 static inline void xnpod_lock_sched (void)
00451 {
00452     /* Don't swap these two lines... */
00453     xnarch_atomic_inc(&nkpod->schedlck);
00454     __setbits(xnpod_current_sched()->runthread->status,XNLOCK);
00455 }
00456 
00457 static inline void xnpod_unlock_sched (void)
00458 {
00459     if (xnarch_atomic_dec_and_test(&nkpod->schedlck))
00460         {
00461         __clrbits(xnpod_current_sched()->runthread->status,XNLOCK);
00462         xnpod_schedule();
00463         }
00464 }
00465 
00466 static inline void xnpod_lock_timers (void)
00467 {
00468     xnarch_atomic_inc(&nkpod->timerlck);
00469     setbits(nkpod->status,XNTLOCK);
00470 }
00471 
00472 static inline void xnpod_unlock_timers (void)
00473 {
00474     if (xnarch_atomic_dec_and_test(&nkpod->timerlck))
00475         clrbits(nkpod->status,XNTLOCK);
00476 }
00477 
00478 int xnpod_announce_tick(struct xnintr *intr);
00479 
00480 void xnpod_activate_rr(xnticks_t quantum);
00481 
00482 void xnpod_deactivate_rr(void);
00483 
00484 void xnpod_set_time(xnticks_t newtime);
00485 
00486 int xnpod_set_thread_periodic(xnthread_t *thread,
00487                               xnticks_t idate,
00488                               xnticks_t period);
00489 
00490 int xnpod_wait_thread_period(void);
00491 
00492 xnticks_t xnpod_get_time(void);
00493 
00494 static inline xntime_t xnpod_get_cpu_time(void)
00495 {
00496     return xnarch_get_cpu_time();
00497 }
00498 
00499 int xnpod_add_hook(int type,
00500                    void (*routine)(xnthread_t *));
00501 
00502 int xnpod_remove_hook(int type,
00503                       void (*routine)(xnthread_t *));
00504 
00505 void xnpod_check_context(int mask);
00506 
00507 static inline void xnpod_yield (void) {
00508     xnpod_resume_thread(xnpod_current_thread(),0);
00509     xnpod_schedule();
00510 }
00511 
00512 static inline void xnpod_delay (xnticks_t timeout) {
00513     xnpod_suspend_thread(xnpod_current_thread(),XNDELAY,timeout,NULL);
00514 }
00515 
00516 static inline void xnpod_suspend_self (void) {
00517     xnpod_suspend_thread(xnpod_current_thread(),XNSUSP,XN_INFINITE,NULL);
00518 }
00519 
00520 static inline void xnpod_delete_self (void) {
00521     xnpod_delete_thread(xnpod_current_thread());
00522 }
00523 
00524 #ifdef __cplusplus
00525 }
00526 #endif
00527 
00530 #endif /* !_RTAI_NUCLEUS_POD_H */

Generated on Sat Sep 3 12:32:47 2005 for RTAI Fusion API by  doxygen 1.4.2