Xenomai API  2.6.5
thread.h
1 /*
2  * @note Copyright (C) 2001,2002,2003 Philippe Gerum <[email protected]>.
3  *
4  * Xenomai is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * Xenomai is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Xenomai; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  *
19  * \ingroup thread
20  */
21 
22 #ifndef _XENO_NUCLEUS_THREAD_H
23 #define _XENO_NUCLEUS_THREAD_H
24 
25 #include <nucleus/types.h>
26 
33 /* State flags */
34 
35 #define XNSUSP 0x00000001
36 #define XNPEND 0x00000002
37 #define XNDELAY 0x00000004
38 #define XNREADY 0x00000008
39 #define XNDORMANT 0x00000010
40 #define XNZOMBIE 0x00000020
41 #define XNRESTART 0x00000040
42 #define XNSTARTED 0x00000080
43 #define XNMAPPED 0x00000100
44 #define XNRELAX 0x00000200
45 #define XNMIGRATE 0x00000400
46 #define XNHELD 0x00000800
48 #define XNBOOST 0x00001000
49 #define XNDEBUG 0x00002000
50 #define XNLOCK 0x00004000
51 #define XNRRB 0x00008000
52 #define XNASDI 0x00010000
53 #define XNDEFCAN 0x00020000
55 /*
56  * Some skins may depend on the following fields to live in the high
57  * 16-bit word, in order to be combined with the emulated RTOS flags
58  * which use the low one, so don't change them carelessly.
59  */
60 #define XNTRAPSW 0x00040000
61 #define XNRPIOFF 0x00080000
62 #define XNFPU 0x00100000
63 #define XNSHADOW 0x00200000
64 #define XNROOT 0x00400000
65 #define XNOTHER 0x00800000 /* Ends doxygen comment group: nucleus_state_flags */
68 
69 /*
70  Must follow the declaration order of the above bits. Status symbols
71  are defined as follows:
72  'S' -> Forcibly suspended.
73  'w'/'W' -> Waiting for a resource, with or without timeout.
74  'D' -> Delayed (without any other wait condition).
75  'R' -> Runnable.
76  'U' -> Unstarted or dormant.
77  'X' -> Relaxed shadow.
78  'H' -> Held in emergency.
79  'b' -> Priority boost undergoing.
80  'T' -> Ptraced and stopped.
81  'l' -> Locks scheduler.
82  'r' -> Undergoes round-robin.
83  's' -> Interrupt shield enabled.
84  't' -> Mode switches trapped.
85  'o' -> Priority coupling off.
86  'f' -> FPU enabled (for kernel threads).
87 */
88 #define XNTHREAD_STATE_LABELS "SWDRU....X.HbTlr..tof.."
89 
90 #define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNMIGRATE|XNHELD)
91 #define XNTHREAD_MODE_BITS (XNLOCK|XNRRB|XNASDI|XNTRAPSW|XNRPIOFF)
92 
93 /* These state flags are available to the real-time interfaces */
94 #define XNTHREAD_STATE_SPARE0 0x10000000
95 #define XNTHREAD_STATE_SPARE1 0x20000000
96 #define XNTHREAD_STATE_SPARE2 0x40000000
97 #define XNTHREAD_STATE_SPARE3 0x80000000
98 #define XNTHREAD_STATE_SPARES 0xf0000000
99 
106 /* Information flags */
107 
108 #define XNTIMEO 0x00000001
109 #define XNRMID 0x00000002
110 #define XNBREAK 0x00000004
111 #define XNKICKED 0x00000008
112 #define XNWAKEN 0x00000010
113 #define XNROBBED 0x00000020
114 #define XNATOMIC 0x00000040
115 #define XNAFFSET 0x00000080
116 #define XNPRIOSET 0x00000100
117 #define XNABORT 0x00000200
118 #define XNCANPND 0x00000400
119 #define XNAMOK 0x00000800
120 #define XNSWREP 0x00001000
122 /* These information flags are available to the real-time interfaces */
123 #define XNTHREAD_INFO_SPARE0 0x10000000
124 #define XNTHREAD_INFO_SPARE1 0x20000000
125 #define XNTHREAD_INFO_SPARE2 0x40000000
126 #define XNTHREAD_INFO_SPARE3 0x80000000
127 #define XNTHREAD_INFO_SPARES 0xf0000000
128  /* Ends doxygen comment group: nucleus_info_flags */
130 
134 typedef struct xnthread_info {
135 
136  unsigned long state;
138  int bprio;
139  int cprio;
141  int cpu;
142  unsigned long affinity;
144  unsigned long long relpoint;
146  unsigned long long exectime;
148  unsigned long modeswitches;
149  unsigned long ctxswitches;
150  unsigned long pagefaults;
152  char name[XNOBJECT_NAME_LEN];
155 
156 #if defined(__KERNEL__) || defined(__XENO_SIM__)
157 
158 #include <nucleus/stat.h>
159 #include <nucleus/timer.h>
160 #include <nucleus/registry.h>
161 #include <nucleus/schedparam.h>
162 
163 #ifdef __XENO_SIM__
164 /* Pseudo-status (must not conflict with other bits) */
165 #define XNRUNNING XNTHREAD_STATE_SPARE0
166 #define XNDELETED XNTHREAD_STATE_SPARE1
167 #endif /* __XENO_SIM__ */
168 
169 #define XNTHREAD_INVALID_ASR ((void (*)(xnsigmask_t))0)
170 
171 struct xnthread;
172 struct xnsynch;
173 struct xnsched;
174 struct xnselector;
175 struct xnsched_class;
176 struct xnsched_tpslot;
177 union xnsched_policy_param;
178 struct xnbufd;
179 
180 struct xnthread_operations {
181  int (*get_denormalized_prio)(struct xnthread *, int coreprio);
182  unsigned (*get_magic)(void);
183 };
184 
185 struct xnthread_init_attr {
186  struct xntbase *tbase;
187  struct xnthread_operations *ops;
188  xnflags_t flags;
189  unsigned int stacksize;
190  const char *name;
191 };
192 
193 struct xnthread_start_attr {
194  xnflags_t mode;
195  int imask;
196  xnarch_cpumask_t affinity;
197  void (*entry)(void *cookie);
198  void *cookie;
199 };
200 
201 struct xnthread_wait_context {
202  unsigned long oldstate;
203 };
204 
205 typedef void (*xnasr_t)(xnsigmask_t sigs);
206 
207 typedef struct xnthread {
208 
209  xnarchtcb_t tcb; /* Architecture-dependent block -- Must be first */
210 
211  xnflags_t state; /* Thread state flags */
212 
213  xnflags_t info; /* Thread information flags */
214 
215  struct xnsched *sched; /* Thread scheduler */
216 
217  struct xnsched_class *sched_class; /* Current scheduling class */
218 
219  struct xnsched_class *base_class; /* Base scheduling class */
220 
221 #ifdef CONFIG_XENO_OPT_SCHED_TP
222  struct xnsched_tpslot *tps; /* Current partition slot for TP scheduling */
223  struct xnholder tp_link; /* Link in per-sched TP thread queue */
224 #endif
225 #ifdef CONFIG_XENO_OPT_SCHED_SPORADIC
226  struct xnsched_sporadic_data *pss; /* Sporadic scheduling data. */
227 #endif
228 
229  unsigned idtag; /* Unique ID tag */
230 
231  xnarch_cpumask_t affinity; /* Processor affinity. */
232 
233  int bprio; /* Base priority (before PIP boost) */
234 
235  int cprio; /* Current priority */
236 
237  u_long schedlck;
239  xnpholder_t rlink; /* Thread holder in ready queue */
240 
241  xnpholder_t plink; /* Thread holder in synchronization queue(s) */
242 
243 #ifdef CONFIG_XENO_OPT_PRIOCPL
244  xnpholder_t xlink; /* Thread holder in the RPI queue (shadow only) */
245 
246  struct xnsched *rpi; /* Backlink pointer to the RPI slot (shadow only) */
247 #endif /* CONFIG_XENO_OPT_PRIOCPL */
248 
249  xnholder_t glink; /* Thread holder in global queue */
250 
251 #define link2thread(ln, fld) container_of(ln, struct xnthread, fld)
252 
253  xnpqueue_t claimq; /* Owned resources claimed by others (PIP) */
254 
255  struct xnsynch *wchan; /* Resource the thread pends on */
256 
257  struct xnsynch *wwake; /* Wait channel the thread was resumed from */
258 
259  int hrescnt; /* Held resources count */
260 
261  xntimer_t rtimer; /* Resource timer */
262 
263  xntimer_t ptimer; /* Periodic timer */
264 
265  xnsigmask_t signals; /* Pending core signals */
266 
267  xnticks_t rrperiod; /* Allotted round-robin period (ticks) */
268 
269  xnticks_t rrcredit; /* Remaining round-robin time credit (ticks) */
270 
271  union {
272  struct {
273  /*
274  * XXX: the buffer struct should disappear as
275  * soon as all IPCs are converted to use
276  * buffer descriptors instead (bufd).
277  */
278  void *ptr;
279  size_t size;
280  } buffer;
281  struct xnbufd *bufd;
282  size_t size;
283  } wait_u;
284 
285  /* Active wait context - Obsoletes wait_u. */
286  struct xnthread_wait_context *wcontext;
287 
288  struct {
289  xnstat_counter_t ssw; /* Primary -> secondary mode switch count */
290  xnstat_counter_t csw; /* Context switches (includes secondary -> primary switches) */
291  xnstat_counter_t pf; /* Number of page faults */
292  xnstat_exectime_t account; /* Execution time accounting entity */
293  xnstat_exectime_t lastperiod; /* Interval marker for execution time reports */
294  } stat;
295 
296 #ifdef CONFIG_XENO_OPT_SELECT
297  struct xnselector *selector; /* For select. */
298 #endif /* CONFIG_XENO_OPT_SELECT */
299 
300  int errcode; /* Local errno */
301 
302  xnasr_t asr; /* Asynchronous service routine */
303 
304  xnflags_t asrmode; /* Thread's mode for ASR */
305 
306  int asrimask; /* Thread's interrupt mask for ASR */
307 
308  unsigned asrlevel; /* ASR execution level (ASRs are reentrant) */
309 
310  int imask; /* Initial interrupt mask */
311 
312  int imode; /* Initial mode */
313 
314  struct xnsched_class *init_class; /* Initial scheduling class */
315 
316  union xnsched_policy_param init_schedparam; /* Initial scheduling parameters */
317 
318  struct {
319  xnhandle_t handle; /* Handle in registry */
320  const char *waitkey; /* Pended key */
321  } registry;
322 
323  struct xnthread_operations *ops; /* Thread class operations. */
324 
325  char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */
326 
327  void (*entry)(void *cookie); /* Thread entry routine */
328 
329  void *cookie; /* Cookie to pass to the entry routine */
330 
331 #ifdef CONFIG_XENO_OPT_PERVASIVE
332  unsigned long *u_mode; /* Thread mode variable shared with userland. */
333 #endif /* CONFIG_XENO_OPT_PERVASIVE */
334 
335  XNARCH_DECL_DISPLAY_CONTEXT();
336 
337 } xnthread_t;
338 
339 #define XNHOOK_THREAD_START 1
340 #define XNHOOK_THREAD_SWITCH 2
341 #define XNHOOK_THREAD_DELETE 3
342 
343 typedef struct xnhook {
344  xnholder_t link;
345 #define link2hook(ln) container_of(ln, xnhook_t, link)
346  void (*routine)(struct xnthread *thread);
347 } xnhook_t;
348 
349 #define xnthread_name(thread) ((thread)->name)
350 #define xnthread_clear_name(thread) do { *(thread)->name = 0; } while(0)
351 #define xnthread_sched(thread) ((thread)->sched)
352 #define xnthread_start_time(thread) ((thread)->stime)
353 #define xnthread_state_flags(thread) ((thread)->state)
354 #define xnthread_test_state(thread,flags) testbits((thread)->state,flags)
355 #define xnthread_set_state(thread,flags) __setbits((thread)->state,flags)
356 #define xnthread_clear_state(thread,flags) __clrbits((thread)->state,flags)
357 #define xnthread_test_info(thread,flags) testbits((thread)->info,flags)
358 #define xnthread_set_info(thread,flags) __setbits((thread)->info,flags)
359 #define xnthread_clear_info(thread,flags) __clrbits((thread)->info,flags)
360 #define xnthread_lock_count(thread) ((thread)->schedlck)
361 #define xnthread_init_schedparam(thread) ((thread)->init_schedparam)
362 #define xnthread_base_priority(thread) ((thread)->bprio)
363 #define xnthread_current_priority(thread) ((thread)->cprio)
364 #define xnthread_init_class(thread) ((thread)->init_class)
365 #define xnthread_base_class(thread) ((thread)->base_class)
366 #define xnthread_sched_class(thread) ((thread)->sched_class)
367 #define xnthread_time_slice(thread) ((thread)->rrperiod)
368 #define xnthread_time_credit(thread) ((thread)->rrcredit)
369 #define xnthread_archtcb(thread) (&((thread)->tcb))
370 #define xnthread_asr_level(thread) ((thread)->asrlevel)
371 #define xnthread_pending_signals(thread) ((thread)->signals)
372 #define xnthread_timeout(thread) xntimer_get_timeout(&(thread)->rtimer)
373 #define xnthread_stack_size(thread) xnarch_stack_size(xnthread_archtcb(thread))
374 #define xnthread_stack_base(thread) xnarch_stack_base(xnthread_archtcb(thread))
375 #define xnthread_stack_end(thread) xnarch_stack_end(xnthread_archtcb(thread))
376 #define xnthread_handle(thread) ((thread)->registry.handle)
377 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
378 #define xnthread_time_base(thread) ((thread)->rtimer.base)
379 #else /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
380 #define xnthread_time_base(thread) (&nktbase)
381 #endif /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
382 #define xnthread_signaled_p(thread) ((thread)->signals != 0)
383 #define xnthread_timed_p(thread) (!!testbits(xnthread_time_base(thread)->status, XNTBRUN))
384 #define xnthread_user_task(thread) xnarch_user_task(xnthread_archtcb(thread))
385 #define xnthread_user_pid(thread) \
386  (xnthread_test_state((thread),XNROOT) || !xnthread_user_task(thread) ? \
387  0 : xnarch_user_pid(xnthread_archtcb(thread)))
388 #define xnthread_current_user_task(curr) \
389  ({ \
390  struct xnthread *__c = (curr); \
391  XENO_BUGON(NUCLEUS, __c != xnpod_current_thread()); \
392  xnthread_test_state(__c, XNROOT|XNSHADOW) ? current : NULL; \
393  })
394 #define xnthread_current_user_pid(curr) \
395  ({ \
396  struct task_struct *p = xnthread_current_user_task(curr); \
397  p ? p->pid : 0; \
398  })
399 #define xnthread_affinity(thread) ((thread)->affinity)
400 #define xnthread_affine_p(thread, cpu) xnarch_cpu_isset(cpu, (thread)->affinity)
401 #define xnthread_get_exectime(thread) xnstat_exectime_get_total(&(thread)->stat.account)
402 #define xnthread_get_lastswitch(thread) xnstat_exectime_get_last_switch((thread)->sched)
403 #ifdef CONFIG_XENO_OPT_PERVASIVE
404 #define xnthread_inc_rescnt(thread) ({ (thread)->hrescnt++; })
405 #define xnthread_dec_rescnt(thread) ({ --(thread)->hrescnt; })
406 #define xnthread_get_rescnt(thread) ((thread)->hrescnt)
407 #else /* !CONFIG_XENO_OPT_PERVASIVE */
408 #define xnthread_inc_rescnt(thread) do { } while (0)
409 #define xnthread_dec_rescnt(thread) do { } while (0)
410 #endif /* !CONFIG_XENO_OPT_PERVASIVE */
411 #if defined(CONFIG_XENO_OPT_WATCHDOG) || defined(CONFIG_XENO_SKIN_POSIX)
412 #define xnthread_amok_p(thread) xnthread_test_info(thread, XNAMOK)
413 #define xnthread_clear_amok(thread) xnthread_clear_info(thread, XNAMOK)
414 #else /* !CONFIG_XENO_OPT_WATCHDOG && !CONFIG_XENO_SKIN_POSIX */
415 #define xnthread_amok_p(thread) ({ (void)(thread); 0; })
416 #define xnthread_clear_amok(thread) do { (void)(thread); } while (0)
417 #endif /* !CONFIG_XENO_OPT_WATCHDOG && !CONFIG_XENO_SKIN_POSIX */
418 
419 /* Class-level operations for threads. */
420 static inline int xnthread_get_denormalized_prio(struct xnthread *t, int coreprio)
421 {
422  return t->ops && t->ops->get_denormalized_prio
423  ? t->ops->get_denormalized_prio(t, coreprio) : coreprio;
424 }
425 
426 static inline unsigned xnthread_get_magic(struct xnthread *t)
427 {
428  return t->ops ? t->ops->get_magic() : 0;
429 }
430 
431 static inline
432 struct xnthread_wait_context *xnthread_get_wait_context(struct xnthread *thread)
433 {
434  return thread->wcontext;
435 }
436 
437 static inline
438 int xnthread_register(struct xnthread *thread, const char *name)
439 {
440  return xnregistry_enter(name, thread, &xnthread_handle(thread), NULL);
441 }
442 
443 static inline
444 struct xnthread *xnthread_lookup(xnhandle_t threadh)
445 {
446  struct xnthread *thread = (struct xnthread *)xnregistry_lookup(threadh);
447  return (thread && xnthread_handle(thread) == threadh) ? thread : NULL;
448 }
449 
450 static inline int xnthread_try_grab(struct xnthread *curr,
451  struct xnsynch *synch)
452 {
453  XENO_BUGON(NUCLEUS, xnsynch_fastlock_p(synch));
454 
455  if (xnsynch_owner(synch) != NULL)
456  return 0;
457 
458  xnsynch_set_owner(synch, curr);
459 
460  if (xnthread_test_state(curr, XNOTHER))
461  xnthread_inc_rescnt(curr);
462 
463  return 1;
464 }
465 
466 #ifdef __cplusplus
467 extern "C" {
468 #endif
469 
470 int xnthread_init(struct xnthread *thread,
471  const struct xnthread_init_attr *attr,
472  struct xnsched *sched,
473  struct xnsched_class *sched_class,
474  const union xnsched_policy_param *sched_param);
475 
476 void xnthread_cleanup_tcb(struct xnthread *thread);
477 
478 char *xnthread_format_status(xnflags_t status, char *buf, int size);
479 
480 int *xnthread_get_errno_location(struct xnthread *thread);
481 
482 xnticks_t xnthread_get_timeout(struct xnthread *thread, xnticks_t tsc_ns);
483 
484 xnticks_t xnthread_get_period(struct xnthread *thread);
485 
486 void xnthread_prepare_wait(struct xnthread_wait_context *wc);
487 
488 void xnthread_finish_wait(struct xnthread_wait_context *wc,
489  void (*cleanup)(struct xnthread_wait_context *wc));
490 
491 #ifdef __cplusplus
492 }
493 #endif
494 
495 #endif /* __KERNEL__ || __XENO_SIM__ */
496 
497 #endif /* !_XENO_NUCLEUS_THREAD_H */
#define XNOTHER
Non real-time shadow (prio=0)
Definition: thread.h:65
This file is part of the Xenomai project.
int cprio
Current priority.
Definition: thread.h:139
unsigned long modeswitches
Number of primary->secondary mode switches.
Definition: thread.h:148
Structure containing thread information.
Definition: thread.h:134
Scheduling information structure.
Definition: sched.h:66
int cpu
CPU the thread currently runs on.
Definition: thread.h:141
int xnregistry_enter(const char *key, void *objaddr, xnhandle_t *phandle, struct xnpnode *pnode)
Register a real-time object.
Definition: registry.c:657
char name[XNOBJECT_NAME_LEN]
Symbolic name assigned at creation.
Definition: thread.h:152
unsigned long pagefaults
Number of triggered page faults.
Definition: thread.h:150
unsigned long affinity
Thread's CPU affinity.
Definition: thread.h:142
unsigned long state
Thread state,.
Definition: thread.h:136
int bprio
Base priority.
Definition: thread.h:138
unsigned long long exectime
Execution time in primary mode in nanoseconds.
Definition: thread.h:146
unsigned long ctxswitches
Number of context switches.
Definition: thread.h:149
unsigned long long relpoint
Time of next release.
Definition: thread.h:144