pod.h

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

Generated on Mon Dec 13 09:49:49 2004 for RTAI API by  doxygen 1.3.9.1