Xenomai API
2.5.6.1
|
00001 /* 00002 * @note Copyright (C) 2001,2002,2003 Philippe Gerum <[email protected]>. 00003 * 00004 * Xenomai is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published 00006 * by the Free Software Foundation; either version 2 of the License, 00007 * or (at your option) any later version. 00008 * 00009 * Xenomai is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with Xenomai; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00017 * 02111-1307, USA. 00018 * 00019 * \ingroup thread 00020 */ 00021 00022 #ifndef _XENO_NUCLEUS_THREAD_H 00023 #define _XENO_NUCLEUS_THREAD_H 00024 00025 #include <nucleus/types.h> 00026 00033 /* State flags */ 00034 00035 #define XNSUSP 0x00000001 00036 #define XNPEND 0x00000002 00037 #define XNDELAY 0x00000004 00038 #define XNREADY 0x00000008 00039 #define XNDORMANT 0x00000010 00040 #define XNZOMBIE 0x00000020 00041 #define XNRESTART 0x00000040 00042 #define XNSTARTED 0x00000080 00043 #define XNMAPPED 0x00000100 00044 #define XNRELAX 0x00000200 00045 #define XNMIGRATE 0x00000400 00046 #define XNHELD 0x00000800 00048 #define XNBOOST 0x00001000 00049 #define XNDEBUG 0x00002000 00050 #define XNLOCK 0x00004000 00051 #define XNRRB 0x00008000 00052 #define XNASDI 0x00010000 00053 #define XNDEFCAN 0x00020000 00055 /* 00056 * Some skins may depend on the following fields to live in the high 00057 * 16-bit word, in order to be combined with the emulated RTOS flags 00058 * which use the low one, so don't change them carelessly. 00059 */ 00060 #define XNTRAPSW 0x00040000 00061 #define XNRPIOFF 0x00080000 00062 #define XNFPU 0x00100000 00063 #define XNSHADOW 0x00200000 00064 #define XNROOT 0x00400000 00065 #define XNSWREP 0x00800000 /* Ends doxygen comment group: nucleus_state_flags */ 00068 00069 /* 00070 Must follow the declaration order of the above bits. Status symbols 00071 are defined as follows: 00072 'S' -> Forcibly suspended. 00073 'w'/'W' -> Waiting for a resource, with or without timeout. 00074 'D' -> Delayed (without any other wait condition). 00075 'R' -> Runnable. 00076 'U' -> Unstarted or dormant. 00077 'X' -> Relaxed shadow. 00078 'H' -> Held in emergency. 00079 'b' -> Priority boost undergoing. 00080 'T' -> Ptraced and stopped. 00081 'l' -> Locks scheduler. 00082 'r' -> Undergoes round-robin. 00083 's' -> Interrupt shield enabled. 00084 't' -> Mode switches trapped. 00085 'o' -> Priority coupling off. 00086 'f' -> FPU enabled (for kernel threads). 00087 */ 00088 #define XNTHREAD_STATE_LABELS "SWDRU....X.HbTlr..tof.." 00089 00090 #define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD) 00091 #define XNTHREAD_MODE_BITS (XNLOCK|XNRRB|XNASDI|XNTRAPSW|XNRPIOFF) 00092 00093 /* These state flags are available to the real-time interfaces */ 00094 #define XNTHREAD_STATE_SPARE0 0x10000000 00095 #define XNTHREAD_STATE_SPARE1 0x20000000 00096 #define XNTHREAD_STATE_SPARE2 0x40000000 00097 #define XNTHREAD_STATE_SPARE3 0x80000000 00098 #define XNTHREAD_STATE_SPARES 0xf0000000 00099 00106 /* Information flags */ 00107 00108 #define XNTIMEO 0x00000001 00109 #define XNRMID 0x00000002 00110 #define XNBREAK 0x00000004 00111 #define XNKICKED 0x00000008 00112 #define XNWAKEN 0x00000010 00113 #define XNROBBED 0x00000020 00114 #define XNATOMIC 0x00000040 00115 #define XNAFFSET 0x00000080 00116 #define XNPRIOSET 0x00000100 00117 #define XNABORT 0x00000200 00118 #define XNCANPND 0x00000400 00119 #define XNAMOK 0x00000800 00121 /* These information flags are available to the real-time interfaces */ 00122 #define XNTHREAD_INFO_SPARE0 0x10000000 00123 #define XNTHREAD_INFO_SPARE1 0x20000000 00124 #define XNTHREAD_INFO_SPARE2 0x40000000 00125 #define XNTHREAD_INFO_SPARE3 0x80000000 00126 #define XNTHREAD_INFO_SPARES 0xf0000000 00127 /* Ends doxygen comment group: nucleus_info_flags */ 00129 00133 typedef struct xnthread_info { 00134 00135 unsigned long state; 00137 int bprio; 00138 int cprio; 00140 int cpu; 00141 unsigned long affinity; 00143 unsigned long long relpoint; 00145 unsigned long long exectime; 00147 unsigned long modeswitches; 00148 unsigned long ctxswitches; 00149 unsigned long pagefaults; 00151 char name[XNOBJECT_NAME_LEN]; 00153 } xnthread_info_t; 00154 00155 #if defined(__KERNEL__) || defined(__XENO_SIM__) 00156 00157 #include <nucleus/stat.h> 00158 #include <nucleus/timer.h> 00159 #include <nucleus/registry.h> 00160 #include <nucleus/schedparam.h> 00161 00162 #ifdef __XENO_SIM__ 00163 /* Pseudo-status (must not conflict with other bits) */ 00164 #define XNRUNNING XNTHREAD_STATE_SPARE0 00165 #define XNDELETED XNTHREAD_STATE_SPARE1 00166 #endif /* __XENO_SIM__ */ 00167 00168 #define XNTHREAD_INVALID_ASR ((void (*)(xnsigmask_t))0) 00169 00170 struct xnthread; 00171 struct xnsynch; 00172 struct xnsched; 00173 struct xnselector; 00174 struct xnsched_class; 00175 struct xnsched_tpslot; 00176 union xnsched_policy_param; 00177 struct xnbufd; 00178 00179 struct xnthread_operations { 00180 int (*get_denormalized_prio)(struct xnthread *, int coreprio); 00181 unsigned (*get_magic)(void); 00182 }; 00183 00184 struct xnthread_init_attr { 00185 struct xntbase *tbase; 00186 struct xnthread_operations *ops; 00187 xnflags_t flags; 00188 unsigned int stacksize; 00189 const char *name; 00190 }; 00191 00192 struct xnthread_start_attr { 00193 xnflags_t mode; 00194 int imask; 00195 xnarch_cpumask_t affinity; 00196 void (*entry)(void *cookie); 00197 void *cookie; 00198 }; 00199 00200 struct xnthread_wait_context { 00201 unsigned long oldstate; 00202 }; 00203 00204 typedef void (*xnasr_t)(xnsigmask_t sigs); 00205 00206 typedef struct xnthread { 00207 00208 xnarchtcb_t tcb; /* Architecture-dependent block -- Must be first */ 00209 00210 xnflags_t state; /* Thread state flags */ 00211 00212 xnflags_t info; /* Thread information flags */ 00213 00214 struct xnsched *sched; /* Thread scheduler */ 00215 00216 struct xnsched_class *sched_class; /* Current scheduling class */ 00217 00218 struct xnsched_class *base_class; /* Base scheduling class */ 00219 00220 #ifdef CONFIG_XENO_OPT_SCHED_TP 00221 struct xnsched_tpslot *tps; /* Current partition slot for TP scheduling */ 00222 struct xnholder tp_link; /* Link in per-sched TP thread queue */ 00223 #endif 00224 #ifdef CONFIG_XENO_OPT_SCHED_SPORADIC 00225 struct xnsched_sporadic_data *pss; /* Sporadic scheduling data. */ 00226 #endif 00227 00228 unsigned idtag; /* Unique ID tag */ 00229 00230 xnarch_cpumask_t affinity; /* Processor affinity. */ 00231 00232 int bprio; /* Base priority (before PIP boost) */ 00233 00234 int cprio; /* Current priority */ 00235 00236 u_long schedlck; 00238 xnpholder_t rlink; /* Thread holder in ready queue */ 00239 00240 xnpholder_t plink; /* Thread holder in synchronization queue(s) */ 00241 00242 #ifdef CONFIG_XENO_OPT_PRIOCPL 00243 xnpholder_t xlink; /* Thread holder in the RPI queue (shadow only) */ 00244 00245 struct xnsched *rpi; /* Backlink pointer to the RPI slot (shadow only) */ 00246 #endif /* CONFIG_XENO_OPT_PRIOCPL */ 00247 00248 xnholder_t glink; /* Thread holder in global queue */ 00249 00250 #define link2thread(ln, fld) container_of(ln, struct xnthread, fld) 00251 00252 xnpqueue_t claimq; /* Owned resources claimed by others (PIP) */ 00253 00254 struct xnsynch *wchan; /* Resource the thread pends on */ 00255 00256 struct xnsynch *wwake; /* Wait channel the thread was resumed from */ 00257 00258 xntimer_t rtimer; /* Resource timer */ 00259 00260 xntimer_t ptimer; /* Periodic timer */ 00261 00262 xnsigmask_t signals; /* Pending core signals */ 00263 00264 xnticks_t rrperiod; /* Allotted round-robin period (ticks) */ 00265 00266 xnticks_t rrcredit; /* Remaining round-robin time credit (ticks) */ 00267 00268 union { 00269 struct { 00270 /* 00271 * XXX: the buffer struct should disappear as 00272 * soon as all IPCs are converted to use 00273 * buffer descriptors instead (bufd). 00274 */ 00275 void *ptr; 00276 size_t size; 00277 } buffer; 00278 struct xnbufd *bufd; 00279 size_t size; 00280 } wait_u; 00281 00282 /* Active wait context - Obsoletes wait_u. */ 00283 struct xnthread_wait_context *wcontext; 00284 00285 struct { 00286 xnstat_counter_t ssw; /* Primary -> secondary mode switch count */ 00287 xnstat_counter_t csw; /* Context switches (includes secondary -> primary switches) */ 00288 xnstat_counter_t pf; /* Number of page faults */ 00289 xnstat_exectime_t account; /* Execution time accounting entity */ 00290 xnstat_exectime_t lastperiod; /* Interval marker for execution time reports */ 00291 } stat; 00292 00293 #ifdef CONFIG_XENO_OPT_SELECT 00294 struct xnselector *selector; /* For select. */ 00295 #endif /* CONFIG_XENO_OPT_SELECT */ 00296 00297 int errcode; /* Local errno */ 00298 00299 xnasr_t asr; /* Asynchronous service routine */ 00300 00301 xnflags_t asrmode; /* Thread's mode for ASR */ 00302 00303 int asrimask; /* Thread's interrupt mask for ASR */ 00304 00305 unsigned asrlevel; /* ASR execution level (ASRs are reentrant) */ 00306 00307 int imask; /* Initial interrupt mask */ 00308 00309 int imode; /* Initial mode */ 00310 00311 struct xnsched_class *init_class; /* Initial scheduling class */ 00312 00313 union xnsched_policy_param init_schedparam; /* Initial scheduling parameters */ 00314 00315 struct { 00316 xnhandle_t handle; /* Handle in registry */ 00317 const char *waitkey; /* Pended key */ 00318 } registry; 00319 00320 struct xnthread_operations *ops; /* Thread class operations. */ 00321 00322 char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */ 00323 00324 void (*entry)(void *cookie); /* Thread entry routine */ 00325 00326 void *cookie; /* Cookie to pass to the entry routine */ 00327 00328 #ifdef CONFIG_XENO_OPT_PERVASIVE 00329 unsigned long __user *u_mode; /* Thread mode variable in userland. */ 00330 00331 unsigned u_sigpending; /* One bit per skin */ 00332 #endif /* CONFIG_XENO_OPT_PERVASIVE */ 00333 00334 XNARCH_DECL_DISPLAY_CONTEXT(); 00335 00336 } xnthread_t; 00337 00338 #define XNHOOK_THREAD_START 1 00339 #define XNHOOK_THREAD_SWITCH 2 00340 #define XNHOOK_THREAD_DELETE 3 00341 00342 typedef struct xnhook { 00343 xnholder_t link; 00344 #define link2hook(ln) container_of(ln, xnhook_t, link) 00345 void (*routine)(struct xnthread *thread); 00346 } xnhook_t; 00347 00348 #define xnthread_name(thread) ((thread)->name) 00349 #define xnthread_clear_name(thread) do { *(thread)->name = 0; } while(0) 00350 #define xnthread_sched(thread) ((thread)->sched) 00351 #define xnthread_start_time(thread) ((thread)->stime) 00352 #define xnthread_state_flags(thread) ((thread)->state) 00353 #define xnthread_test_state(thread,flags) testbits((thread)->state,flags) 00354 #define xnthread_set_state(thread,flags) __setbits((thread)->state,flags) 00355 #define xnthread_clear_state(thread,flags) __clrbits((thread)->state,flags) 00356 #define xnthread_test_info(thread,flags) testbits((thread)->info,flags) 00357 #define xnthread_set_info(thread,flags) __setbits((thread)->info,flags) 00358 #define xnthread_clear_info(thread,flags) __clrbits((thread)->info,flags) 00359 #define xnthread_lock_count(thread) ((thread)->schedlck) 00360 #define xnthread_init_schedparam(thread) ((thread)->init_schedparam) 00361 #define xnthread_base_priority(thread) ((thread)->bprio) 00362 #define xnthread_current_priority(thread) ((thread)->cprio) 00363 #define xnthread_init_class(thread) ((thread)->init_class) 00364 #define xnthread_base_class(thread) ((thread)->base_class) 00365 #define xnthread_sched_class(thread) ((thread)->sched_class) 00366 #define xnthread_time_slice(thread) ((thread)->rrperiod) 00367 #define xnthread_time_credit(thread) ((thread)->rrcredit) 00368 #define xnthread_archtcb(thread) (&((thread)->tcb)) 00369 #define xnthread_asr_level(thread) ((thread)->asrlevel) 00370 #define xnthread_pending_signals(thread) ((thread)->signals) 00371 #define xnthread_timeout(thread) xntimer_get_timeout(&(thread)->rtimer) 00372 #define xnthread_stack_size(thread) xnarch_stack_size(xnthread_archtcb(thread)) 00373 #define xnthread_stack_base(thread) xnarch_stack_base(xnthread_archtcb(thread)) 00374 #define xnthread_stack_end(thread) xnarch_stack_end(xnthread_archtcb(thread)) 00375 #define xnthread_handle(thread) ((thread)->registry.handle) 00376 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC 00377 #define xnthread_time_base(thread) ((thread)->rtimer.base) 00378 #else /* !CONFIG_XENO_OPT_TIMING_PERIODIC */ 00379 #define xnthread_time_base(thread) (&nktbase) 00380 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */ 00381 #define xnthread_signaled_p(thread) ((thread)->signals != 0) 00382 #define xnthread_timed_p(thread) (!!testbits(xnthread_time_base(thread)->status, XNTBRUN)) 00383 #define xnthread_user_task(thread) xnarch_user_task(xnthread_archtcb(thread)) 00384 #define xnthread_user_pid(thread) \ 00385 (xnthread_test_state((thread),XNROOT) || !xnthread_user_task(thread) ? \ 00386 0 : xnarch_user_pid(xnthread_archtcb(thread))) 00387 #define xnthread_affinity(thread) ((thread)->affinity) 00388 #define xnthread_affine_p(thread, cpu) xnarch_cpu_isset(cpu, (thread)->affinity) 00389 #define xnthread_get_exectime(thread) xnstat_exectime_get_total(&(thread)->stat.account) 00390 #define xnthread_get_lastswitch(thread) xnstat_exectime_get_last_switch((thread)->sched) 00391 #ifdef CONFIG_XENO_OPT_PERVASIVE 00392 #define xnthread_sigpending(thread) ((thread)->u_sigpending) 00393 #define xnthread_set_sigpending(thread, pending) \ 00394 ((thread)->u_sigpending = (pending)) 00395 #endif /* CONFIG_XENO_OPT_PERVASIVE */ 00396 #ifdef CONFIG_XENO_OPT_WATCHDOG 00397 #define xnthread_amok_p(thread) xnthread_test_info(thread, XNAMOK) 00398 #define xnthread_clear_amok(thread) xnthread_clear_info(thread, XNAMOK) 00399 #else /* !CONFIG_XENO_OPT_WATCHDOG */ 00400 #define xnthread_amok_p(thread) (0) 00401 #define xnthread_clear_amok(thread) do { } while (0) 00402 #endif /* !CONFIG_XENO_OPT_WATCHDOG */ 00403 00404 /* Class-level operations for threads. */ 00405 static inline int xnthread_get_denormalized_prio(struct xnthread *t, int coreprio) 00406 { 00407 return t->ops && t->ops->get_denormalized_prio 00408 ? t->ops->get_denormalized_prio(t, coreprio) : coreprio; 00409 } 00410 00411 static inline unsigned xnthread_get_magic(struct xnthread *t) 00412 { 00413 return t->ops ? t->ops->get_magic() : 0; 00414 } 00415 00416 static inline 00417 struct xnthread_wait_context *xnthread_get_wait_context(struct xnthread *thread) 00418 { 00419 return thread->wcontext; 00420 } 00421 00422 static inline 00423 int xnthread_register(struct xnthread *thread, const char *name) 00424 { 00425 return xnregistry_enter(name, thread, &xnthread_handle(thread), NULL); 00426 } 00427 00428 static inline 00429 struct xnthread *xnthread_lookup(xnhandle_t threadh) 00430 { 00431 struct xnthread *thread = (struct xnthread *)xnregistry_lookup(threadh); 00432 return (thread && xnthread_handle(thread) == threadh) ? thread : NULL; 00433 } 00434 00435 #ifdef __cplusplus 00436 extern "C" { 00437 #endif 00438 00439 int xnthread_init(struct xnthread *thread, 00440 const struct xnthread_init_attr *attr, 00441 struct xnsched *sched, 00442 struct xnsched_class *sched_class, 00443 const union xnsched_policy_param *sched_param); 00444 00445 void xnthread_cleanup_tcb(struct xnthread *thread); 00446 00447 char *xnthread_format_status(xnflags_t status, char *buf, int size); 00448 00449 int *xnthread_get_errno_location(struct xnthread *thread); 00450 00451 xnticks_t xnthread_get_timeout(struct xnthread *thread, xnticks_t tsc_ns); 00452 00453 xnticks_t xnthread_get_period(struct xnthread *thread); 00454 00455 void xnthread_prepare_wait(struct xnthread_wait_context *wc); 00456 00457 void xnthread_finish_wait(struct xnthread_wait_context *wc, 00458 void (*cleanup)(struct xnthread_wait_context *wc)); 00459 00460 #ifdef __cplusplus 00461 } 00462 #endif 00463 00464 #endif /* __KERNEL__ || __XENO_SIM__ */ 00465 00466 #endif /* !_XENO_NUCLEUS_THREAD_H */