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
00053
00054 #define XNPOD_SPARE0 0x01000000
00055 #define XNPOD_SPARE1 0x02000000
00056 #define XNPOD_SPARE2 0x04000000
00057 #define XNPOD_SPARE3 0x08000000
00058 #define XNPOD_SPARE4 0x10000000
00059 #define XNPOD_SPARE5 0x20000000
00060 #define XNPOD_SPARE6 0x40000000
00061 #define XNPOD_SPARE7 0x80000000
00062
00063
00064 #define XNPOD_THREAD_CONTEXT 0x1
00065 #define XNPOD_INTERRUPT_CONTEXT 0x2
00066 #define XNPOD_HOOK_CONTEXT 0x4
00067 #define XNPOD_ROOT_CONTEXT 0x8
00068
00069 #define XNPOD_NORMAL_EXIT 0x0
00070 #define XNPOD_FATAL_EXIT 0x1
00071
00072 #define XNPOD_DEFAULT_TICKHANDLER (&xnpod_announce_tick)
00073
00074 #define XNPOD_ALL_CPUS XNARCH_CPU_MASK_ALL
00075
00076 #define XNPOD_HEAPSIZE (CONFIG_XENO_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_XENO_OPT_SCALABLE_SCHED
00089 typedef xnmlqueue_t xnsched_queue_t;
00090 #define sched_initpq initmlq
00091 #define sched_emptypq_p emptymlq_p
00092 #define sched_insertpql insertmlql
00093 #define sched_insertpqf insertmlqf
00094 #define sched_appendpq appendmlq
00095 #define sched_prependpq prependmlq
00096 #define sched_removepq removemlq
00097 #define sched_getheadpq getheadmlq
00098 #define sched_getpq getmlq
00099 #define sched_findpqh findmlqh
00100 #else
00101 typedef xnpqueue_t xnsched_queue_t;
00102 #define sched_initpq initpq
00103 #define sched_emptypq_p emptypq_p
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 xntimerq_t timerqueue;
00131 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00132 xnqueue_t timerwheel[XNTIMER_WHEELSIZE];
00133 #endif
00134
00135 volatile unsigned inesting;
00137 #ifdef CONFIG_XENO_HW_FPU
00138 xnthread_t *fpuholder;
00139 #endif
00140
00141 #ifdef CONFIG_XENO_OPT_WATCHDOG
00142 xntimer_t wd_timer;
00143 int wd_count;
00144 #endif
00145
00146 xnthread_t rootcb;
00148 #ifdef CONFIG_XENO_OPT_STATS
00149 xnticks_t last_account_switch;
00151 xnstat_runtime_t *current_account;
00152 #endif
00153
00154 } xnsched_t;
00155
00156 #ifdef CONFIG_SMP
00157 #define xnsched_cpu(__sched__) \
00158 ((__sched__) - &nkpod->sched[0])
00159 #else
00160 #define xnsched_cpu(__sched__) (0)
00161 #endif
00162
00163 #define xnsched_resched_mask() \
00164 (xnpod_current_sched()->resched)
00165
00166 #define xnsched_resched_p() \
00167 (!xnarch_cpus_empty(xnsched_resched_mask()))
00168
00169 #define xnsched_tst_resched(__sched__) \
00170 xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00171
00172 #define xnsched_set_resched(__sched__) \
00173 xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00174
00175 #define xnsched_clr_resched(__sched__) \
00176 xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00177
00178 #define xnsched_clr_mask(__sched__) \
00179 xnarch_cpus_clear((__sched__)->resched)
00180
00181 struct xnsynch;
00182 struct xnintr;
00183
00190 struct xnpod {
00191
00192 xnflags_t status;
00194 xnticks_t jiffies;
00196 xnticks_t wallclock_offset;
00199 xntimer_t htimer;
00201 xnsched_t sched[XNARCH_NR_CPUS];
00203 xnqueue_t threadq;
00204 int threadq_rev;
00206 volatile u_long schedlck;
00208 xnqueue_t tstartq,
00209 tswitchq,
00210 tdeleteq;
00212 int minpri,
00213 maxpri;
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 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 : pod->minpri - incr;
00287 }
00288
00289 static inline int xnpod_get_maxprio(xnpod_t *pod, int incr)
00290 {
00291 return xnpod_get_qdir(pod) == xnqueue_up ?
00292 pod->maxpri - incr : pod->maxpri + incr;
00293 }
00294
00295 static inline int xnpod_compare_prio(int inprio, int outprio)
00296 {
00297
00298
00299 int delta = inprio - outprio;
00300 return testbits(nkpod->status, XNRPRIO) ? -delta : delta;
00301 }
00302
00303 static inline int xnpod_rescale_prio(int prio)
00304 {
00305 return xnpod_get_qdir(nkpod) == xnqueue_up ?
00306 nkpod->minpri - prio : nkpod->maxpri - prio - 1;
00307 }
00308
00309 static inline void xnpod_renice_root(int prio)
00310 {
00311 xnthread_t *rootcb;
00312 spl_t s;
00313
00314 xnlock_get_irqsave(&nklock, s);
00315 rootcb = &nkpod->sched[xnarch_current_cpu()].rootcb;
00316 rootcb->cprio = prio;
00317 xnpod_schedule_runnable(rootcb, XNPOD_SCHEDLIFO | XNPOD_NOSWITCH);
00318 xnlock_put_irqrestore(&nklock, s);
00319 }
00320
00321
00322
00323 #define xnpod_sched_slot(cpu) \
00324 (&nkpod->sched[cpu])
00325
00326 #define xnpod_current_sched() \
00327 xnpod_sched_slot(xnarch_current_cpu())
00328
00329 #define xnpod_interrupt_p() \
00330 (xnpod_current_sched()->inesting > 0)
00331
00332 #define xnpod_callout_p() \
00333 (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00334
00335 #define xnpod_asynch_p() \
00336 (xnpod_interrupt_p() || xnpod_callout_p())
00337
00338 #define xnpod_current_thread() \
00339 (xnpod_current_sched()->runthread)
00340
00341 #define xnpod_current_root() \
00342 (&xnpod_current_sched()->rootcb)
00343
00344 #define xnpod_current_p(thread) \
00345 (xnpod_current_thread() == (thread))
00346
00347 #define xnpod_locked_p() \
00348 (!!xnthread_test_state(xnpod_current_thread(),XNLOCK))
00349
00350 #define xnpod_unblockable_p() \
00351 (xnpod_asynch_p() || xnthread_test_state(xnpod_current_thread(),XNLOCK|XNROOT))
00352
00353 #define xnpod_root_p() \
00354 (!!xnthread_test_state(xnpod_current_thread(),XNROOT))
00355
00356 #define xnpod_shadow_p() \
00357 (!!xnthread_test_state(xnpod_current_thread(),XNSHADOW))
00358
00359 #define xnpod_userspace_p() \
00360 (!!xnthread_test_state(xnpod_current_thread(),XNROOT|XNSHADOW))
00361
00362 #define xnpod_primary_p() \
00363 (!(xnpod_asynch_p() || xnpod_root_p()))
00364
00365 #define xnpod_secondary_p() xnpod_root_p()
00366
00367 #define xnpod_idle_p() xnpod_root_p()
00368
00369 #define xnpod_timeset_p() (!!testbits(nkpod->status,XNTMSET))
00370
00371 static inline u_long xnpod_get_ticks2sec(void)
00372 {
00373 return nkpod->ticks2sec;
00374 }
00375
00376 static inline u_long xnpod_get_tickval(void)
00377 {
00378
00379 return nkpod->tickvalue;
00380 }
00381
00382 static inline xntime_t xnpod_ticks2ns(xnticks_t ticks)
00383 {
00384
00385 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00386 return ticks * xnpod_get_tickval();
00387 #else
00388 return ticks;
00389 #endif
00390 }
00391
00392 static inline xnticks_t xnpod_ns2ticks(xntime_t t)
00393 {
00394 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00395 return xnarch_ulldiv(t, xnpod_get_tickval(), NULL);
00396 #else
00397 return t;
00398 #endif
00399 }
00400
00401 int xnpod_init(xnpod_t *pod, int minpri, int maxpri, xnflags_t flags);
00402
00403 int xnpod_start_timer(u_long nstick, xnisr_t tickhandler);
00404
00405 void xnpod_stop_timer(void);
00406
00407 int xnpod_reset_timer(void);
00408
00409 void xnpod_shutdown(int xtype);
00410
00411 int xnpod_init_thread(xnthread_t *thread,
00412 const char *name,
00413 int prio, xnflags_t flags, unsigned stacksize);
00414
00415 int xnpod_start_thread(xnthread_t *thread,
00416 xnflags_t mode,
00417 int imask,
00418 xnarch_cpumask_t affinity,
00419 void (*entry) (void *cookie), 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, xnflags_t setmask);
00427
00428 void xnpod_suspend_thread(xnthread_t *thread,
00429 xnflags_t mask,
00430 xnticks_t timeout, struct xnsynch *resource);
00431
00432 void xnpod_resume_thread(xnthread_t *thread, xnflags_t mask);
00433
00434 int xnpod_unblock_thread(xnthread_t *thread);
00435
00436 void xnpod_renice_thread(xnthread_t *thread, int prio);
00437
00438 int xnpod_migrate_thread(int cpu);
00439
00440 void xnpod_rotate_readyq(int prio);
00441
00442 void xnpod_schedule(void);
00443
00444 void xnpod_dispatch_signals(void);
00445
00446 static inline void xnpod_lock_sched(void)
00447 {
00448 spl_t s;
00449
00450 xnlock_get_irqsave(&nklock, s);
00451
00452 if (nkpod->schedlck++ == 0)
00453 xnthread_set_state(xnpod_current_sched()->runthread, XNLOCK);
00454
00455 xnlock_put_irqrestore(&nklock, s);
00456 }
00457
00458 static inline void xnpod_unlock_sched(void)
00459 {
00460 spl_t s;
00461
00462 xnlock_get_irqsave(&nklock, s);
00463
00464 if (--nkpod->schedlck == 0) {
00465 xnthread_clear_state(xnpod_current_sched()->runthread, XNLOCK);
00466 xnpod_schedule();
00467 }
00468
00469 xnlock_put_irqrestore(&nklock, s);
00470 }
00471
00472 int xnpod_announce_tick(struct xnintr *intr);
00473
00474 void xnpod_activate_rr(xnticks_t quantum);
00475
00476 void xnpod_deactivate_rr(void);
00477
00478 void xnpod_set_time(xnticks_t newtime);
00479
00480 int xnpod_set_thread_periodic(xnthread_t *thread,
00481 xnticks_t idate, xnticks_t period);
00482
00483 int xnpod_wait_thread_period(unsigned long *overruns_r);
00484
00485 xnticks_t xnpod_get_time(void);
00486
00487 static inline xntime_t xnpod_get_cpu_time(void)
00488 {
00489 return xnarch_get_cpu_time();
00490 }
00491
00492 int xnpod_add_hook(int type, void (*routine) (xnthread_t *));
00493
00494 int xnpod_remove_hook(int type, void (*routine) (xnthread_t *));
00495
00496 void xnpod_check_context(int mask);
00497
00498 static inline void xnpod_yield(void)
00499 {
00500 xnpod_resume_thread(xnpod_current_thread(), 0);
00501 xnpod_schedule();
00502 }
00503
00504 static inline void xnpod_delay(xnticks_t timeout)
00505 {
00506 xnpod_suspend_thread(xnpod_current_thread(), XNDELAY, timeout, NULL);
00507 }
00508
00509 static inline void xnpod_suspend_self(void)
00510 {
00511 xnpod_suspend_thread(xnpod_current_thread(), XNSUSP, XN_INFINITE, NULL);
00512 }
00513
00514 static inline void xnpod_delete_self(void)
00515 {
00516 xnpod_delete_thread(xnpod_current_thread());
00517 }
00518
00519 #ifdef __cplusplus
00520 }
00521 #endif
00522
00525 #endif