19#ifndef _COPPERPLATE_THREADOBJ_H
20#define _COPPERPLATE_THREADOBJ_H
27#include <boilerplate/list.h>
28#include <boilerplate/lock.h>
29#include <boilerplate/sched.h>
30#include <copperplate/clockobj.h>
31#include <copperplate/heapobj.h>
33#ifdef CONFIG_XENO_COBALT
35#include <cobalt/uapi/kernel/types.h>
37struct xnthread_user_window;
39struct threadobj_corespec {
43 struct xnthread_user_window *u_window;
47struct threadobj_stat {
68#define SCHED_CORE SCHED_COBALT
71void threadobj_save_timeout(
struct threadobj_corespec *corespec,
72 const struct timespec *timeout)
80#ifdef CONFIG_XENO_PSHARED
82static inline struct xnthread_user_window *
83threadobj_get_window(
struct threadobj_corespec *corespec)
85 extern void *cobalt_umm_shared;
86 return (
struct xnthread_user_window *)
87 ((caddr_t)cobalt_umm_shared + corespec->u_winoff);
92static inline struct xnthread_user_window *
93threadobj_get_window(
struct threadobj_corespec *corespec)
95 return corespec->u_window;
104struct threadobj_corespec {
105 pthread_cond_t grant_sync;
107 struct sched_param_ex schedparam_unlocked;
110 struct timespec timeout;
111#ifdef CONFIG_XENO_WORKAROUND_CONDVAR_PI
112 int policy_unboosted;
113 struct sched_param_ex schedparam_unboosted;
117struct threadobj_stat {
128#define SCHED_CORE SCHED_FIFO
131void threadobj_save_timeout(
struct threadobj_corespec *corespec,
132 const struct timespec *timeout)
135 corespec->timeout = *timeout;
143#define __THREAD_S_STARTED (1 << 0)
144#define __THREAD_S_WARMUP (1 << 1)
145#define __THREAD_S_ABORTED (1 << 2)
146#define __THREAD_S_LOCKED (1 << 3)
147#define __THREAD_S_ACTIVE (1 << 4)
148#define __THREAD_S_SUSPENDED (1 << 5)
149#define __THREAD_S_SAFE (1 << 6)
150#define __THREAD_S_PERIODIC (1 << 7)
151#define __THREAD_S_DEBUG (1 << 31)
156#define __THREAD_S_RUNNING 0
157#define __THREAD_S_DORMANT (1 << 16)
158#define __THREAD_S_WAIT (1 << 17)
159#define __THREAD_S_TIMEDWAIT (1 << 18)
160#define __THREAD_S_DELAYED (1 << 19)
161#define __THREAD_S_BREAK (__THREAD_S_DELAYED|(1 << 20))
164#define __THREAD_M_LOCK (1 << 0)
165#define __THREAD_M_WARNSW (1 << 1)
166#define __THREAD_M_CONFORMING (1 << 2)
167#define __THREAD_M_SPARE0 (1 << 16)
168#define __THREAD_M_SPARE1 (1 << 17)
169#define __THREAD_M_SPARE2 (1 << 18)
170#define __THREAD_M_SPARE3 (1 << 19)
171#define __THREAD_M_SPARE4 (1 << 20)
172#define __THREAD_M_SPARE5 (1 << 21)
173#define __THREAD_M_SPARE6 (1 << 22)
174#define __THREAD_M_SPARE7 (1 << 23)
180#define THREADOBJ_IRQCONTEXT ((struct threadobj *)&threadobj_tskey)
188 pthread_mutex_t lock;
195 struct sched_param_ex schedparam;
201 void (*finalizer)(
struct threadobj *thobj);
205 struct syncobj *wait_sobj;
206 struct holder wait_link;
209 dref_type(
void *) wait_union;
211 timer_t periodic_timer;
213 struct threadobj_corespec core;
214 struct timespec tslice;
215 pthread_cond_t barrier;
216 struct traceobj *tracer;
218 struct sysgroup_memspec memspec;
219 struct backtrace_data btd;
222struct threadobj_init_data {
226 struct sched_param_ex param_ex;
227 void (*finalizer)(
struct threadobj *thobj);
230extern int threadobj_high_prio;
232extern int threadobj_irq_prio;
234extern pthread_key_t threadobj_tskey;
238extern __thread __attribute__ ((tls_model (CONFIG_XENO_TLS_MODEL)))
239struct threadobj *__threadobj_current;
241static inline void threadobj_set_current(
struct threadobj *thobj)
243 __threadobj_current = thobj;
244 pthread_setspecific(threadobj_tskey, thobj);
247static inline struct threadobj *__threadobj_get_current(
void)
249 return __threadobj_current;
254static inline void threadobj_set_current(
struct threadobj *thobj)
256 pthread_setspecific(threadobj_tskey, thobj);
259static inline struct threadobj *__threadobj_get_current(
void)
261 return (
struct threadobj *)pthread_getspecific(threadobj_tskey);
266static inline struct threadobj *threadobj_current(
void)
268 struct threadobj *thobj = __threadobj_get_current();
269 return thobj == NULL || thobj == THREADOBJ_IRQCONTEXT ? NULL : thobj;
272#ifdef CONFIG_XENO_DEBUG
274static inline void __threadobj_tag_locked(
struct threadobj *thobj)
276 thobj->status |= __THREAD_S_LOCKED;
279static inline void __threadobj_tag_unlocked(
struct threadobj *thobj)
281 assert(thobj->status & __THREAD_S_LOCKED);
282 thobj->status &= ~__THREAD_S_LOCKED;
285static inline void __threadobj_check_locked(
struct threadobj *thobj)
287 assert(thobj->status & __THREAD_S_LOCKED);
292static inline void __threadobj_tag_locked(
struct threadobj *thobj)
296static inline void __threadobj_tag_unlocked(
struct threadobj *thobj)
300static inline void __threadobj_check_locked(
struct threadobj *thobj)
310void *__threadobj_alloc(
size_t tcb_struct_size,
311 size_t wait_union_size,
314static inline void __threadobj_free(
void *p)
319static inline void threadobj_free(
struct threadobj *thobj)
321 __threadobj_free((
unsigned char *)thobj - thobj->core_offset);
324int threadobj_init(
struct threadobj *thobj,
325 struct threadobj_init_data *idata) __must_check;
327int threadobj_start(
struct threadobj *thobj) __must_check;
329int threadobj_shadow(
struct threadobj *thobj,
332int threadobj_prologue(
struct threadobj *thobj,
335void threadobj_wait_start(
void);
337void threadobj_notify_entry(
void);
339int threadobj_cancel(
struct threadobj *thobj);
341void threadobj_uninit(
struct threadobj *thobj);
343int threadobj_suspend(
struct threadobj *thobj);
345int threadobj_resume(
struct threadobj *thobj);
347int threadobj_unblock(
struct threadobj *thobj);
349int __threadobj_lock_sched(
struct threadobj *current);
351int threadobj_lock_sched(
void);
353int __threadobj_unlock_sched(
struct threadobj *current);
355int threadobj_unlock_sched(
void);
357int threadobj_set_schedparam(
struct threadobj *thobj,
int policy,
358 const struct sched_param_ex *param_ex);
360int threadobj_set_schedprio(
struct threadobj *thobj,
int priority);
362int threadobj_set_mode(
int clrmask,
int setmask,
int *mode_r);
364int threadobj_set_periodic(
struct threadobj *thobj,
365 const struct timespec *__restrict__ idate,
366 const struct timespec *__restrict__ period);
368int threadobj_get_periodic(
struct threadobj *thobj,
369 struct timespec *__restrict__ idate,
370 struct timespec *__restrict__ period);
372int threadobj_wait_period(
unsigned long *overruns_r) __must_check;
374void threadobj_spin(ticks_t ns);
376int threadobj_stat(
struct threadobj *thobj,
377 struct threadobj_stat *stat);
379int threadobj_sleep(
const struct timespec *ts);
381void threadobj_set_current_name(
const char *name);
383#ifdef CONFIG_XENO_PSHARED
385static inline int threadobj_local_p(
struct threadobj *thobj)
387 extern pid_t __node_id;
388 return thobj->cnode == __node_id;
393static inline int threadobj_local_p(
struct threadobj *thobj)
400void threadobj_init_key(
void);
402int threadobj_pkg_init(
int anon_session);
408#define threadobj_alloc(T, __mptr, W) \
411 __p = __threadobj_alloc(sizeof(T), sizeof(W), offsetof(T, __mptr)); \
415static inline int threadobj_get_policy(
struct threadobj *thobj)
417 return thobj->policy;
420static inline int threadobj_get_priority(
struct threadobj *thobj)
422 return thobj->schedparam.sched_priority;
425static inline void threadobj_copy_schedparam(
struct sched_param_ex *param_ex,
426 const struct threadobj *thobj)
428 *param_ex = thobj->schedparam;
431static inline int threadobj_lock(
struct threadobj *thobj)
435 ret = write_lock_safe(&thobj->lock, thobj->cancel_state);
439 __threadobj_tag_locked(thobj);
444static inline int threadobj_trylock(
struct threadobj *thobj)
448 ret = write_trylock_safe(&thobj->lock, thobj->cancel_state);
452 __threadobj_tag_locked(thobj);
457static inline int threadobj_unlock(
struct threadobj *thobj)
459 __threadobj_check_locked(thobj);
460 __threadobj_tag_unlocked(thobj);
461 return write_unlock_safe(&thobj->lock, thobj->cancel_state);
464static inline int threadobj_irq_p(
void)
466 struct threadobj *current = __threadobj_get_current();
467 return current == THREADOBJ_IRQCONTEXT;
470static inline int threadobj_current_p(
void)
472 return threadobj_current() != NULL;
475static inline int __threadobj_lock_sched_once(
struct threadobj *current)
477 if (current->schedlock_depth == 0)
478 return __threadobj_lock_sched(current);
483static inline int threadobj_lock_sched_once(
void)
485 struct threadobj *current = threadobj_current();
487 if (current->schedlock_depth == 0)
488 return threadobj_lock_sched();
493static inline void threadobj_yield(
void)
498static inline unsigned int threadobj_get_magic(
struct threadobj *thobj)
503static inline void threadobj_set_magic(
struct threadobj *thobj,
506 thobj->magic = magic;
509static inline int threadobj_get_lockdepth(
struct threadobj *thobj)
511 return thobj->schedlock_depth;
514static inline int threadobj_get_status(
struct threadobj *thobj)
516 return thobj->status | thobj->run_state;
519static inline int threadobj_get_errno(
struct threadobj *thobj)
521 return *thobj->errno_pointer;
524#define threadobj_prepare_wait(T) \
526 struct threadobj *__thobj = threadobj_current(); \
527 assert(__thobj != NULL); \
528 assert(sizeof(typeof(T)) <= __thobj->wait_size); \
529 __mptr(__thobj->wait_union); \
532#define threadobj_finish_wait() do { } while (0)
534static inline void *threadobj_get_wait(
struct threadobj *thobj)
536 return __mptr(thobj->wait_union);
539static inline const char *threadobj_get_name(
struct threadobj *thobj)
544static inline pid_t threadobj_get_pid(
struct threadobj *thobj)
549#ifdef CONFIG_XENO_WORKAROUND_CONDVAR_PI
551int threadobj_cond_timedwait(pthread_cond_t *cond,
552 pthread_mutex_t *lock,
553 const struct timespec *timeout);
555int threadobj_cond_wait(pthread_cond_t *cond,
556 pthread_mutex_t *lock);
558int threadobj_cond_signal(pthread_cond_t *cond);
560int threadobj_cond_broadcast(pthread_cond_t *cond);
565int threadobj_cond_timedwait(pthread_cond_t *cond,
566 pthread_mutex_t *lock,
567 const struct timespec *timeout)
569 return __RT(pthread_cond_timedwait(cond, lock, timeout));
573int threadobj_cond_wait(pthread_cond_t *cond,
574 pthread_mutex_t *lock)
580int threadobj_cond_signal(pthread_cond_t *cond)
586int threadobj_cond_broadcast(pthread_cond_t *cond)
int pthread_cond_signal(pthread_cond_t *cond))
Signal a condition variable.
Definition cond.c:457
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex))
Wait on a condition variable.
Definition cond.c:297
int pthread_cond_broadcast(pthread_cond_t *cond))
Broadcast a condition variable.
Definition cond.c:512
int sched_yield(void))
Yield the processor.
Definition sched.c:52