Blob


1 #include "u.h"
2 #include <errno.h>
3 #include "libc.h"
4 #include "thread.h"
5 #include "threadimpl.h"
7 static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;
9 static void
10 lockinit(Lock *lk)
11 {
12 pthread_mutexattr_t attr;
14 pthread_mutex_lock(&initmutex);
15 if(lk->init == 0){
16 pthread_mutexattr_init(&attr);
17 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
18 pthread_mutex_init(&lk->mutex, &attr);
19 pthread_mutexattr_destroy(&attr);
20 lk->init = 1;
21 }
22 pthread_mutex_unlock(&initmutex);
23 }
25 int
26 _threadlock(Lock *lk, int block, ulong pc)
27 {
28 int r;
30 if(!lk->init)
31 lockinit(lk);
32 if(block){
33 if(pthread_mutex_lock(&lk->mutex) != 0)
34 abort();
35 return 1;
36 }else{
37 r = pthread_mutex_trylock(&lk->mutex);
38 if(r == 0)
39 return 1;
40 if(r == EBUSY)
41 return 0;
42 abort();
43 return 0;
44 }
45 }
47 void
48 _threadunlock(Lock *lk, ulong pc)
49 {
50 if(pthread_mutex_unlock(&lk->mutex) != 0)
51 abort();
52 }
54 void
55 _procsleep(_Procrendez *r)
56 {
57 /* r is protected by r->l, which we hold */
58 pthread_cond_init(&r->cond, 0);
59 r->asleep = 1;
60 pthread_cond_wait(&r->cond, &r->l->mutex);
61 pthread_cond_destroy(&r->cond);
62 r->asleep = 0;
63 }
65 void
66 _procwakeup(_Procrendez *r)
67 {
68 if(r->asleep){
69 r->asleep = 0;
70 pthread_cond_signal(&r->cond);
71 }
72 }
74 static void
75 startprocfn(void *v)
76 {
77 void **a;
78 void (*fn)(void*);
79 Proc *p;
81 a = (void**)v;
82 fn = a[0];
83 p = a[1];
84 free(a);
85 p->osprocid = pthread_self();
86 pthread_detach(p->osprocid);
88 (*fn)(p);
90 pthread_exit(0);
91 }
93 void
94 _procstart(Proc *p, void (*fn)(Proc*))
95 {
96 void **a;
98 a = malloc(2*sizeof a[0]);
99 if(a == nil)
100 sysfatal("_procstart malloc: %r");
101 a[0] = fn;
102 a[1] = p;
104 if(pthread_create(&p->osprocid, nil, (void*(*)(void*))startprocfn, (void*)a) < 0){
105 fprint(2, "pthread_create: %r\n");
106 abort();
110 static pthread_key_t prockey;
112 Proc*
113 _threadproc(void)
115 Proc *p;
117 p = pthread_getspecific(prockey);
118 return p;
121 void
122 _threadsetproc(Proc *p)
124 pthread_setspecific(prockey, p);
127 void
128 _pthreadinit(void)
130 pthread_key_create(&prockey, 0);