#include "u.h" #include #include "libc.h" #include "thread.h" #include "threadimpl.h" static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; static void lockinit(Lock *lk) { pthread_mutexattr_t attr; pthread_mutex_lock(&initmutex); if(lk->init == 0){ pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&lk->mutex, &attr); pthread_mutexattr_destroy(&attr); lk->init = 1; } pthread_mutex_unlock(&initmutex); } int _threadlock(Lock *lk, int block, ulong pc) { int r; if(!lk->init) lockinit(lk); if(block){ if(pthread_mutex_lock(&lk->mutex) != 0) abort(); return 1; }else{ r = pthread_mutex_trylock(&lk->mutex); if(r == 0) return 1; if(r == EBUSY) return 0; abort(); return 0; } } void _threadunlock(Lock *lk, ulong pc) { if(pthread_mutex_unlock(&lk->mutex) != 0) abort(); } void _procsleep(_Procrendez *r) { /* r is protected by r->l, which we hold */ pthread_cond_init(&r->cond, 0); r->asleep = 1; pthread_cond_wait(&r->cond, &r->l->mutex); pthread_cond_destroy(&r->cond); r->asleep = 0; } void _procwakeup(_Procrendez *r) { if(r->asleep){ r->asleep = 0; pthread_cond_signal(&r->cond); } } void _procstart(Proc *p, void (*fn)(void*)) { //print("pc\n"); if(pthread_create(&p->tid, nil, (void*(*)(void*))fn, p) < 0){ //print("pc1\n"); fprint(2, "pthread_create: %r\n"); abort(); } //print("pc2\n"); } static pthread_key_t prockey; Proc* _threadproc(void) { Proc *p; p = pthread_getspecific(prockey); return p; } void _threadsetproc(Proc *p) { pthread_setspecific(prockey, p); } void pthreadinit(void) { pthread_key_create(&prockey, 0); }