rtai-core/include/xenomai/pod.h

Go to the documentation of this file.
00001 
00051 #ifndef _xenomai_pod_h
00052 #define _xenomai_pod_h
00053 
00057 #include "xenomai/thread.h"
00058 
00059 /* Creation flags */
00060 #define XNDREORD 0x00000001     /* Don't reorder pend queues upon prio change */
00061 
00062 /* Status flags */
00063 #define XNRPRIO  0x00000002     /* Reverse priority scheme */
00064 #define XNTIMED  0x00000004     /* Timer started */
00065 #define XNTMSET  0x00000008     /* Pod time has been set */
00066 #define XNTMPER  0x00000010     /* Periodic timing */
00067 #define XNSCHED  0x00000020     /* Pod needs rescheduling */
00068 #define XNFATAL  0x00000040     /* Pod encountered a fatal error */
00069 #define XNKCOUT  0x00000080     /* Kernel callout context */
00070 
00071 /* These flags are available to the real-time interfaces */
00072 #define XNPOD_SPARE0  0x01000000
00073 #define XNPOD_SPARE1  0x02000000
00074 #define XNPOD_SPARE2  0x04000000
00075 #define XNPOD_SPARE3  0x08000000
00076 #define XNPOD_SPARE4  0x10000000
00077 #define XNPOD_SPARE5  0x20000000
00078 #define XNPOD_SPARE6  0x40000000
00079 #define XNPOD_SPARE7  0x80000000
00080 
00081 /* Flags for context checking */
00082 #define XNPOD_THREAD_CONTEXT     0x1 /* Regular thread */
00083 #define XNPOD_INTERRUPT_CONTEXT  0x2 /* Interrupt service thread */
00084 #define XNPOD_HOOK_CONTEXT       0x4 /* Nanokernel hook */
00085 
00086 #define XNPOD_NORMAL_EXIT  0x0
00087 #define XNPOD_FATAL_EXIT   0x1
00088 
00089 #define XNPOD_DEFAULT_TICK         XNARCH_DEFAULT_TICK
00090 #define XNPOD_DEFAULT_TICKHANDLER  (&xnpod_announce_tick)
00091 
00092 #define XNPOD_HEAPSIZE  (128 * 1024)
00093 #define XNPOD_PAGESIZE  512
00094 #define XNPOD_RUNPRI    0x80000000 /* Placeholder for "stdthread priority" */
00095 
00096 /* Flags for xnpod_schedule_runnable() */
00097 #define XNPOD_SCHEDFIFO 0x0
00098 #define XNPOD_SCHEDLIFO 0x1
00099 #define XNPOD_NOSWITCH  0x2
00100 
00101 /* Normal root thread priority == min_std_prio - 1 */
00102 #define XNPOD_ROOT_PRIO_BASE   ((nkpod)->root_prio_base)
00103 
00104 /* Idle svc thread priority == min_std_prio - 2 */
00105 #define XNPOD_ISVC_PRIO_IDLE     ((nkpod)->isvc_prio_idle)
00106 
00107 /* max_std_prio + 1 <= prio < max_std_prio + max_irq_prio + 1 */
00108 #define XNPOD_ISVC_PRIO_BASE(iprio) \
00109 xnpod_get_maxprio(nkpod,iprio + 1)
00110 
00115 typedef struct xnsched {
00116 
00117     xnqueue_t suspendq;         
00119     xnpqueue_t readyq;          
00121     xnthread_t rootcb;          
00123     xnthread_t *runthread;      
00125     xnthread_t *usrthread;      
00127 #ifdef CONFIG_RTAI_FPU_SUPPORT
00128     xnthread_t *fpuholder;      
00129 #endif /* CONFIG_RTAI_FPU_SUPPORT */
00130 
00131     unsigned inesting;          
00133 } xnsched_t;
00134 
00135 struct xnsynch;
00136 struct xnintr;
00137 struct xnmutex;
00138 
00145 typedef struct xnpod {
00146 
00147     xnsched_t sched;            
00149     xnflags_t status;           
00151     xnqueue_t threadq;          
00153     xnqueue_t timerwheel[XNTIMER_WHEELSIZE]; 
00155     xnticks_t jiffies;          
00157     xnticks_t wallclock;        
00159     atomic_counter_t schedlck;  
00161     xnqueue_t tstartq,          
00162               tswitchq,         
00163               tdeleteq;         
00165     int minpri,                 
00166         maxpri;                 
00168     int root_prio_base,         
00169         isvc_prio_idle;         
00171     u_long tickvalue;           
00173     xnticks_t ticks2sec;        
00175     xntimer_t htimer;           
00177     struct {
00178         void (*tickhandler)(struct xnintr *, int hits); 
00179         void (*shutdown)(int xtype); 
00180         void (*settime)(xnticks_t newtime); 
00181         int (*faulthandler)(xnarch_fltinfo_t *fltinfo); 
00182     } svctable;                 
00184     void (*schedhook)(xnthread_t *thread,
00185                       xnflags_t mask); 
00187     u_long latency;     /* !< Mean scheduling latency (in CPU ticks,
00188                            aperiodic timing only). */
00189 } xnpod_t;
00190 
00191 extern xnpod_t *nkpod;
00192 
00193 #define xnprintf       xnarch_printf
00194 #define xnmalloc(size) xnheap_alloc(&kheap,size,XNHEAP_WAIT)
00195 #define xnfree(ptr)    xnheap_free(&kheap,ptr)
00196 
00197 #ifdef __cplusplus
00198 extern "C" {
00199 #endif
00200 
00201 void xnpod_schedule_runnable(xnthread_t *thread,
00202                              int flags);
00203 
00204 void xnpod_renice_thread_inner(xnthread_t *thread,
00205                                int prio,
00206                                int propagate);
00207 
00208 #ifdef CONFIG_RTAI_FPU_SUPPORT
00209 void xnpod_switch_fpu(void);
00210 #endif /* CONFIG_RTAI_FPU_SUPPORT */
00211 
00212 static inline int xnpod_get_qdir (xnpod_t *pod) {
00213     /* Returns the queuing direction of threads for a given pod */
00214     return testbits(pod->status,XNRPRIO) ? xnqueue_up : xnqueue_down;
00215 }
00216 
00217 static inline int xnpod_get_minprio (xnpod_t *pod, int incr) {
00218     return xnpod_get_qdir(pod) == xnqueue_up ?
00219         pod->minpri + incr :
00220         pod->minpri - incr;
00221 }
00222 
00223 static inline int xnpod_get_maxprio (xnpod_t *pod, int incr) {
00224     return xnpod_get_qdir(pod) == xnqueue_up ?
00225         pod->maxpri - incr :
00226         pod->maxpri + incr;
00227 }
00228 
00229 static inline int xnpod_priocompare (int inprio, int outprio) {
00230     /* Returns a negative, null or positive value whether inprio is
00231        lower than, equal to or greater than outprio. */
00232     int delta = inprio - outprio;
00233     return testbits(nkpod->status,XNRPRIO) ? -delta : delta;
00234 }
00235 
00236 static inline void xnpod_renice_isvc (xnthread_t *thread, int prio) {
00237 
00238     spl_t s;
00239 
00240     splhigh(s);
00241     thread->cprio = prio;
00242     xnpod_schedule_runnable(thread,XNPOD_SCHEDFIFO);
00243     splexit(s);
00244 }
00245 
00246 static inline void xnpod_renice_root (int prio) {
00247 
00248     spl_t s;
00249 
00250     splhigh(s);
00251     nkpod->sched.rootcb.cprio = prio;
00252     xnpod_schedule_runnable(&nkpod->sched.rootcb,XNPOD_SCHEDLIFO|XNPOD_NOSWITCH);
00253     splexit(s);
00254 }
00255 
00256     /* -- Beginning of the exported interface */
00257 
00258 #define xnpod_current_sched() \
00259     (&nkpod->sched)
00260 
00261 #define xnpod_interrupt_p() \
00262     (xnpod_current_sched()->inesting > 0)
00263 
00264 #define xnpod_callout_p() \
00265     (!!testbits(nkpod->status,XNKCOUT))
00266 
00267 #define xnpod_asynch_p() \
00268     (xnpod_interrupt_p() || xnpod_callout_p())
00269 
00270 #define xnpod_current_thread() \
00271     (xnpod_current_sched()->runthread)
00272 
00273 #define xnpod_current_root() \
00274     (&xnpod_current_sched()->rootcb)
00275 
00276 #define xnpod_current_p(thread) \
00277     (xnpod_current_thread() == (thread))
00278 
00279 #define xnpod_locked_p() \
00280     (!!testbits(xnpod_current_thread()->status,XNLOCK))
00281 
00282 #define xnpod_pendable_p() \
00283     (!(xnpod_asynch_p() || testbits(xnpod_current_thread()->status,XNLOCK)))
00284 
00285 #define xnpod_root_p() \
00286     (!!testbits(xnpod_current_thread()->status,XNROOT))
00287 
00288 #define xnpod_shadow_p() \
00289     (!!testbits(xnpod_current_thread()->status,XNSHADOW))
00290 
00291 #define xnpod_userspace_p() \
00292     (!!testbits(xnpod_current_thread()->status,XNROOT|XNSHADOW))
00293 
00294 #define xnpod_idle_p() xnpod_root_p()
00295 
00296 #define xnpod_timeset_p() \
00297     (!!testbits(nkpod->status,XNTMSET))
00298 
00299 static inline xnticks_t xnpod_get_ticks2sec (void) {
00300     return nkpod->ticks2sec;
00301 }
00302 
00303 static inline u_long xnpod_get_tickval (void) {
00304     /* Returns the duration of a tick in nanoseconds */
00305     return nkpod->tickvalue;
00306 }
00307 
00308 static inline xntime_t xnpod_ticks2time (xnticks_t ticks) {
00309     /* Convert a count of ticks in nanoseconds */
00310     return ticks * xnpod_get_tickval();
00311 }
00312 
00313 static inline xnticks_t xnpod_time2ticks (xntime_t t) {
00314     unsigned long r;
00315     return xnarch_ulldiv(t,xnpod_get_tickval(),&r);
00316 }
00317 
00318 int xnpod_init(xnpod_t *pod,
00319                int minpri,
00320                int maxpri,
00321                xnflags_t flags);
00322 
00323 int xnpod_start_timer(u_long nstick,
00324                       void (*handler)(struct xnintr *,
00325                                       int hits));
00326 
00327 void xnpod_stop_timer(void);
00328 
00329 void xnpod_shutdown(int xtype);
00330 
00331 int xnpod_init_thread(xnthread_t *thread,
00332                       const char *name,
00333                       int prio,
00334                       xnflags_t flags,
00335                       unsigned stacksize,
00336                       void *adcookie,
00337                       unsigned magic);
00338 
00339 void xnpod_start_thread(xnthread_t *thread,
00340                         xnflags_t mode,
00341                         int imask,
00342                         void (*entry)(void *cookie),
00343                         void *cookie);
00344 
00345 void xnpod_restart_thread(xnthread_t *thread,
00346                           struct xnmutex *imutex);
00347 
00348 void xnpod_delete_thread(xnthread_t *thread,
00349                          struct xnmutex *imutex);
00350 
00351 xnflags_t xnpod_set_thread_mode(xnthread_t *thread,
00352                                 xnflags_t clrmask,
00353                                 xnflags_t setmask);
00354 
00355 int xnpod_suspend_thread(xnthread_t *thread,
00356                          xnflags_t mask,
00357                          xnticks_t timeout,
00358                          struct xnsynch *resource,
00359                          struct xnmutex *imutex);
00360 
00361 void xnpod_resume_thread(xnthread_t *thread,
00362                          xnflags_t mask);
00363 
00364 void xnpod_unblock_thread(xnthread_t *thread);
00365 
00366 void xnpod_renice_thread(xnthread_t *thread,
00367                          int prio);
00368 
00369 void xnpod_rotate_readyq(int prio);
00370 
00371 void xnpod_schedule(struct xnmutex *imutex);
00372 
00373 static inline void xnpod_lock_sched (void) {
00374 
00375     /* Don't swap these two lines... */
00376     xnarch_atomic_inc(&nkpod->schedlck);
00377     setbits(xnpod_current_sched()->runthread->status,XNLOCK);
00378 }
00379 
00380 static inline void xnpod_unlock_sched (void) {
00381 
00382     if (xnarch_atomic_dec_and_test(&nkpod->schedlck))
00383         {
00384         clrbits(xnpod_current_sched()->runthread->status,XNLOCK);
00385 
00386         if (testbits(nkpod->status,XNSCHED))
00387             xnpod_schedule(NULL);
00388         }
00389 }
00390 
00391 void xnpod_announce_tick(struct xnintr *intr,
00392                          int hits);
00393 
00394 void xnpod_activate_rr(xnticks_t quantum);
00395 
00396 void xnpod_deactivate_rr(void);
00397 
00398 void xnpod_set_time(xnticks_t newtime);
00399 
00400 xnticks_t xnpod_get_time(void);
00401 
00402 static inline xntime_t xnpod_get_cpu_time(void) {
00403     return xnarch_get_cpu_time();
00404 }
00405 
00406 int xnpod_add_hook(int type,
00407                    void (*routine)(xnthread_t *));
00408 
00409 int xnpod_remove_hook(int type,
00410                       void (*routine)(xnthread_t *));
00411 
00412 void xnpod_check_context(int mask);
00413 
00414 static inline void xnpod_yield (void) {
00415     xnpod_resume_thread(xnpod_current_thread(),0);
00416     xnpod_schedule(NULL);
00417 }
00418 
00419 static inline void xnpod_delay (xnticks_t timeout) {
00420     xnpod_suspend_thread(xnpod_current_thread(),XNDELAY,timeout,NULL,NULL);
00421 }
00422 
00423 static inline void xnpod_suspend_self (struct xnmutex *imutex) {
00424     xnpod_suspend_thread(xnpod_current_thread(),XNSUSP,XN_INFINITE,NULL,imutex);
00425 }
00426 
00427 static inline void xnpod_delete_self (struct xnmutex *imutex) {
00428     xnpod_delete_thread(xnpod_current_thread(),imutex);
00429 }
00430 
00431 #ifdef __cplusplus
00432 }
00433 #endif
00434 
00437 #endif /* !_xenomai_pod_h */

Generated on Sat Jul 24 19:36:04 2004 for RTAI API by doxygen 1.3.4