Xenomai 3.3.3
Loading...
Searching...
No Matches
thread.h
1/*
2 * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
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#ifndef _COBALT_KERNEL_THREAD_H
20#define _COBALT_KERNEL_THREAD_H
21
22#include <linux/irq_work.h>
23#include <linux/wait.h>
24#include <linux/sched.h>
25#include <linux/sched/rt.h>
26#include <pipeline/thread.h>
27#include <cobalt/kernel/list.h>
28#include <cobalt/kernel/stat.h>
29#include <cobalt/kernel/timer.h>
30#include <cobalt/kernel/registry.h>
31#include <cobalt/kernel/schedparam.h>
32#include <cobalt/kernel/trace.h>
33#include <cobalt/kernel/synch.h>
34#include <cobalt/uapi/kernel/thread.h>
35#include <cobalt/uapi/signal.h>
36#include <asm/xenomai/machine.h>
37#include <asm/xenomai/thread.h>
38
43#define XNTHREAD_BLOCK_BITS (XNSUSP|XNPEND|XNDELAY|XNDORMANT|XNRELAX|XNHELD|XNDBGSTOP)
44#define XNTHREAD_MODE_BITS (XNRRB|XNWARN|XNTRAPLB)
45
46#define XNTHREAD_SIGDEBUG 0
47#define XNTHREAD_SIGSHADOW_HARDEN 1
48#define XNTHREAD_SIGSHADOW_BACKTRACE 2
49#define XNTHREAD_SIGSHADOW_HOME 3
50#define XNTHREAD_SIGTERM 4
51#define XNTHREAD_MAX_SIGNALS 5
52
53struct xnthread;
54struct xnsched;
55struct xnselector;
56struct xnsched_class;
57struct xnsched_tpslot;
58struct xnthread_personality;
59struct completion;
60
61struct lostage_signal {
62 struct irq_work inband_work;
63 struct task_struct *task;
64 int signo, sigval;
65};
66
67struct lostage_wakeup {
68 struct irq_work inband_work;
69 struct task_struct *task;
70};
71
72struct xnthread_init_attr {
73 struct xnthread_personality *personality;
74 cpumask_t affinity;
75 int flags;
76 const char *name;
77};
78
79struct xnthread_start_attr {
80 int mode;
81 void (*entry)(void *cookie);
82 void *cookie;
83};
84
85struct xnthread_wait_context {
86 int posted;
87};
88
89struct xnthread_personality {
90 const char *name;
91 unsigned int magic;
92 int xid;
93 atomic_t refcnt;
94 struct {
95 void *(*attach_process)(void);
96 void (*detach_process)(void *arg);
97 void (*map_thread)(struct xnthread *thread);
98 struct xnthread_personality *(*relax_thread)(struct xnthread *thread);
99 struct xnthread_personality *(*harden_thread)(struct xnthread *thread);
100 struct xnthread_personality *(*move_thread)(struct xnthread *thread,
101 int dest_cpu);
102 struct xnthread_personality *(*exit_thread)(struct xnthread *thread);
103 struct xnthread_personality *(*finalize_thread)(struct xnthread *thread);
104 } ops;
105 struct module *module;
106};
107
108struct xnthread {
109 struct xnarchtcb tcb; /* Architecture-dependent block */
110
111 __u32 state; /* Thread state flags */
112 __u32 info; /* Thread information flags */
113 __u32 local_info; /* Local thread information flags */
114
115 struct xnsched *sched; /* Thread scheduler */
116 struct xnsched_class *sched_class; /* Current scheduling class */
117 struct xnsched_class *base_class; /* Base scheduling class */
118
119#ifdef CONFIG_XENO_OPT_SCHED_TP
120 struct xnsched_tpslot *tps; /* Current partition slot for TP scheduling */
121 struct list_head tp_link; /* Link in per-sched TP thread queue */
122#endif
123#ifdef CONFIG_XENO_OPT_SCHED_SPORADIC
124 struct xnsched_sporadic_data *pss; /* Sporadic scheduling data. */
125#endif
126#ifdef CONFIG_XENO_OPT_SCHED_QUOTA
127 struct xnsched_quota_group *quota; /* Quota scheduling group. */
128 struct list_head quota_expired;
129 struct list_head quota_next;
130#endif
131 cpumask_t affinity; /* Processor affinity. */
132
134 int bprio;
135
137 int cprio;
138
142 int wprio;
143
144 int lock_count;
150 struct list_head rlink;
151
156 struct list_head plink;
157
159 struct list_head glink;
160
173 struct list_head boosters;
174
175 struct xnsynch *wchan; /* Resource the thread pends on */
176
177 struct xnsynch *wwake; /* Wait channel the thread was resumed from */
178
179 int res_count; /* Held resources count */
180
181 struct xntimer rtimer; /* Resource timer */
182
183 struct xntimer ptimer; /* Periodic timer */
184
185 xnticks_t rrperiod; /* Allotted round-robin period (ns) */
186
187 struct xnthread_wait_context *wcontext; /* Active wait context. */
188
189 struct {
190 xnstat_counter_t ssw; /* Primary -> secondary mode switch count */
191 xnstat_counter_t csw; /* Context switches (includes secondary -> primary switches) */
192 xnstat_counter_t xsc; /* Xenomai syscalls */
193 xnstat_counter_t pf; /* Number of page faults */
194 xnstat_exectime_t account; /* Execution time accounting entity */
195 xnstat_exectime_t lastperiod; /* Interval marker for execution time reports */
196 } stat;
197
198 struct xnselector *selector; /* For select. */
199
200 xnhandle_t handle; /* Handle in registry */
201
202 char name[XNOBJECT_NAME_LEN]; /* Symbolic name of thread */
203
204 void (*entry)(void *cookie); /* Thread entry routine */
205 void *cookie; /* Cookie to pass to the entry routine */
206
207 pid_t host_pid; /* PID of host task (if any), or -1 */
208
213 struct xnthread_user_window *u_window;
214
215 struct xnthread_personality *personality;
216
217 struct completion exited;
218
219#ifdef CONFIG_XENO_OPT_DEBUG
220 const char *exe_path; /* Executable path */
221 u32 proghash; /* Hash value for exe_path */
222#endif
223 struct lostage_signal sigarray[XNTHREAD_MAX_SIGNALS];
224 struct lostage_wakeup relax_work;
225};
226
227static inline int xnthread_get_state(const struct xnthread *thread)
228{
229 return thread->state;
230}
231
232static inline int xnthread_test_state(struct xnthread *thread, int bits)
233{
234 return thread->state & bits;
235}
236
237static inline void xnthread_set_state(struct xnthread *thread, int bits)
238{
239 thread->state |= bits;
240}
241
242static inline void xnthread_clear_state(struct xnthread *thread, int bits)
243{
244 thread->state &= ~bits;
245}
246
247static inline int xnthread_test_info(struct xnthread *thread, int bits)
248{
249 return thread->info & bits;
250}
251
252static inline void xnthread_set_info(struct xnthread *thread, int bits)
253{
254 thread->info |= bits;
255}
256
257static inline void xnthread_clear_info(struct xnthread *thread, int bits)
258{
259 thread->info &= ~bits;
260}
261
262static inline int xnthread_test_localinfo(struct xnthread *curr, int bits)
263{
264 return curr->local_info & bits;
265}
266
267static inline void xnthread_set_localinfo(struct xnthread *curr, int bits)
268{
269 curr->local_info |= bits;
270}
271
272static inline void xnthread_clear_localinfo(struct xnthread *curr, int bits)
273{
274 curr->local_info &= ~bits;
275}
276
277static inline struct xnarchtcb *xnthread_archtcb(struct xnthread *thread)
278{
279 return &thread->tcb;
280}
281
282static inline int xnthread_base_priority(const struct xnthread *thread)
283{
284 return thread->bprio;
285}
286
287static inline int xnthread_current_priority(const struct xnthread *thread)
288{
289 return thread->cprio;
290}
291
292static inline struct task_struct *xnthread_host_task(struct xnthread *thread)
293{
294 return xnarch_host_task(xnthread_archtcb(thread));
295}
296
297#define xnthread_for_each_booster(__pos, __thread) \
298 list_for_each_entry(__pos, &(__thread)->boosters, next)
299
300#define xnthread_for_each_booster_safe(__pos, __tmp, __thread) \
301 list_for_each_entry_safe(__pos, __tmp, &(__thread)->boosters, next)
302
303#define xnthread_run_handler(__t, __h, __a...) \
304 do { \
305 struct xnthread_personality *__p__ = (__t)->personality; \
306 if ((__p__)->ops.__h) \
307 (__p__)->ops.__h(__t, ##__a); \
308 } while (0)
309
310#define xnthread_run_handler_stack(__t, __h, __a...) \
311 do { \
312 struct xnthread_personality *__p__ = (__t)->personality; \
313 do { \
314 if ((__p__)->ops.__h == NULL) \
315 break; \
316 __p__ = (__p__)->ops.__h(__t, ##__a); \
317 } while (__p__); \
318 } while (0)
319
320static inline
321struct xnthread_wait_context *xnthread_get_wait_context(struct xnthread *thread)
322{
323 return thread->wcontext;
324}
325
326static inline
327int xnthread_register(struct xnthread *thread, const char *name)
328{
329 return xnregistry_enter(name, thread, &thread->handle, NULL);
330}
331
332static inline
333struct xnthread *xnthread_lookup(xnhandle_t threadh)
334{
335 struct xnthread *thread = xnregistry_lookup(threadh, NULL);
336 return thread && thread->handle == xnhandle_get_index(threadh) ? thread : NULL;
337}
338
339static inline void xnthread_sync_window(struct xnthread *thread)
340{
341 if (thread->u_window) {
342 thread->u_window->state = thread->state;
343 thread->u_window->info = thread->info;
344 }
345}
346
347static inline
348void xnthread_clear_sync_window(struct xnthread *thread, int state_bits)
349{
350 if (thread->u_window) {
351 thread->u_window->state = thread->state & ~state_bits;
352 thread->u_window->info = thread->info;
353 }
354}
355
356static inline
357void xnthread_set_sync_window(struct xnthread *thread, int state_bits)
358{
359 if (thread->u_window) {
360 thread->u_window->state = thread->state | state_bits;
361 thread->u_window->info = thread->info;
362 }
363}
364
365static inline int normalize_priority(int prio)
366{
367 return prio < MAX_RT_PRIO ? prio : MAX_RT_PRIO - 1;
368}
369
370int __xnthread_init(struct xnthread *thread,
371 const struct xnthread_init_attr *attr,
372 struct xnsched *sched,
373 struct xnsched_class *sched_class,
374 const union xnsched_policy_param *sched_param);
375
376void __xnthread_test_cancel(struct xnthread *curr);
377
378void __xnthread_cleanup(struct xnthread *curr);
379
380void __xnthread_discard(struct xnthread *thread);
381
397static inline struct xnthread *xnthread_current(void)
398{
399 return pipeline_current()->thread;
400}
401
413static inline struct xnthread *xnthread_from_task(struct task_struct *p)
414{
415 return pipeline_thread_from_task(p);
416}
417
427static inline void xnthread_test_cancel(void)
428{
429 struct xnthread *curr = xnthread_current();
430
431 if (curr && xnthread_test_info(curr, XNCANCELD))
432 __xnthread_test_cancel(curr);
433}
434
435static inline
436void xnthread_complete_wait(struct xnthread_wait_context *wc)
437{
438 wc->posted = 1;
439}
440
441static inline
442int xnthread_wait_complete_p(struct xnthread_wait_context *wc)
443{
444 return wc->posted;
445}
446
447#ifdef CONFIG_XENO_ARCH_FPU
448void xnthread_switch_fpu(struct xnsched *sched);
449#else
450static inline void xnthread_switch_fpu(struct xnsched *sched) { }
451#endif /* CONFIG_XENO_ARCH_FPU */
452
453void xnthread_deregister(struct xnthread *thread);
454
455char *xnthread_format_status(unsigned long status,
456 char *buf, int size);
457
458static inline pid_t xnthread_host_pid(struct xnthread *thread)
459{
460 return thread->host_pid;
461}
462
463int xnthread_set_clock(struct xnthread *thread,
464 struct xnclock *newclock);
465
466xnticks_t xnthread_get_timeout(struct xnthread *thread,
467 xnticks_t ns);
468
469xnticks_t xnthread_get_period(struct xnthread *thread);
470
471void xnthread_prepare_wait(struct xnthread_wait_context *wc);
472
473int xnthread_init(struct xnthread *thread,
474 const struct xnthread_init_attr *attr,
475 struct xnsched_class *sched_class,
476 const union xnsched_policy_param *sched_param);
477
478int xnthread_start(struct xnthread *thread,
479 const struct xnthread_start_attr *attr);
480
481int xnthread_set_mode(int clrmask,
482 int setmask);
483
484void xnthread_suspend(struct xnthread *thread,
485 int mask,
486 xnticks_t timeout,
487 xntmode_t timeout_mode,
488 struct xnsynch *wchan);
489
490void xnthread_resume(struct xnthread *thread,
491 int mask);
492
493int xnthread_unblock(struct xnthread *thread);
494
495int xnthread_set_periodic(struct xnthread *thread,
496 xnticks_t idate,
497 xntmode_t timeout_mode,
498 xnticks_t period);
499
500int xnthread_wait_period(unsigned long *overruns_r);
501
502int xnthread_set_slice(struct xnthread *thread,
503 xnticks_t quantum);
504
505void xnthread_cancel(struct xnthread *thread);
506
507int xnthread_join(struct xnthread *thread, bool uninterruptible);
508
509int xnthread_harden(void);
510
511void xnthread_relax(int notify, int reason);
512
513void __xnthread_kick(struct xnthread *thread);
514
515void xnthread_kick(struct xnthread *thread);
516
517void __xnthread_demote(struct xnthread *thread);
518
519void xnthread_demote(struct xnthread *thread);
520
521void __xnthread_signal(struct xnthread *thread, int sig, int arg);
522
523void xnthread_signal(struct xnthread *thread, int sig, int arg);
524
525void xnthread_pin_initial(struct xnthread *thread);
526
527void xnthread_call_mayday(struct xnthread *thread, int reason);
528
529static inline void xnthread_get_resource(struct xnthread *curr)
530{
531 if (xnthread_test_state(curr, XNWEAK|XNDEBUG))
532 curr->res_count++;
533}
534
535static inline int xnthread_put_resource(struct xnthread *curr)
536{
537 if (xnthread_test_state(curr, XNWEAK) ||
538 IS_ENABLED(CONFIG_XENO_OPT_DEBUG_MUTEX_SLEEP)) {
539 if (unlikely(curr->res_count == 0)) {
540 if (xnthread_test_state(curr, XNWARN))
541 xnthread_signal(curr, SIGDEBUG,
542 SIGDEBUG_RESCNT_IMBALANCE);
543 return -EPERM;
544 }
545 curr->res_count--;
546 }
547
548 return 0;
549}
550
551static inline void xnthread_commit_ceiling(struct xnthread *curr)
552{
553 if (curr->u_window->pp_pending)
554 xnsynch_commit_ceiling(curr);
555}
556
557#ifdef CONFIG_SMP
558
559void xnthread_migrate_passive(struct xnthread *thread,
560 struct xnsched *sched);
561#else
562
563static inline void xnthread_migrate_passive(struct xnthread *thread,
564 struct xnsched *sched)
565{ }
566
567#endif
568
569int __xnthread_set_schedparam(struct xnthread *thread,
570 struct xnsched_class *sched_class,
571 const union xnsched_policy_param *sched_param);
572
573int xnthread_set_schedparam(struct xnthread *thread,
574 struct xnsched_class *sched_class,
575 const union xnsched_policy_param *sched_param);
576
577int xnthread_killall(int grace, int mask);
578
579void __xnthread_propagate_schedparam(struct xnthread *curr);
580
581static inline void xnthread_propagate_schedparam(struct xnthread *curr)
582{
583 if (xnthread_test_info(curr, XNSCHEDP))
584 __xnthread_propagate_schedparam(curr);
585}
586
587extern struct xnthread_personality xenomai_personality;
588
591#endif /* !_COBALT_KERNEL_THREAD_H */
int xnregistry_enter(const char *key, void *objaddr, xnhandle_t *phandle, struct xnpnode *pnode)
Register a real-time object.
Definition registry.c:634
static void * xnregistry_lookup(xnhandle_t handle, unsigned long *cstamp_r)
Find a real-time object into the registry.
Definition registry.h:176
#define XNSCHEDP
schedparam propagation is pending
Definition thread.h:74
#define XNCANCELD
Cancellation request is pending.
Definition thread.h:72
#define XNWARN
Issue SIGDEBUG on error detection.
Definition thread.h:45
#define XNDEBUG
User-level debugging enabled.
Definition thread.h:52
#define XNWEAK
Non real-time shadow (from the WEAK class)
Definition thread.h:48
int xnthread_wait_period(unsigned long *overruns_r)
Wait for the next periodic release point.
Definition thread.c:1385
static struct xnthread * xnthread_current(void)
Retrieve the current Cobalt core TCB.
Definition thread.h:397
int xnthread_set_mode(int clrmask, int setmask)
Change control mode of the current thread.
Definition thread.c:774
int xnthread_init(struct xnthread *thread, const struct xnthread_init_attr *attr, struct xnsched_class *sched_class, const union xnsched_policy_param *sched_param)
Initialize a new thread.
Definition thread.c:610
int xnthread_unblock(struct xnthread *thread)
Unblock a thread.
Definition thread.c:1203
int xnthread_set_slice(struct xnthread *thread, xnticks_t quantum)
Set thread time-slicing information.
Definition thread.c:1461
void xnthread_resume(struct xnthread *thread, int mask)
Resume a thread.
Definition thread.c:1085
void xnthread_relax(int notify, int reason)
Switch a shadow thread back to the Linux domain.
Definition thread.c:2036
void xnthread_suspend(struct xnthread *thread, int mask, xnticks_t timeout, xntmode_t timeout_mode, struct xnsynch *wchan)
Suspend a thread.
Definition thread.c:868
static void xnthread_test_cancel(void)
Introduce a thread cancellation point.
Definition thread.h:427
void xnthread_cancel(struct xnthread *thread)
Cancel a thread.
Definition thread.c:1518
static struct xnthread * xnthread_from_task(struct task_struct *p)
Retrieve the Cobalt core TCB attached to a Linux task.
Definition thread.h:413
int xnthread_start(struct xnthread *thread, const struct xnthread_start_attr *attr)
Start a newly created thread.
Definition thread.c:683
int xnthread_join(struct xnthread *thread, bool uninterruptible)
Join with a terminated thread.
Definition thread.c:1647
int xnthread_set_periodic(struct xnthread *thread, xnticks_t idate, xntmode_t timeout_mode, xnticks_t period)
Make a thread periodic.
Definition thread.c:1295
int xnthread_harden(void)
Migrate a Linux task to the Xenomai domain.
Definition thread.c:1916
int xnthread_set_schedparam(struct xnthread *thread, struct xnsched_class *sched_class, const union xnsched_policy_param *sched_param)
Change the base scheduling parameters of a thread.
Definition thread.c:1821
Copyright © 2011 Gilles Chanteperdrix gilles.chanteperdrix@xenomai.org.
Definition atomic.h:24
Scheduling information structure.
Definition sched.h:64