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
00047
00048 #define XNKCOUT 0x80000000
00049 #define XNHTICK 0x40000000
00050
00051
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
00062 #define XNPOD_THREAD_CONTEXT 0x1
00063 #define XNPOD_INTERRUPT_CONTEXT 0x2
00064 #define XNPOD_HOOK_CONTEXT 0x4
00065 #define XNPOD_ROOT_CONTEXT 0x8
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
00078
00079
00080 #define XNPOD_SCHEDFIFO 0x0
00081 #define XNPOD_SCHEDLIFO 0x1
00082 #define XNPOD_NOSWITCH 0x2
00083
00084
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
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
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
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;
00211 xnticks_t watchdog_reload;
00212 int watchdog_armed;
00213 #endif
00214
00215 #ifdef __RTAI_SIM__
00216 void (*schedhook)(xnthread_t *thread,
00217 xnflags_t mask);
00218 #endif
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
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
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
00260 static inline void xnpod_reset_watchdog (void)
00261 {
00262 }
00263 #endif
00264
00265 static inline int xnpod_get_qdir (xnpod_t *pod)
00266 {
00267
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
00288
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
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
00364 return nkpod->tickvalue;
00365 }
00366
00367 static inline xntime_t xnpod_ticks2ns (xnticks_t ticks) {
00368
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
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