include/nucleus/pod.h

Go to the documentation of this file.
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 /* Creation flags */
00038 #define XNREUSE  0x00000001     /* Reuse pod with identical properties */
00039 
00040 /* Pod status flags */
00041 #define XNRPRIO  0x00000002     /* Reverse priority scheme */
00042 #define XNTIMED  0x00000004     /* Timer started */
00043 #define XNTMSET  0x00000008     /* Pod time has been set */
00044 #define XNTMPER  0x00000010     /* Periodic timing */
00045 #define XNFATAL  0x00000020     /* Pod encountered a fatal error */
00046 #define XNPIDLE  0x00000040     /* Pod is unavailable (initializing/shutting down) */
00047 #define XNTLOCK  0x00000080     /* Timer lock pending */
00048 
00049 /* Sched status flags */
00050 #define XNKCOUT  0x80000000     /* Sched callout context */
00051 #define XNHTICK  0x40000000     /* Host tick pending  */
00052 #define XNRPICK  0x20000000     /* Check RPI state */
00053 
00054 /* These flags are available to the real-time interfaces */
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 /* Flags for context checking */
00065 #define XNPOD_THREAD_CONTEXT     0x1    /* Regular thread */
00066 #define XNPOD_INTERRUPT_CONTEXT  0x2    /* Interrupt service thread */
00067 #define XNPOD_HOOK_CONTEXT       0x4    /* Nanokernel hook */
00068 #define XNPOD_ROOT_CONTEXT       0x8    /* Root thread */
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 /* Placeholder for "running thread priority" */
00080 #define XNPOD_RUNPRIO   0x80000000
00081 
00082 /* Flags for xnpod_schedule_runnable() */
00083 #define XNPOD_SCHEDFIFO 0x0
00084 #define XNPOD_SCHEDLIFO 0x1
00085 #define XNPOD_NOSWITCH  0x2
00086 
00087 /* Normal root thread priority == min_std_prio - 1 */
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 /* ! CONFIG_XENO_OPT_SCALABLE_SCHED */
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 /* !CONFIG_XENO_OPT_SCALABLE_SCHED */
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                          /* CONFIG_XENO_OPT_TIMING_PERIODIC */
00136 
00137         volatile unsigned inesting;     
00139 #ifdef CONFIG_XENO_HW_FPU
00140         xnthread_t *fpuholder;  
00141 #endif                          /* CONFIG_XENO_HW_FPU */
00142 
00143 #ifdef CONFIG_XENO_OPT_WATCHDOG
00144         xntimer_t wd_timer;     
00145         int wd_count;           
00146 #endif                          /* CONFIG_XENO_OPT_WATCHDOG */
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                          /* CONFIG_XENO_OPT_STATS */
00155 
00156 } xnsched_t;
00157 
00158 #ifdef CONFIG_SMP
00159 #define xnsched_cpu(__sched__)                  \
00160     ((__sched__) - &nkpod->sched[0])
00161 #else /* !CONFIG_SMP */
00162 #define xnsched_cpu(__sched__) ({ (void)__sched__; 0; })
00163 #endif /* CONFIG_SMP */
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                          /* __KERNEL__ */
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                          /* __XENO_SIM__ */
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 /* CONFIG_SMP */
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 /* CONFIG_XENO_HW_FPU */
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 /* !CONFIG_XENO_OPT_WATCHDOG */
00273 static inline void xnpod_reset_watchdog(xnsched_t *sched)
00274 {
00275 }
00276 #endif /* CONFIG_XENO_OPT_WATCHDOG */
00277 
00278         /* -- Beginning of the exported interface */
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         /* Returns the queuing direction of threads for a given pod */
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         /* Returns a negative, null or positive value whether inprio is
00362            lower than, equal to or greater than outprio. */
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         /* Returns the duration of a tick in nanoseconds */
00381         return nkpod->tickvalue;
00382 }
00383 
00384 static inline xntime_t xnpod_ticks2ns(xnticks_t ticks)
00385 {
00386         /* Convert a count of ticks in nanoseconds */
00387 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00388         return ticks * xnpod_get_tickval();
00389 #else /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00390         return ticks;
00391 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
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 /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00399         return t;
00400 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
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 /* !_XENO_NUCLEUS_POD_H */

Generated on Sun Dec 9 10:37:17 2007 for Xenomai API by  doxygen 1.5.3