00001
00028 #ifndef _XENO_NUCLEUS_POD_H
00029 #define _XENO_NUCLEUS_POD_H
00030
00034 #include <nucleus/thread.h>
00035 #include <nucleus/intr.h>
00036
00037
00038 #define XNREUSE 0x00000001
00039
00040
00041 #define XNRPRIO 0x00000002
00042 #define XNTIMED 0x00000004
00043 #define XNTMSET 0x00000008
00044 #define XNTMPER 0x00000010
00045 #define XNFATAL 0x00000020
00046 #define XNPIDLE 0x00000040
00047 #define XNTLOCK 0x00000080
00048
00049
00050 #define XNKCOUT 0x80000000
00051 #define XNHTICK 0x40000000
00052 #define XNRPICK 0x20000000
00053
00054
00055 #define XNPOD_SPARE0 0x01000000
00056 #define XNPOD_SPARE1 0x02000000
00057 #define XNPOD_SPARE2 0x04000000
00058 #define XNPOD_SPARE3 0x08000000
00059 #define XNPOD_SPARE4 0x10000000
00060 #define XNPOD_SPARE5 0x20000000
00061 #define XNPOD_SPARE6 0x40000000
00062 #define XNPOD_SPARE7 0x80000000
00063
00064
00065 #define XNPOD_THREAD_CONTEXT 0x1
00066 #define XNPOD_INTERRUPT_CONTEXT 0x2
00067 #define XNPOD_HOOK_CONTEXT 0x4
00068 #define XNPOD_ROOT_CONTEXT 0x8
00069
00070 #define XNPOD_NORMAL_EXIT 0x0
00071 #define XNPOD_FATAL_EXIT 0x1
00072
00073 #define XNPOD_DEFAULT_TICKHANDLER (&xnpod_announce_tick)
00074
00075 #define XNPOD_ALL_CPUS XNARCH_CPU_MASK_ALL
00076
00077 #define XNPOD_HEAPSIZE (CONFIG_XENO_OPT_SYS_HEAPSZ * 1024)
00078 #define XNPOD_PAGESIZE 512
00079
00080 #define XNPOD_RUNPRIO 0x80000000
00081
00082
00083 #define XNPOD_SCHEDFIFO 0x0
00084 #define XNPOD_SCHEDLIFO 0x1
00085 #define XNPOD_NOSWITCH 0x2
00086
00087
00088 #define XNPOD_ROOT_PRIO_BASE ((nkpod)->root_prio_base)
00089
00090 #ifdef CONFIG_XENO_OPT_SCALABLE_SCHED
00091 typedef xnmlqueue_t xnsched_queue_t;
00092 #define sched_initpq initmlq
00093 #define sched_emptypq_p emptymlq_p
00094 #define sched_insertpql insertmlql
00095 #define sched_insertpqf insertmlqf
00096 #define sched_appendpq appendmlq
00097 #define sched_prependpq prependmlq
00098 #define sched_removepq removemlq
00099 #define sched_getheadpq getheadmlq
00100 #define sched_getpq getmlq
00101 #define sched_findpqh findmlqh
00102 #else
00103 typedef xnpqueue_t xnsched_queue_t;
00104 #define sched_initpq(pqslot, qdir, minp, maxp) initpq(pqslot, qdir)
00105 #define sched_emptypq_p emptypq_p
00106 #define sched_insertpql insertpql
00107 #define sched_insertpqf insertpqf
00108 #define sched_appendpq appendpq
00109 #define sched_prependpq prependpq
00110 #define sched_removepq removepq
00111 #define sched_getheadpq getheadpq
00112 #define sched_getpq getpq
00113 #define sched_findpqh findpqh
00114 #endif
00115
00116 #define XNPOD_FATAL_BUFSZ 16384
00117
00122 typedef struct xnsched {
00123
00124 xnflags_t status;
00126 xnthread_t *runthread;
00128 xnarch_cpumask_t resched;
00130 xnsched_queue_t readyq;
00132 xntimerq_t timerqueue;
00133 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00134 xnqueue_t timerwheel[XNTIMER_WHEELSIZE];
00135 #endif
00136
00137 volatile unsigned inesting;
00139 #ifdef CONFIG_XENO_HW_FPU
00140 xnthread_t *fpuholder;
00141 #endif
00142
00143 #ifdef CONFIG_XENO_OPT_WATCHDOG
00144 xntimer_t wd_timer;
00145 int wd_count;
00146 #endif
00147
00148 xnthread_t rootcb;
00150 #ifdef CONFIG_XENO_OPT_STATS
00151 xnticks_t last_account_switch;
00153 xnstat_runtime_t *current_account;
00154 #endif
00155
00156 } xnsched_t;
00157
00158 #ifdef CONFIG_SMP
00159 #define xnsched_cpu(__sched__) \
00160 ((__sched__) - &nkpod->sched[0])
00161 #else
00162 #define xnsched_cpu(__sched__) ({ (void)__sched__; 0; })
00163 #endif
00164
00165 #define xnsched_resched_mask() \
00166 (xnpod_current_sched()->resched)
00167
00168 #define xnsched_resched_p() \
00169 (!xnarch_cpus_empty(xnsched_resched_mask()))
00170
00171 #define xnsched_tst_resched(__sched__) \
00172 xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00173
00174 #define xnsched_set_resched(__sched__) \
00175 xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00176
00177 #define xnsched_clr_resched(__sched__) \
00178 xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00179
00180 #define xnsched_clr_mask(__sched__) \
00181 xnarch_cpus_clear((__sched__)->resched)
00182
00183 struct xnsynch;
00184 struct xnintr;
00185
00192 struct xnpod {
00193
00194 xnflags_t status;
00196 xnticks_t jiffies;
00198 xnticks_t wallclock_offset;
00201 xntimer_t htimer;
00203 xnsched_t sched[XNARCH_NR_CPUS];
00205 xnqueue_t threadq;
00206 int threadq_rev;
00208 xnqueue_t tstartq,
00209 tswitchq,
00210 tdeleteq;
00212 int loprio,
00213 hiprio;
00215 int root_prio_base;
00217 u_long tickvalue;
00219 u_long ticks2sec;
00222 int refcnt;
00224 #ifdef __KERNEL__
00225 atomic_counter_t timerlck;
00226 #endif
00227
00228 struct {
00229 void (*settime) (xnticks_t newtime);
00230 int (*faulthandler) (xnarch_fltinfo_t *fltinfo);
00231 int (*unload) (void);
00232 } svctable;
00234 #ifdef __XENO_SIM__
00235 void (*schedhook) (xnthread_t *thread, xnflags_t mask);
00236 #endif
00237 };
00238
00239 typedef struct xnpod xnpod_t;
00240
00241 extern xnpod_t *nkpod;
00242
00243 #ifdef CONFIG_SMP
00244 extern xnlock_t nklock;
00245 #endif
00246
00247 extern u_long nkschedlat;
00248
00249 extern u_long nktimerlat;
00250
00251 extern u_long nktickdef;
00252
00253 extern char *nkmsgbuf;
00254
00255 #ifdef __cplusplus
00256 extern "C" {
00257 #endif
00258
00259 void xnpod_schedule_runnable(xnthread_t *thread, int flags);
00260
00261 void xnpod_renice_thread_inner(xnthread_t *thread, int prio, int propagate);
00262
00263 #ifdef CONFIG_XENO_HW_FPU
00264 void xnpod_switch_fpu(xnsched_t *sched);
00265 #endif
00266
00267 #ifdef CONFIG_XENO_OPT_WATCHDOG
00268 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00269 {
00270 sched->wd_count = 0;
00271 }
00272 #else
00273 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00274 {
00275 }
00276 #endif
00277
00278
00279
00280 #define xnpod_sched_slot(cpu) \
00281 (&nkpod->sched[cpu])
00282
00283 #define xnpod_current_sched() \
00284 xnpod_sched_slot(xnarch_current_cpu())
00285
00286 #define xnpod_interrupt_p() \
00287 (xnpod_current_sched()->inesting > 0)
00288
00289 #define xnpod_callout_p() \
00290 (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00291
00292 #define xnpod_asynch_p() \
00293 (xnpod_interrupt_p() || xnpod_callout_p())
00294
00295 #define xnpod_current_thread() \
00296 (xnpod_current_sched()->runthread)
00297
00298 #define xnpod_current_root() \
00299 (&xnpod_current_sched()->rootcb)
00300
00301 #ifdef CONFIG_XENO_OPT_PERVASIVE
00302 #define xnpod_current_p(thread) \
00303 ({ int __shadow_p = xnthread_test_state(thread, XNSHADOW); \
00304 int __curr_p = __shadow_p ? xnshadow_thread(current) == thread \
00305 : thread == xnpod_current_thread(); \
00306 __curr_p;})
00307 #else
00308 #define xnpod_current_p(thread) \
00309 (xnpod_current_thread() == (thread))
00310 #endif
00311
00312 #define xnpod_locked_p() \
00313 (!!xnthread_test_state(xnpod_current_thread(),XNLOCK))
00314
00315 #define xnpod_unblockable_p() \
00316 (xnpod_asynch_p() || xnthread_test_state(xnpod_current_thread(),XNROOT))
00317
00318 #define xnpod_root_p() \
00319 (!!xnthread_test_state(xnpod_current_thread(),XNROOT))
00320
00321 #define xnpod_shadow_p() \
00322 (!!xnthread_test_state(xnpod_current_thread(),XNSHADOW))
00323
00324 #define xnpod_userspace_p() \
00325 (!!xnthread_test_state(xnpod_current_thread(),XNROOT|XNSHADOW))
00326
00327 #define xnpod_primary_p() \
00328 (!(xnpod_asynch_p() || xnpod_root_p()))
00329
00330 #define xnpod_secondary_p() xnpod_root_p()
00331
00332 #define xnpod_idle_p() xnpod_root_p()
00333
00334 #define xnpod_timeset_p() (!!testbits(nkpod->status,XNTMSET))
00335
00336 static inline void xnpod_renice_root(int prio)
00337 {
00338 xnthread_t *rootcb;
00339 spl_t s;
00340
00341 xnlock_get_irqsave(&nklock, s);
00342 rootcb = xnpod_current_root();
00343 rootcb->cprio = prio;
00344 xnpod_schedule_runnable(rootcb, XNPOD_SCHEDLIFO | XNPOD_NOSWITCH);
00345 xnlock_put_irqrestore(&nklock, s);
00346 }
00347
00348 static inline int xnpod_root_priority(void)
00349 {
00350 return xnthread_current_priority(xnpod_current_root());
00351 }
00352
00353 static inline int xnpod_get_qdir(xnpod_t *pod)
00354 {
00355
00356 return testbits(pod->status, XNRPRIO) ? xnqueue_up : xnqueue_down;
00357 }
00358
00359 static inline int xnpod_compare_prio(int inprio, int outprio)
00360 {
00361
00362
00363 int delta = inprio - outprio;
00364 return testbits(nkpod->status, XNRPRIO) ? -delta : delta;
00365 }
00366
00367 static inline int xnpod_rescale_prio(int prio)
00368 {
00369 return xnpod_get_qdir(nkpod) == xnqueue_up ?
00370 nkpod->loprio - prio : nkpod->hiprio - prio - 1;
00371 }
00372
00373 static inline u_long xnpod_get_ticks2sec(void)
00374 {
00375 return nkpod->ticks2sec;
00376 }
00377
00378 static inline u_long xnpod_get_tickval(void)
00379 {
00380
00381 return nkpod->tickvalue;
00382 }
00383
00384 static inline xntime_t xnpod_ticks2ns(xnticks_t ticks)
00385 {
00386
00387 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00388 return ticks * xnpod_get_tickval();
00389 #else
00390 return ticks;
00391 #endif
00392 }
00393
00394 static inline xnticks_t xnpod_ns2ticks(xntime_t t)
00395 {
00396 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00397 return xnarch_ulldiv(t, xnpod_get_tickval(), NULL);
00398 #else
00399 return t;
00400 #endif
00401 }
00402
00403 int xnpod_init(xnpod_t *pod, int loprio, int hiprio, xnflags_t flags);
00404
00405 int xnpod_start_timer(u_long nstick, xnisr_t tickhandler);
00406
00407 void xnpod_stop_timer(void);
00408
00409 int xnpod_reset_timer(void);
00410
00411 void xnpod_shutdown(int xtype);
00412
00413 int xnpod_init_thread(xnthread_t *thread,
00414 const char *name,
00415 int prio, xnflags_t flags, unsigned stacksize);
00416
00417 int xnpod_start_thread(xnthread_t *thread,
00418 xnflags_t mode,
00419 int imask,
00420 xnarch_cpumask_t affinity,
00421 void (*entry) (void *cookie), void *cookie);
00422
00423 void xnpod_restart_thread(xnthread_t *thread);
00424
00425 void xnpod_delete_thread(xnthread_t *thread);
00426
00427 void xnpod_abort_thread(xnthread_t *thread);
00428
00429 xnflags_t xnpod_set_thread_mode(xnthread_t *thread,
00430 xnflags_t clrmask, xnflags_t setmask);
00431
00432 void xnpod_suspend_thread(xnthread_t *thread,
00433 xnflags_t mask,
00434 xnticks_t timeout, struct xnsynch *resource);
00435
00436 void xnpod_resume_thread(xnthread_t *thread, xnflags_t mask);
00437
00438 int xnpod_unblock_thread(xnthread_t *thread);
00439
00440 void xnpod_renice_thread(xnthread_t *thread, 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 xnthread_t *runthread = xnpod_current_sched()->runthread;
00453 spl_t s;
00454
00455 xnlock_get_irqsave(&nklock, s);
00456
00457 if (xnthread_lock_count(runthread)++ == 0)
00458 xnthread_set_state(runthread, XNLOCK);
00459
00460 xnlock_put_irqrestore(&nklock, s);
00461 }
00462
00463 static inline void xnpod_unlock_sched(void)
00464 {
00465 xnthread_t *runthread = xnpod_current_sched()->runthread;
00466 spl_t s;
00467
00468 xnlock_get_irqsave(&nklock, s);
00469
00470 if (--xnthread_lock_count(runthread) == 0) {
00471 xnthread_clear_state(runthread, XNLOCK);
00472 xnpod_schedule();
00473 }
00474
00475 xnlock_put_irqrestore(&nklock, s);
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, xnticks_t period);
00488
00489 int xnpod_wait_thread_period(unsigned long *overruns_r);
00490
00491 xnticks_t xnpod_get_time(void);
00492
00493 static inline xntime_t xnpod_get_cpu_time(void)
00494 {
00495 return xnarch_get_cpu_time();
00496 }
00497
00498 int xnpod_add_hook(int type, void (*routine) (xnthread_t *));
00499
00500 int xnpod_remove_hook(int type, void (*routine) (xnthread_t *));
00501
00502 void xnpod_check_context(int mask);
00503
00504 static inline void xnpod_yield(void)
00505 {
00506 xnpod_resume_thread(xnpod_current_thread(), 0);
00507 xnpod_schedule();
00508 }
00509
00510 static inline void xnpod_delay(xnticks_t timeout)
00511 {
00512 xnpod_suspend_thread(xnpod_current_thread(), XNDELAY, timeout, NULL);
00513 }
00514
00515 static inline void xnpod_suspend_self(void)
00516 {
00517 xnpod_suspend_thread(xnpod_current_thread(), XNSUSP, XN_INFINITE, NULL);
00518 }
00519
00520 static inline void xnpod_delete_self(void)
00521 {
00522 xnpod_delete_thread(xnpod_current_thread());
00523 }
00524
00525 #ifdef __cplusplus
00526 }
00527 #endif
00528
00531 #endif