1*433d6423SLionel Sambuc #ifndef _MTHREAD_H 2*433d6423SLionel Sambuc #define _MTHREAD_H 3*433d6423SLionel Sambuc 4*433d6423SLionel Sambuc #include <minix/config.h> /* MUST be first */ 5*433d6423SLionel Sambuc #include <minix/const.h> 6*433d6423SLionel Sambuc #include <sys/types.h> 7*433d6423SLionel Sambuc #include <stdio.h> 8*433d6423SLionel Sambuc #include <ucontext.h> 9*433d6423SLionel Sambuc #include <errno.h> 10*433d6423SLionel Sambuc #include <stdlib.h> 11*433d6423SLionel Sambuc #include <limits.h> 12*433d6423SLionel Sambuc #include <sys/signal.h> 13*433d6423SLionel Sambuc 14*433d6423SLionel Sambuc typedef int mthread_thread_t; 15*433d6423SLionel Sambuc typedef int mthread_once_t; 16*433d6423SLionel Sambuc typedef int mthread_key_t; 17*433d6423SLionel Sambuc typedef void * mthread_condattr_t; 18*433d6423SLionel Sambuc typedef void * mthread_mutexattr_t; 19*433d6423SLionel Sambuc 20*433d6423SLionel Sambuc struct __mthread_tcb; 21*433d6423SLionel Sambuc typedef struct { 22*433d6423SLionel Sambuc struct __mthread_tcb *mq_head; 23*433d6423SLionel Sambuc struct __mthread_tcb *mq_tail; 24*433d6423SLionel Sambuc } mthread_queue_t; 25*433d6423SLionel Sambuc 26*433d6423SLionel Sambuc struct __mthread_mutex { 27*433d6423SLionel Sambuc mthread_queue_t mm_queue; /* Queue of threads blocked on this mutex */ 28*433d6423SLionel Sambuc mthread_thread_t mm_owner; /* Thread ID that currently owns mutex */ 29*433d6423SLionel Sambuc #ifdef MTHREAD_STRICT 30*433d6423SLionel Sambuc struct __mthread_mutex *mm_prev; 31*433d6423SLionel Sambuc struct __mthread_mutex *mm_next; 32*433d6423SLionel Sambuc #endif 33*433d6423SLionel Sambuc unsigned int mm_magic; 34*433d6423SLionel Sambuc }; 35*433d6423SLionel Sambuc typedef struct __mthread_mutex *mthread_mutex_t; 36*433d6423SLionel Sambuc 37*433d6423SLionel Sambuc struct __mthread_cond { 38*433d6423SLionel Sambuc struct __mthread_mutex *mc_mutex; /* Associate mutex with condition */ 39*433d6423SLionel Sambuc #ifdef MTHREAD_STRICT 40*433d6423SLionel Sambuc struct __mthread_cond *mc_prev; 41*433d6423SLionel Sambuc struct __mthread_cond *mc_next; 42*433d6423SLionel Sambuc #endif 43*433d6423SLionel Sambuc unsigned int mc_magic; 44*433d6423SLionel Sambuc }; 45*433d6423SLionel Sambuc typedef struct __mthread_cond *mthread_cond_t; 46*433d6423SLionel Sambuc 47*433d6423SLionel Sambuc struct __mthread_attr { 48*433d6423SLionel Sambuc size_t ma_stacksize; 49*433d6423SLionel Sambuc char *ma_stackaddr; 50*433d6423SLionel Sambuc int ma_detachstate; 51*433d6423SLionel Sambuc struct __mthread_attr *ma_prev; 52*433d6423SLionel Sambuc struct __mthread_attr *ma_next; 53*433d6423SLionel Sambuc }; 54*433d6423SLionel Sambuc typedef struct __mthread_attr *mthread_attr_t; 55*433d6423SLionel Sambuc 56*433d6423SLionel Sambuc typedef struct { 57*433d6423SLionel Sambuc mthread_mutex_t mutex; 58*433d6423SLionel Sambuc mthread_cond_t cond; 59*433d6423SLionel Sambuc } mthread_event_t; 60*433d6423SLionel Sambuc 61*433d6423SLionel Sambuc typedef struct { 62*433d6423SLionel Sambuc unsigned int readers; 63*433d6423SLionel Sambuc mthread_thread_t writer; 64*433d6423SLionel Sambuc mthread_mutex_t queue; 65*433d6423SLionel Sambuc mthread_event_t drain; 66*433d6423SLionel Sambuc } mthread_rwlock_t; 67*433d6423SLionel Sambuc 68*433d6423SLionel Sambuc #define MTHREAD_CREATE_JOINABLE 001 69*433d6423SLionel Sambuc #define MTHREAD_CREATE_DETACHED 002 70*433d6423SLionel Sambuc #define MTHREAD_ONCE_INIT 0 71*433d6423SLionel Sambuc #define MTHREAD_STACK_MIN MINSIGSTKSZ 72*433d6423SLionel Sambuc #define MTHREAD_KEYS_MAX 128 73*433d6423SLionel Sambuc 74*433d6423SLionel Sambuc __BEGIN_DECLS 75*433d6423SLionel Sambuc /* allocate.c */ 76*433d6423SLionel Sambuc int mthread_create(mthread_thread_t *thread, mthread_attr_t *tattr, void 77*433d6423SLionel Sambuc *(*proc)(void *), void *arg); 78*433d6423SLionel Sambuc int mthread_detach(mthread_thread_t thread); 79*433d6423SLionel Sambuc int mthread_equal(mthread_thread_t l, mthread_thread_t r); 80*433d6423SLionel Sambuc void mthread_exit(void *value); 81*433d6423SLionel Sambuc int mthread_join(mthread_thread_t thread, void **value); 82*433d6423SLionel Sambuc int mthread_once(mthread_once_t *once, void (*proc)(void)); 83*433d6423SLionel Sambuc mthread_thread_t mthread_self(void); 84*433d6423SLionel Sambuc 85*433d6423SLionel Sambuc /* attribute.c */ 86*433d6423SLionel Sambuc int mthread_attr_destroy(mthread_attr_t *tattr); 87*433d6423SLionel Sambuc int mthread_attr_getdetachstate(mthread_attr_t *tattr, int 88*433d6423SLionel Sambuc *detachstate); 89*433d6423SLionel Sambuc int mthread_attr_getstack(mthread_attr_t *tattr, void **stackaddr, 90*433d6423SLionel Sambuc size_t *stacksize); 91*433d6423SLionel Sambuc int mthread_attr_getstacksize(mthread_attr_t *tattr, size_t *stacksize); 92*433d6423SLionel Sambuc int mthread_attr_init(mthread_attr_t *tattr); 93*433d6423SLionel Sambuc int mthread_attr_setdetachstate(mthread_attr_t *tattr, int detachstate); 94*433d6423SLionel Sambuc int mthread_attr_setstack(mthread_attr_t *tattr, void *stackaddr, size_t 95*433d6423SLionel Sambuc stacksize); 96*433d6423SLionel Sambuc int mthread_attr_setstacksize(mthread_attr_t *tattr, size_t stacksize); 97*433d6423SLionel Sambuc 98*433d6423SLionel Sambuc 99*433d6423SLionel Sambuc /* condition.c */ 100*433d6423SLionel Sambuc int mthread_cond_broadcast(mthread_cond_t *cond); 101*433d6423SLionel Sambuc int mthread_cond_destroy(mthread_cond_t *cond); 102*433d6423SLionel Sambuc int mthread_cond_init(mthread_cond_t *cond, mthread_condattr_t *cattr); 103*433d6423SLionel Sambuc int mthread_cond_signal(mthread_cond_t *cond); 104*433d6423SLionel Sambuc int mthread_cond_wait(mthread_cond_t *cond, mthread_mutex_t *mutex); 105*433d6423SLionel Sambuc 106*433d6423SLionel Sambuc /* key.c */ 107*433d6423SLionel Sambuc int mthread_key_create(mthread_key_t *key, void (*destructor)(void *)); 108*433d6423SLionel Sambuc int mthread_key_delete(mthread_key_t key); 109*433d6423SLionel Sambuc void *mthread_getspecific(mthread_key_t key); 110*433d6423SLionel Sambuc int mthread_setspecific(mthread_key_t key, void *value); 111*433d6423SLionel Sambuc 112*433d6423SLionel Sambuc /* misc.c */ 113*433d6423SLionel Sambuc void mthread_stats(void); 114*433d6423SLionel Sambuc void mthread_verify_f(char *f, int l); 115*433d6423SLionel Sambuc #define mthread_verify() mthread_verify_f(__FILE__, __LINE__) 116*433d6423SLionel Sambuc void mthread_stacktrace(mthread_thread_t t); 117*433d6423SLionel Sambuc void mthread_stacktraces(void); 118*433d6423SLionel Sambuc 119*433d6423SLionel Sambuc /* mutex.c */ 120*433d6423SLionel Sambuc int mthread_mutex_destroy(mthread_mutex_t *mutex); 121*433d6423SLionel Sambuc int mthread_mutex_init(mthread_mutex_t *mutex, mthread_mutexattr_t 122*433d6423SLionel Sambuc *mattr); 123*433d6423SLionel Sambuc int mthread_mutex_lock(mthread_mutex_t *mutex); 124*433d6423SLionel Sambuc int mthread_mutex_trylock(mthread_mutex_t *mutex); 125*433d6423SLionel Sambuc int mthread_mutex_unlock(mthread_mutex_t *mutex); 126*433d6423SLionel Sambuc 127*433d6423SLionel Sambuc /* event.c */ 128*433d6423SLionel Sambuc int mthread_event_destroy(mthread_event_t *event); 129*433d6423SLionel Sambuc int mthread_event_init(mthread_event_t *event); 130*433d6423SLionel Sambuc int mthread_event_wait(mthread_event_t *event); 131*433d6423SLionel Sambuc int mthread_event_fire(mthread_event_t *event); 132*433d6423SLionel Sambuc int mthread_event_fire_all(mthread_event_t *event); 133*433d6423SLionel Sambuc 134*433d6423SLionel Sambuc /* rwlock.c */ 135*433d6423SLionel Sambuc int mthread_rwlock_destroy(mthread_rwlock_t *rwlock); 136*433d6423SLionel Sambuc int mthread_rwlock_init(mthread_rwlock_t *rwlock); 137*433d6423SLionel Sambuc int mthread_rwlock_rdlock(mthread_rwlock_t *rwlock); 138*433d6423SLionel Sambuc int mthread_rwlock_wrlock(mthread_rwlock_t *rwlock); 139*433d6423SLionel Sambuc int mthread_rwlock_unlock(mthread_rwlock_t *rwlock); 140*433d6423SLionel Sambuc 141*433d6423SLionel Sambuc /* schedule.c */ 142*433d6423SLionel Sambuc int mthread_yield(void); 143*433d6423SLionel Sambuc void mthread_yield_all(void); 144*433d6423SLionel Sambuc __END_DECLS 145*433d6423SLionel Sambuc 146*433d6423SLionel Sambuc #if defined(_MTHREADIFY_PTHREADS) 147*433d6423SLionel Sambuc typedef mthread_thread_t pthread_t; 148*433d6423SLionel Sambuc typedef mthread_once_t pthread_once_t; 149*433d6423SLionel Sambuc typedef mthread_key_t pthread_key_t; 150*433d6423SLionel Sambuc typedef mthread_cond_t pthread_cond_t; 151*433d6423SLionel Sambuc typedef mthread_mutex_t pthread_mutex_t; 152*433d6423SLionel Sambuc typedef mthread_condattr_t pthread_condattr_t; 153*433d6423SLionel Sambuc typedef mthread_mutexattr_t pthread_mutexattr_t; 154*433d6423SLionel Sambuc typedef mthread_attr_t pthread_attr_t; 155*433d6423SLionel Sambuc typedef mthread_event_t pthread_event_t; 156*433d6423SLionel Sambuc typedef mthread_rwlock_t pthread_rwlock_t; 157*433d6423SLionel Sambuc 158*433d6423SLionel Sambuc /* LSC: No equivalent, so void* for now. */ 159*433d6423SLionel Sambuc typedef void *pthread_rwlockattr_t; 160*433d6423SLionel Sambuc 161*433d6423SLionel Sambuc #define PTHREAD_ONCE_INIT 0 162*433d6423SLionel Sambuc #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1) 163*433d6423SLionel Sambuc #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1) 164*433d6423SLionel Sambuc 165*433d6423SLionel Sambuc __BEGIN_DECLS 166*433d6423SLionel Sambuc /* allocate.c */ 167*433d6423SLionel Sambuc int pthread_create(pthread_t *thread, pthread_attr_t *tattr, void 168*433d6423SLionel Sambuc *(*proc)(void *), void *arg); 169*433d6423SLionel Sambuc int pthread_detach(pthread_t thread); 170*433d6423SLionel Sambuc int pthread_equal(pthread_t l, pthread_t r); 171*433d6423SLionel Sambuc void pthread_exit(void *value); 172*433d6423SLionel Sambuc int pthread_join(pthread_t thread, void **value); 173*433d6423SLionel Sambuc int pthread_once(pthread_once_t *once, void (*proc)(void)); 174*433d6423SLionel Sambuc pthread_t pthread_self(void); 175*433d6423SLionel Sambuc 176*433d6423SLionel Sambuc /* attribute.c */ 177*433d6423SLionel Sambuc int pthread_attr_destroy(pthread_attr_t *tattr); 178*433d6423SLionel Sambuc int pthread_attr_getdetachstate(pthread_attr_t *tattr, int 179*433d6423SLionel Sambuc *detachstate); 180*433d6423SLionel Sambuc int pthread_attr_getstack(pthread_attr_t *tattr, void **stackaddr, 181*433d6423SLionel Sambuc size_t *stacksize); 182*433d6423SLionel Sambuc int pthread_attr_getstacksize(pthread_attr_t *tattr, size_t *stacksize); 183*433d6423SLionel Sambuc int pthread_attr_init(pthread_attr_t *tattr); 184*433d6423SLionel Sambuc int pthread_attr_setdetachstate(pthread_attr_t *tattr, int detachstate); 185*433d6423SLionel Sambuc int pthread_attr_setstack(pthread_attr_t *tattr, void *stackaddr, size_t 186*433d6423SLionel Sambuc stacksize); 187*433d6423SLionel Sambuc int pthread_attr_setstacksize(pthread_attr_t *tattr, size_t stacksize); 188*433d6423SLionel Sambuc 189*433d6423SLionel Sambuc /* condition.c */ 190*433d6423SLionel Sambuc int pthread_cond_broadcast(pthread_cond_t *cond); 191*433d6423SLionel Sambuc int pthread_cond_destroy(pthread_cond_t *cond); 192*433d6423SLionel Sambuc int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cattr); 193*433d6423SLionel Sambuc int pthread_cond_signal(pthread_cond_t *cond); 194*433d6423SLionel Sambuc int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 195*433d6423SLionel Sambuc 196*433d6423SLionel Sambuc /* key.c */ 197*433d6423SLionel Sambuc int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)); 198*433d6423SLionel Sambuc int pthread_key_delete(pthread_key_t key); 199*433d6423SLionel Sambuc void *pthread_getspecific(pthread_key_t key); 200*433d6423SLionel Sambuc int pthread_setspecific(pthread_key_t key, void *value); 201*433d6423SLionel Sambuc 202*433d6423SLionel Sambuc /* mutex.c */ 203*433d6423SLionel Sambuc int pthread_mutex_destroy(pthread_mutex_t *mutex); 204*433d6423SLionel Sambuc int pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t 205*433d6423SLionel Sambuc *mattr); 206*433d6423SLionel Sambuc int pthread_mutex_lock(pthread_mutex_t *mutex); 207*433d6423SLionel Sambuc int pthread_mutex_trylock(pthread_mutex_t *mutex); 208*433d6423SLionel Sambuc int pthread_mutex_unlock(pthread_mutex_t *mutex); 209*433d6423SLionel Sambuc 210*433d6423SLionel Sambuc /* event.c */ 211*433d6423SLionel Sambuc int pthread_event_destroy(pthread_event_t *event); 212*433d6423SLionel Sambuc int pthread_event_init(pthread_event_t *event); 213*433d6423SLionel Sambuc int pthread_event_wait(pthread_event_t *event); 214*433d6423SLionel Sambuc int pthread_event_fire(pthread_event_t *event); 215*433d6423SLionel Sambuc int pthread_event_fire_all(pthread_event_t *event); 216*433d6423SLionel Sambuc 217*433d6423SLionel Sambuc /* rwlock.c */ 218*433d6423SLionel Sambuc int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); 219*433d6423SLionel Sambuc int pthread_rwlock_init(pthread_rwlock_t *rwlock, 220*433d6423SLionel Sambuc pthread_rwlockattr_t *UNUSED(attr)); 221*433d6423SLionel Sambuc int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); 222*433d6423SLionel Sambuc int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); 223*433d6423SLionel Sambuc int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); 224*433d6423SLionel Sambuc 225*433d6423SLionel Sambuc /* schedule.c */ 226*433d6423SLionel Sambuc int pthread_yield(void); 227*433d6423SLionel Sambuc int sched_yield(void); 228*433d6423SLionel Sambuc void pthread_yield_all(void); 229*433d6423SLionel Sambuc 230*433d6423SLionel Sambuc /* LSC: FIXME: Maybe we should really do something with those... */ 231*433d6423SLionel Sambuc #define pthread_mutexattr_init(u) (0) 232*433d6423SLionel Sambuc #define pthread_mutexattr_destroy(u) (0) 233*433d6423SLionel Sambuc 234*433d6423SLionel Sambuc #define PTHREAD_MUTEX_RECURSIVE 0 235*433d6423SLionel Sambuc #define pthread_mutexattr_settype(x, y) (EINVAL) 236*433d6423SLionel Sambuc __END_DECLS 237*433d6423SLionel Sambuc 238*433d6423SLionel Sambuc #endif /* defined(_MTHREADIFY_PTHREADS) */ 239*433d6423SLionel Sambuc #endif 240