1 /**
2    pthread.c
3 
4    Copyright (C) 1999, RTFM, Inc.
5    All Rights Reserved.
6 
7    ekr@rtfm.com  Tue Feb 23 15:08:03 1999
8  */
9 
10 
11 static char *RCSSTRING="$Id: pthread.c,v 1.1.1.1 2000/10/09 00:45:39 ekr Exp $";
12 
13 #include <r_common.h>
14 #include <r_thread.h>
15 #include <pthread.h>
16 
17 static int thread_count=0;
18 
19 typedef struct {
20      void (*func) PROTO_LIST((void *));
21      void *arg;
22 } helper;
23 
24 
25 static void *r_thread_real_create PROTO_LIST((void *arg));
26 
r_thread_real_create(arg)27 static void *r_thread_real_create(arg)
28   void *arg;
29   {
30     helper *h;
31 
32     h=(helper *)arg;
33 
34     thread_count++;
35 
36     h->func(h->arg);
37 
38     thread_count--;
39     free(h);
40     return(0);
41   }
42 
43 int r_thread_fork(func,arg,id)
44   void (*func) PROTO_LIST((void *));
45   void *arg;
46   r_thread *id;
47   {
48     pthread_t thread;
49     helper *h;
50     int r,_status;
51 
52     h=(helper *)malloc(sizeof(helper));
53 
54     h->func=func;
55     h->arg=arg;
56 
57     if(r=pthread_create(&thread,0,r_thread_real_create,(void *)h))
58       ABORT(R_INTERNAL);
59 
60     _status=0;
61   abort:
62     return(_status);
63   }
64 
r_thread_yield()65 int r_thread_yield()
66   {
67     pthread_yield();
68   }
69 
r_thread_exit()70 int r_thread_exit()
71   {
72     thread_count--;
73     pthread_exit(0);
74     return(0);
75   }
76 
r_thread_wait_last()77 int r_thread_wait_last()
78   {
79     do {
80       pthread_yield();
81       usleep(10000);
82       DBG((0,"%d threads left",thread_count));
83     } while (thread_count);
84 
85     return(0);
86   }
87 
r_rwlock_create(lockp)88 int r_rwlock_create(lockp)
89   r_rwlock **lockp;
90   {
91     pthread_rwlock_t *lock;
92     int r;
93 
94     if(!(lock=(pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t))))
95       ERETURN(R_NO_MEMORY);
96 
97     if(r=pthread_rwlock_init(lock,0))
98       ERETURN(R_INTERNAL);
99 
100     *lockp=(void *)lock;
101     return(0);
102   }
103 
r_rwlock_destroy(lock)104 int r_rwlock_destroy(lock)
105   r_rwlock **lock;
106   {
107     pthread_rwlock_t *plock;
108 
109     if(!lock || !*lock)
110       return(0);
111 
112     plock=(pthread_rwlock_t *)(*lock);
113 
114     pthread_rwlock_destroy(plock);
115 
116     return(0);
117   }
118 
r_rwlock_lock(lock,action)119 int r_rwlock_lock(lock,action)
120   r_rwlock *lock;
121   int action;
122   {
123     pthread_rwlock_t *plock;
124     int r,_status;
125 
126     plock=(pthread_rwlock_t *)lock;
127 
128     switch(action){
129       case R_RWLOCK_UNLOCK:
130 	if(r=pthread_rwlock_unlock(plock))
131 	  ABORT(R_INTERNAL);
132 	break;
133       case R_RWLOCK_RLOCK:
134 	if(r=pthread_rwlock_rdlock(plock))
135 	  ABORT(R_INTERNAL);
136 	break;
137       case R_RWLOCK_WLOCK:
138 	if(r=pthread_rwlock_wrlock(plock))
139 	  ABORT(R_INTERNAL);
140 	break;
141       default:
142 	ABORT(R_BAD_ARGS);
143     }
144 
145     _status=0;
146   abort:
147     return(_status);
148   }
149 
150 
151 
152