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
00037 #define XNDREORD 0x00000001
00038
00039
00040 #define XNRPRIO 0x00000002
00041 #define XNTIMED 0x00000004
00042 #define XNTMSET 0x00000008
00043 #define XNTMPER 0x00000010
00044 #define XNFATAL 0x00000020
00045 #define XNPIDLE 0x00000040
00046 #define XNTLOCK 0x00000080
00047
00048
00049 #define XNKCOUT 0x80000000
00050 #define XNHTICK 0x40000000
00051
00052
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
00063 #define XNPOD_THREAD_CONTEXT 0x1
00064 #define XNPOD_INTERRUPT_CONTEXT 0x2
00065 #define XNPOD_HOOK_CONTEXT 0x4
00066 #define XNPOD_ROOT_CONTEXT 0x8
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
00079
00080
00081 #define XNPOD_SCHEDFIFO 0x0
00082 #define XNPOD_SCHEDLIFO 0x1
00083 #define XNPOD_NOSWITCH 0x2
00084
00085
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
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
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
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
00146 #define xnsched_cpu(__sched__) (0)
00147 #endif
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;
00221 xnticks_t watchdog_reload;
00222 int watchdog_armed;
00223 #endif
00224
00225 #ifdef __RTAI_SIM__
00226 void (*schedhook)(xnthread_t *thread,
00227 xnflags_t mask);
00228 #endif
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
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
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
00272 static inline void xnpod_reset_watchdog (void)
00273 {
00274 }
00275 #endif
00276
00277 static inline int xnpod_get_qdir (xnpod_t *pod)
00278 {
00279
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
00300
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
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
00376 return nkpod->tickvalue;
00377 }
00378
00379 static inline xntime_t xnpod_ticks2ns (xnticks_t ticks) {
00380
00381 #ifdef CONFIG_RTAI_HW_PERIODIC_TIMER
00382 return ticks * xnpod_get_tickval();
00383 #else
00384 return ticks;
00385 #endif
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
00392 return t;
00393 #endif
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
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