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
00063 #define XNDREORD 0x00000001
00064
00065
00066 #define XNRPRIO 0x00000002
00067 #define XNTIMED 0x00000004
00068 #define XNTMSET 0x00000008
00069 #define XNTMPER 0x00000010
00070 #define XNFATAL 0x00000020
00071 #define XNPIDLE 0x00000040
00072
00073
00074 #define XNKCOUT 0x80000000
00075 #define XNHTICK 0x40000000
00076 #define XNSCHEDMASK ~(XNKCOUT|XNHTICK)
00077
00078
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
00089 #define XNPOD_THREAD_CONTEXT 0x1
00090 #define XNPOD_INTERRUPT_CONTEXT 0x2
00091 #define XNPOD_HOOK_CONTEXT 0x4
00092 #define XNPOD_ROOT_CONTEXT 0x8
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
00105
00106
00107 #define XNPOD_SCHEDFIFO 0x0
00108 #define XNPOD_SCHEDLIFO 0x1
00109 #define XNPOD_NOSWITCH 0x2
00110
00111
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
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
00214
00215 #ifdef CONFIG_RTAI_OPT_TIMESTAMPS
00216 xntimes_t timestamps;
00217 #endif
00218
00219 } xnpod_t;
00220
00221 extern xnpod_t *nkpod;
00222
00223 #ifdef CONFIG_SMP
00224 extern xnlock_t nklock;
00225 #endif
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
00250
00251 static inline int xnpod_get_qdir (xnpod_t *pod) {
00252
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
00270
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
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
00358 return nkpod->tickvalue;
00359 }
00360
00361 static inline xntime_t xnpod_ticks2ns (xnticks_t ticks) {
00362
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
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
00490
00491 #ifdef __cplusplus
00492 }
00493 #endif
00494
00497 #endif