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 
00047 /* Sched status flags */
00048 #define XNKCOUT      0x80000000 /* Sched callout context */
00049 #define XNHTICK      0x40000000 /* Host tick pending  */
00050 
00051 /* These flags are available to the real-time interfaces */
00052 #define XNPOD_SPARE0  0x01000000
00053 #define XNPOD_SPARE1  0x02000000
00054 #define XNPOD_SPARE2  0x04000000
00055 #define XNPOD_SPARE3  0x08000000
00056 #define XNPOD_SPARE4  0x10000000
00057 #define XNPOD_SPARE5  0x20000000
00058 #define XNPOD_SPARE6  0x40000000
00059 #define XNPOD_SPARE7  0x80000000
00060 
00061 /* Flags for context checking */
00062 #define XNPOD_THREAD_CONTEXT     0x1 /* Regular thread */
00063 #define XNPOD_INTERRUPT_CONTEXT  0x2 /* Interrupt service thread */
00064 #define XNPOD_HOOK_CONTEXT       0x4 /* Nanokernel hook */
00065 #define XNPOD_ROOT_CONTEXT       0x8 /* Root thread */
00066 
00067 #define XNPOD_NORMAL_EXIT  0x0
00068 #define XNPOD_FATAL_EXIT   0x1
00069 
00070 #define XNPOD_DEFAULT_TICK         XNARCH_DEFAULT_TICK
00071 #define XNPOD_DEFAULT_TICKHANDLER  (&xnpod_announce_tick)
00072 
00073 #define XNPOD_ALL_CPUS  XNARCH_CPU_MASK_ALL
00074 
00075 #define XNPOD_HEAPSIZE  (CONFIG_RTAI_OPT_SYS_HEAPSZ * 1024)
00076 #define XNPOD_PAGESIZE  512
00077 #define XNPOD_RUNPRIO   0x80000000 /* Placeholder for "stdthread priority" */
00078 
00079 /* Flags for xnpod_schedule_runnable() */
00080 #define XNPOD_SCHEDFIFO 0x0
00081 #define XNPOD_SCHEDLIFO 0x1
00082 #define XNPOD_NOSWITCH  0x2
00083 
00084 /* Normal root thread priority == min_std_prio - 1 */
00085 #define XNPOD_ROOT_PRIO_BASE   ((nkpod)->root_prio_base)
00086 
00087 #ifdef CONFIG_RTAI_OPT_SCALABLE_SCHED
00088 typedef xnspqueue_t xnsched_queue_t;
00089 #define sched_initpq    initspq
00090 #define sched_countpq   countspq
00091 #define sched_insertpql insertspql
00092 #define sched_insertpqf insertspqf
00093 #define sched_appendpq  appendspq
00094 #define sched_prependpq prependspq
00095 #define sched_removepq  removespq
00096 #define sched_getheadpq getheadspq
00097 #define sched_getpq     getspq
00098 #define sched_findpqh   findspqh
00099 #else /* ! CONFIG_RTAI_OPT_SCALABLE_SCHED */
00100 typedef xnpqueue_t xnsched_queue_t;
00101 #define sched_initpq    initpq
00102 #define sched_countpq   countpq
00103 #define sched_insertpql insertpql
00104 #define sched_insertpqf insertpqf
00105 #define sched_appendpq  appendpq
00106 #define sched_prependpq prependpq
00107 #define sched_removepq  removepq
00108 #define sched_getheadpq getheadpq
00109 #define sched_getpq     getpq
00110 #define sched_findpqh   findpqh
00111 #endif /* !CONFIG_RTAI_OPT_SCALABLE_SCHED */
00112 
00117 typedef struct xnsched {
00118 
00119     xnflags_t status;           
00121     xnthread_t *runthread;      
00123     xnarch_cpumask_t resched;   
00125     xnsched_queue_t readyq;     
00127     xnqueue_t timerwheel[XNTIMER_WHEELSIZE]; 
00129     volatile unsigned inesting; 
00131 #ifdef CONFIG_RTAI_HW_FPU
00132     xnthread_t *fpuholder;      
00133 #endif /* CONFIG_RTAI_HW_FPU */
00134 
00135     xnthread_t rootcb;          
00137 } xnsched_t;
00138 
00139 #define xnsched_cpu(__sched__) \
00140     ((__sched__) - &nkpod->sched[0])
00141 
00142 #define xnsched_resched_mask() \
00143     (xnpod_current_sched()->resched)
00144 
00145 #define xnsched_resched_p()                     \
00146     (!xnarch_cpus_empty(xnsched_resched_mask()))
00147 
00148 #define xnsched_tst_resched(__sched__) \
00149     xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00150 
00151 #define xnsched_set_resched(__sched__) \
00152     xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00153 
00154 #define xnsched_clr_resched(__sched__) \
00155     xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00156 
00157 #define xnsched_clr_mask(__sched__) \
00158     xnarch_cpus_clear((__sched__)->resched)
00159 
00160 struct xnsynch;
00161 struct xnintr;
00162 
00169 struct xnpod {
00170 
00171     xnflags_t status;           
00173     xnticks_t jiffies;          
00175     xnticks_t wallclock;        
00177     xntimer_t htimer;           
00179     xnsched_t sched[XNARCH_NR_CPUS]; 
00181     xnqueue_t suspendq;         
00183     xnqueue_t threadq;          
00185     atomic_counter_t schedlck;  
00187     xnqueue_t tstartq,          
00188               tswitchq,         
00189               tdeleteq;         
00191     int minpri,                 
00192         maxpri;                 
00194     int root_prio_base;         
00196     u_long tickvalue;           
00198     u_long ticks2sec;           
00200     int refcnt;                 
00202     struct {
00203         xnisr_t tickhandler; 
00204         void (*settime)(xnticks_t newtime); 
00205         int (*faulthandler)(xnarch_fltinfo_t *fltinfo); 
00206         int (*unload)(void);    
00207     } svctable;                 
00209 #ifdef CONFIG_RTAI_OPT_WATCHDOG
00210     xnticks_t watchdog_trigger; /* !< Watchdog trigger value. */
00211     xnticks_t watchdog_reload;  /* !< Watchdog reload value. */
00212     int watchdog_armed;         /* !< Watchdog state. */
00213 #endif /* CONFIG_RTAI_OPT_WATCHDOG */
00214 
00215 #ifdef __RTAI_SIM__
00216     void (*schedhook)(xnthread_t *thread,
00217                       xnflags_t mask); 
00218 #endif /* __RTAI_SIM__ */
00219 };
00220 
00221 typedef struct xnpod xnpod_t;
00222 
00223 extern xnpod_t *nkpod;
00224 
00225 #ifdef CONFIG_SMP
00226 extern xnlock_t nklock;
00227 #endif /* CONFIG_SMP */
00228 
00229 extern u_long nkschedlat;
00230 
00231 extern u_long nktimerlat;
00232 
00233 #define xnprintf(fmt,args...)  xnarch_printf(fmt , ##args)
00234 #define xnloginfo(fmt,args...) xnarch_loginfo(fmt , ##args)
00235 #define xnlogwarn(fmt,args...) xnarch_logwarn(fmt , ##args)
00236 #define xnlogerr(fmt,args...)  xnarch_logerr(fmt , ##args)
00237 
00238 #ifdef __cplusplus
00239 extern "C" {
00240 #endif
00241 
00242 void xnpod_schedule_runnable(xnthread_t *thread,
00243                              int flags);
00244 
00245 void xnpod_renice_thread_inner(xnthread_t *thread,
00246                                int prio,
00247                                int propagate);
00248 
00249 #ifdef CONFIG_RTAI_HW_FPU
00250 void xnpod_switch_fpu(xnsched_t *sched);
00251 #endif /* CONFIG_RTAI_HW_FPU */
00252 
00253 #ifdef CONFIG_RTAI_OPT_WATCHDOG
00254 static inline void xnpod_reset_watchdog (void)
00255 {
00256     nkpod->watchdog_trigger = xnarch_get_cpu_tsc() + nkpod->watchdog_reload;
00257     nkpod->watchdog_armed = 0;
00258 }
00259 #else /* !CONFIG_RTAI_OPT_WATCHDOG */
00260 static inline void xnpod_reset_watchdog (void)
00261 {
00262 }
00263 #endif /* CONFIG_RTAI_OPT_WATCHDOG */
00264 
00265 static inline int xnpod_get_qdir (xnpod_t *pod)
00266 {
00267     /* Returns the queuing direction of threads for a given pod */
00268     return testbits(pod->status,XNRPRIO) ? xnqueue_up : xnqueue_down;
00269 }
00270 
00271 static inline int xnpod_get_minprio (xnpod_t *pod, int incr)
00272 {
00273     return xnpod_get_qdir(pod) == xnqueue_up ?
00274         pod->minpri + incr :
00275         pod->minpri - incr;
00276 }
00277 
00278 static inline int xnpod_get_maxprio (xnpod_t *pod, int incr)
00279 {
00280     return xnpod_get_qdir(pod) == xnqueue_up ?
00281         pod->maxpri - incr :
00282         pod->maxpri + incr;
00283 }
00284 
00285 static inline int xnpod_priocompare (int inprio, int outprio)
00286 {
00287     /* Returns a negative, null or positive value whether inprio is
00288        lower than, equal to or greater than outprio. */
00289     int delta = inprio - outprio;
00290     return testbits(nkpod->status,XNRPRIO) ? -delta : delta;
00291 }
00292 
00293 static inline void xnpod_renice_root (int prio)
00294 
00295 {
00296     xnthread_t *rootcb;
00297     spl_t s;
00298 
00299     xnlock_get_irqsave(&nklock,s);
00300     rootcb = &nkpod->sched[xnarch_current_cpu()].rootcb;
00301     rootcb->cprio = prio;
00302     xnpod_schedule_runnable(rootcb,XNPOD_SCHEDLIFO|XNPOD_NOSWITCH);
00303     xnlock_put_irqrestore(&nklock,s);
00304 }
00305 
00306     /* -- Beginning of the exported interface */
00307 
00308 #define xnpod_sched_slot(cpu) \
00309     (&nkpod->sched[cpu])
00310 
00311 #define xnpod_current_sched() \
00312     xnpod_sched_slot(xnarch_current_cpu())
00313 
00314 #define xnpod_interrupt_p() \
00315     (xnpod_current_sched()->inesting > 0)
00316 
00317 #define xnpod_callout_p() \
00318     (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00319 
00320 #define xnpod_asynch_p() \
00321     (xnpod_interrupt_p() || xnpod_callout_p())
00322 
00323 #define xnpod_current_thread() \
00324     (xnpod_current_sched()->runthread)
00325 
00326 #define xnpod_current_root() \
00327     (&xnpod_current_sched()->rootcb)
00328 
00329 #define xnpod_current_p(thread) \
00330     (xnpod_current_thread() == (thread))
00331 
00332 #define xnpod_locked_p() \
00333     (!!testbits(xnpod_current_thread()->status,XNLOCK))
00334 
00335 #define xnpod_unblockable_p() \
00336     (xnpod_asynch_p() || testbits(xnpod_current_thread()->status,XNLOCK|XNROOT))
00337 
00338 #define xnpod_root_p() \
00339     (!!testbits(xnpod_current_thread()->status,XNROOT))
00340 
00341 #define xnpod_shadow_p() \
00342     (!!testbits(xnpod_current_thread()->status,XNSHADOW))
00343 
00344 #define xnpod_userspace_p() \
00345     (!!testbits(xnpod_current_thread()->status,XNROOT|XNSHADOW))
00346 
00347 #define xnpod_primary_p() \
00348     (!(xnpod_asynch_p() || xnpod_root_p()))
00349 
00350 #define xnpod_secondary_p() \
00351     (xnpod_root_p())
00352 
00353 #define xnpod_idle_p() xnpod_root_p()
00354 
00355 #define xnpod_timeset_p() \
00356     (!!testbits(nkpod->status,XNTMSET))
00357 
00358 static inline u_long xnpod_get_ticks2sec (void) {
00359     return nkpod->ticks2sec;
00360 }
00361 
00362 static inline u_long xnpod_get_tickval (void) {
00363     /* Returns the duration of a tick in nanoseconds */
00364     return nkpod->tickvalue;
00365 }
00366 
00367 static inline xntime_t xnpod_ticks2ns (xnticks_t ticks) {
00368     /* Convert a count of ticks in nanoseconds */
00369     return ticks * xnpod_get_tickval();
00370 }
00371 
00372 static inline xnticks_t xnpod_ns2ticks (xntime_t t) {
00373     return xnarch_ulldiv(t,xnpod_get_tickval(),NULL);
00374 }
00375 
00376 int xnpod_init(xnpod_t *pod,
00377                int minpri,
00378                int maxpri,
00379                xnflags_t flags);
00380 
00381 int xnpod_start_timer(u_long nstick,
00382                       xnisr_t tickhandler);
00383 
00384 void xnpod_stop_timer(void);
00385 
00386 void xnpod_shutdown(int xtype);
00387 
00388 int xnpod_init_thread(xnthread_t *thread,
00389                       const char *name,
00390                       int prio,
00391                       xnflags_t flags,
00392                       unsigned stacksize);
00393 
00394 int xnpod_start_thread(xnthread_t *thread,
00395                        xnflags_t mode,
00396                        int imask,
00397                        xnarch_cpumask_t affinity,
00398                        void (*entry)(void *cookie),
00399                        void *cookie);
00400 
00401 void xnpod_restart_thread(xnthread_t *thread);
00402 
00403 void xnpod_delete_thread(xnthread_t *thread);
00404 
00405 xnflags_t xnpod_set_thread_mode(xnthread_t *thread,
00406                                 xnflags_t clrmask,
00407                                 xnflags_t setmask);
00408 
00409 void xnpod_suspend_thread(xnthread_t *thread,
00410                           xnflags_t mask,
00411                           xnticks_t timeout,
00412                           struct xnsynch *resource);
00413 
00414 void xnpod_resume_thread(xnthread_t *thread,
00415                          xnflags_t mask);
00416 
00417 int xnpod_unblock_thread(xnthread_t *thread);
00418 
00419 void xnpod_renice_thread(xnthread_t *thread,
00420                          int prio);
00421 
00422 int xnpod_migrate_thread(int cpu);
00423 
00424 void xnpod_rotate_readyq(int prio);
00425 
00426 void xnpod_schedule(void);
00427 
00428 static inline void xnpod_lock_sched (void) {
00429 
00430     /* Don't swap these two lines... */
00431     xnarch_atomic_inc(&nkpod->schedlck);
00432     __setbits(xnpod_current_sched()->runthread->status,XNLOCK);
00433 }
00434 
00435 static inline void xnpod_unlock_sched (void) {
00436 
00437     if (xnarch_atomic_dec_and_test(&nkpod->schedlck))
00438         {
00439         __clrbits(xnpod_current_sched()->runthread->status,XNLOCK);
00440         xnpod_schedule();
00441         }
00442 }
00443 
00444 int xnpod_announce_tick(struct xnintr *intr);
00445 
00446 void xnpod_activate_rr(xnticks_t quantum);
00447 
00448 void xnpod_deactivate_rr(void);
00449 
00450 void xnpod_set_time(xnticks_t newtime);
00451 
00452 int xnpod_set_thread_periodic(xnthread_t *thread,
00453                               xnticks_t idate,
00454                               xnticks_t period);
00455 
00456 int xnpod_wait_thread_period(void);
00457 
00458 xnticks_t xnpod_get_time(void);
00459 
00460 static inline xntime_t xnpod_get_cpu_time(void) {
00461     return xnarch_get_cpu_time();
00462 }
00463 
00464 int xnpod_add_hook(int type,
00465                    void (*routine)(xnthread_t *));
00466 
00467 int xnpod_remove_hook(int type,
00468                       void (*routine)(xnthread_t *));
00469 
00470 void xnpod_check_context(int mask);
00471 
00472 static inline void xnpod_yield (void) {
00473     xnpod_resume_thread(xnpod_current_thread(),0);
00474     xnpod_schedule();
00475 }
00476 
00477 static inline void xnpod_delay (xnticks_t timeout) {
00478     xnpod_suspend_thread(xnpod_current_thread(),XNDELAY,timeout,NULL);
00479 }
00480 
00481 static inline void xnpod_suspend_self (void) {
00482     xnpod_suspend_thread(xnpod_current_thread(),XNSUSP,XN_INFINITE,NULL);
00483 }
00484 
00485 static inline void xnpod_delete_self (void) {
00486     xnpod_delete_thread(xnpod_current_thread());
00487 }
00488 
00489 #ifdef __cplusplus
00490 }
00491 #endif
00492 
00495 #endif /* !_RTAI_NUCLEUS_POD_H */

Generated on Wed Jun 22 22:54:02 2005 for RTAI Fusion API by  doxygen 1.4.1