00001
00051 #ifndef _xenomai_pod_h
00052 #define _xenomai_pod_h
00053
00057 #include "xenomai/thread.h"
00058
00059
00060 #define XNDREORD 0x00000001
00061
00062
00063 #define XNRPRIO 0x00000002
00064 #define XNTIMED 0x00000004
00065 #define XNTMSET 0x00000008
00066 #define XNTMPER 0x00000010
00067 #define XNSCHED 0x00000020
00068 #define XNFATAL 0x00000040
00069 #define XNKCOUT 0x00000080
00070
00071
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
00082 #define XNPOD_THREAD_CONTEXT 0x1
00083 #define XNPOD_INTERRUPT_CONTEXT 0x2
00084 #define XNPOD_HOOK_CONTEXT 0x4
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
00095
00096
00097 #define XNPOD_SCHEDFIFO 0x0
00098 #define XNPOD_SCHEDLIFO 0x1
00099 #define XNPOD_NOSWITCH 0x2
00100
00101
00102 #define XNPOD_ROOT_PRIO_BASE ((nkpod)->root_prio_base)
00103
00104
00105 #define XNPOD_ISVC_PRIO_IDLE ((nkpod)->isvc_prio_idle)
00106
00107
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
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;
00188
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
00211
00212 static inline int xnpod_get_qdir (xnpod_t *pod) {
00213
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
00231
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
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
00305 return nkpod->tickvalue;
00306 }
00307
00308 static inline xntime_t xnpod_ticks2time (xnticks_t ticks) {
00309
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
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