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 XNFATAL 0x00000001
00039 #define XNPEXEC 0x00000002
00040
00041
00042 #define XNKCOUT 0x80000000
00043 #define XNHTICK 0x40000000
00044 #define XNRPICK 0x20000000
00045 #define XNINTCK 0x10000000
00046
00047
00048 #define XNPOD_SPARE0 0x01000000
00049 #define XNPOD_SPARE1 0x02000000
00050 #define XNPOD_SPARE2 0x04000000
00051 #define XNPOD_SPARE3 0x08000000
00052 #define XNPOD_SPARE4 0x10000000
00053 #define XNPOD_SPARE5 0x20000000
00054 #define XNPOD_SPARE6 0x40000000
00055 #define XNPOD_SPARE7 0x80000000
00056
00057
00058 #define XNPOD_THREAD_CONTEXT 0x1
00059 #define XNPOD_INTERRUPT_CONTEXT 0x2
00060 #define XNPOD_HOOK_CONTEXT 0x4
00061 #define XNPOD_ROOT_CONTEXT 0x8
00062
00063 #define XNPOD_NORMAL_EXIT 0x0
00064 #define XNPOD_FATAL_EXIT 0x1
00065
00066 #define XNPOD_ALL_CPUS XNARCH_CPU_MASK_ALL
00067
00068 #define XNPOD_HEAPSIZE (CONFIG_XENO_OPT_SYS_HEAPSZ * 1024)
00069 #define XNPOD_PAGESIZE 512
00070 #define XNPOD_RUNPRIO 0x80000000
00071
00072
00073 #define XNPOD_SCHEDFIFO 0x0
00074 #define XNPOD_SCHEDLIFO 0x1
00075 #define XNPOD_NOSWITCH 0x2
00076
00077 #ifdef CONFIG_XENO_OPT_SCALABLE_SCHED
00078 typedef xnmlqueue_t xnsched_queue_t;
00079 #define sched_initpq initmlq
00080 #define sched_emptypq_p emptymlq_p
00081 #define sched_insertpql insertmlql
00082 #define sched_insertpqf insertmlqf
00083 #define sched_appendpq appendmlq
00084 #define sched_prependpq prependmlq
00085 #define sched_removepq removemlq
00086 #define sched_getheadpq getheadmlq
00087 #define sched_getpq getmlq
00088 #define sched_findpqh findmlqh
00089 #else
00090 typedef xnpqueue_t xnsched_queue_t;
00091 #define sched_initpq(pqslot, minp, maxp) initpq(pqslot)
00092 #define sched_emptypq_p emptypq_p
00093 #define sched_insertpql insertpql
00094 #define sched_insertpqf insertpqf
00095 #define sched_appendpq appendpq
00096 #define sched_prependpq prependpq
00097 #define sched_removepq removepq
00098 #define sched_getheadpq getheadpq
00099 #define sched_getpq getpq
00100 #define sched_findpqh findpqh
00101 #endif
00102
00103 #define XNPOD_FATAL_BUFSZ 16384
00104
00109 typedef struct xnsched {
00110
00111 xnflags_t status;
00113 xnthread_t *runthread;
00115 xnarch_cpumask_t resched;
00117 xnsched_queue_t readyq;
00119 xntimerq_t timerqueue;
00120
00121 volatile unsigned inesting;
00123 #ifdef CONFIG_XENO_HW_FPU
00124 xnthread_t *fpuholder;
00125 #endif
00126
00127 #ifdef CONFIG_XENO_OPT_WATCHDOG
00128 xntimer_t wdtimer;
00129 int wdcount;
00130 #endif
00131
00132 xnthread_t rootcb;
00134 #ifdef CONFIG_XENO_OPT_STATS
00135 xnticks_t last_account_switch;
00137 xnstat_exectime_t *current_account;
00138 #endif
00139
00140 xntimer_t htimer;
00142 } xnsched_t;
00143
00144 #define nkpod (&nkpod_struct)
00145
00146 #ifdef CONFIG_SMP
00147 #define xnsched_cpu(__sched__) \
00148 ((__sched__) - &nkpod->sched[0])
00149 #else
00150 #define xnsched_cpu(__sched__) ({ (void)__sched__; 0; })
00151 #endif
00152
00153 #define xnsched_resched_mask() \
00154 (xnpod_current_sched()->resched)
00155
00156 #define xnsched_resched_p() \
00157 (!xnarch_cpus_empty(xnsched_resched_mask()))
00158
00159 #define xnsched_tst_resched(__sched__) \
00160 xnarch_cpu_isset(xnsched_cpu(__sched__), xnsched_resched_mask())
00161
00162 #define xnsched_set_resched(__sched__) \
00163 xnarch_cpu_set(xnsched_cpu(__sched__), xnsched_resched_mask())
00164
00165 #define xnsched_clr_resched(__sched__) \
00166 xnarch_cpu_clear(xnsched_cpu(__sched__), xnsched_resched_mask())
00167
00168 #define xnsched_clr_mask(__sched__) \
00169 xnarch_cpus_clear((__sched__)->resched)
00170
00171 struct xnsynch;
00172 struct xnintr;
00173
00180 struct xnpod {
00181
00182 xnflags_t status;
00184 xnsched_t sched[XNARCH_NR_CPUS];
00186 xnqueue_t threadq;
00187 int threadq_rev;
00189 xnqueue_t tstartq,
00190 tswitchq,
00191 tdeleteq;
00193 int refcnt;
00195 #ifdef __KERNEL__
00196 atomic_counter_t timerlck;
00197 #endif
00198
00199 #ifdef __XENO_SIM__
00200 void (*schedhook) (xnthread_t *thread, xnflags_t mask);
00201 #endif
00202 };
00203
00204 typedef struct xnpod xnpod_t;
00205
00206 DECLARE_EXTERN_XNLOCK(nklock);
00207
00208 extern u_long nklatency;
00209
00210 extern u_long nktimerlat;
00211
00212 extern char *nkmsgbuf;
00213
00214 extern xnarch_cpumask_t nkaffinity;
00215
00216 extern xnpod_t nkpod_struct;
00217
00218 #ifdef __cplusplus
00219 extern "C" {
00220 #endif
00221
00222 void xnpod_schedule_runnable(xnthread_t *thread, int flags);
00223
00224 void xnpod_renice_thread_inner(xnthread_t *thread, int prio, int propagate);
00225
00226 #ifdef CONFIG_XENO_HW_FPU
00227 void xnpod_switch_fpu(xnsched_t *sched);
00228 #endif
00229
00230 #ifdef CONFIG_XENO_OPT_WATCHDOG
00231 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00232 {
00233 sched->wdcount = 0;
00234 }
00235 #else
00236 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00237 {
00238 }
00239 #endif
00240
00241
00242
00243 #define xnpod_sched_slot(cpu) \
00244 (&nkpod->sched[cpu])
00245
00246 #define xnpod_current_sched() \
00247 xnpod_sched_slot(xnarch_current_cpu())
00248
00249 #define xnpod_active_p() \
00250 (!!testbits(nkpod->status, XNPEXEC))
00251
00252 #define xnpod_fatal_p() \
00253 (!!testbits(nkpod->status, XNFATAL))
00254
00255 #define xnpod_interrupt_p() \
00256 (xnpod_current_sched()->inesting > 0)
00257
00258 #define xnpod_callout_p() \
00259 (!!testbits(xnpod_current_sched()->status,XNKCOUT))
00260
00261 #define xnpod_asynch_p() \
00262 (xnpod_interrupt_p() || xnpod_callout_p())
00263
00264 #define xnpod_current_thread() \
00265 (xnpod_current_sched()->runthread)
00266
00267 #define xnpod_current_root() \
00268 (&xnpod_current_sched()->rootcb)
00269
00270 #ifdef CONFIG_XENO_OPT_PERVASIVE
00271 #define xnpod_current_p(thread) \
00272 ({ int __shadow_p = xnthread_test_state(thread, XNSHADOW); \
00273 int __curr_p = __shadow_p ? xnshadow_thread(current) == thread \
00274 : thread == xnpod_current_thread(); \
00275 __curr_p;})
00276 #else
00277 #define xnpod_current_p(thread) \
00278 (xnpod_current_thread() == (thread))
00279 #endif
00280
00281 #define xnpod_locked_p() \
00282 (!!xnthread_test_state(xnpod_current_thread(),XNLOCK))
00283
00284 #define xnpod_unblockable_p() \
00285 (xnpod_asynch_p() || xnthread_test_state(xnpod_current_thread(),XNROOT))
00286
00287 #define xnpod_root_p() \
00288 (!!xnthread_test_state(xnpod_current_thread(),XNROOT))
00289
00290 #define xnpod_shadow_p() \
00291 (!!xnthread_test_state(xnpod_current_thread(),XNSHADOW))
00292
00293 #define xnpod_userspace_p() \
00294 (!!xnthread_test_state(xnpod_current_thread(),XNROOT|XNSHADOW))
00295
00296 #define xnpod_primary_p() \
00297 (!(xnpod_asynch_p() || xnpod_root_p()))
00298
00299 #define xnpod_secondary_p() xnpod_root_p()
00300
00301 #define xnpod_idle_p() xnpod_root_p()
00302
00303 static inline void xnpod_renice_root(int cpu, int prio)
00304 {
00305 xnthread_t *rootcb;
00306 spl_t s;
00307
00308 xnlock_get_irqsave(&nklock, s);
00309 rootcb = &xnpod_sched_slot(cpu)->rootcb;
00310 rootcb->cprio = prio;
00311 xnpod_schedule_runnable(rootcb, XNPOD_SCHEDLIFO | XNPOD_NOSWITCH);
00312 xnlock_put_irqrestore(&nklock, s);
00313 }
00314
00315 static inline int xnpod_root_priority(int cpu)
00316 {
00317 return xnthread_current_priority(&xnpod_sched_slot(cpu)->rootcb);
00318 }
00319
00320 int xnpod_init(void);
00321
00322 int xnpod_enable_timesource(void);
00323
00324 void xnpod_disable_timesource(void);
00325
00326 void xnpod_shutdown(int xtype);
00327
00328 int xnpod_init_thread(xnthread_t *thread,
00329 xntbase_t *tbase,
00330 const char *name,
00331 int prio,
00332 xnflags_t flags,
00333 unsigned stacksize,
00334 xnthrops_t *ops);
00335
00336 int xnpod_start_thread(xnthread_t *thread,
00337 xnflags_t mode,
00338 int imask,
00339 xnarch_cpumask_t affinity,
00340 void (*entry) (void *cookie),
00341 void *cookie);
00342
00343 void xnpod_restart_thread(xnthread_t *thread);
00344
00345 void xnpod_delete_thread(xnthread_t *thread);
00346
00347 void xnpod_abort_thread(xnthread_t *thread);
00348
00349 xnflags_t xnpod_set_thread_mode(xnthread_t *thread,
00350 xnflags_t clrmask,
00351 xnflags_t setmask);
00352
00353 void xnpod_suspend_thread(xnthread_t *thread,
00354 xnflags_t mask,
00355 xnticks_t timeout,
00356 xntmode_t timeout_mode,
00357 struct xnsynch *wchan);
00358
00359 void xnpod_resume_thread(xnthread_t *thread,
00360 xnflags_t mask);
00361
00362 int xnpod_unblock_thread(xnthread_t *thread);
00363
00364 void xnpod_renice_thread(xnthread_t *thread,
00365 int prio);
00366
00367 int xnpod_migrate_thread(int cpu);
00368
00369 void xnpod_rotate_readyq(int prio);
00370
00371 void xnpod_do_rr(void);
00372
00373 void xnpod_schedule(void);
00374
00375 void xnpod_dispatch_signals(void);
00376
00377 static inline void xnpod_lock_sched(void)
00378 {
00379 xnthread_t *runthread;
00380 spl_t s;
00381
00382 xnlock_get_irqsave(&nklock, s);
00383
00384 runthread = xnpod_current_sched()->runthread;
00385
00386 if (xnthread_lock_count(runthread)++ == 0)
00387 xnthread_set_state(runthread, XNLOCK);
00388
00389 xnlock_put_irqrestore(&nklock, s);
00390 }
00391
00392 static inline void xnpod_unlock_sched(void)
00393 {
00394 xnthread_t *runthread;
00395 spl_t s;
00396
00397 xnlock_get_irqsave(&nklock, s);
00398
00399 runthread = xnpod_current_sched()->runthread;
00400
00401 if (--xnthread_lock_count(runthread) == 0) {
00402 xnthread_clear_state(runthread, XNLOCK);
00403 xnpod_schedule();
00404 }
00405
00406 xnlock_put_irqrestore(&nklock, s);
00407 }
00408
00409 void xnpod_activate_rr(xnticks_t quantum);
00410
00411 void xnpod_deactivate_rr(void);
00412
00413 int xnpod_set_thread_periodic(xnthread_t *thread,
00414 xnticks_t idate,
00415 xnticks_t period);
00416
00417 int xnpod_wait_thread_period(unsigned long *overruns_r);
00418
00419 static inline xntime_t xnpod_get_cpu_time(void)
00420 {
00421 return xnarch_get_cpu_time();
00422 }
00423
00424 int xnpod_add_hook(int type, void (*routine) (xnthread_t *));
00425
00426 int xnpod_remove_hook(int type, void (*routine) (xnthread_t *));
00427
00428 void xnpod_check_context(int mask);
00429
00430 static inline void xnpod_yield(void)
00431 {
00432 xnpod_resume_thread(xnpod_current_thread(), 0);
00433 xnpod_schedule();
00434 }
00435
00436 static inline void xnpod_delay(xnticks_t timeout)
00437 {
00438 xnpod_suspend_thread(xnpod_current_thread(), XNDELAY, timeout, XN_RELATIVE, NULL);
00439 }
00440
00441 static inline void xnpod_suspend_self(void)
00442 {
00443 xnpod_suspend_thread(xnpod_current_thread(), XNSUSP, XN_INFINITE, XN_RELATIVE, NULL);
00444 }
00445
00446 static inline void xnpod_delete_self(void)
00447 {
00448 xnpod_delete_thread(xnpod_current_thread());
00449 }
00450
00451 #ifdef __cplusplus
00452 }
00453 #endif
00454
00457 #endif