/** pthread.c Copyright (C) 1999, RTFM, Inc. All Rights Reserved. ekr@rtfm.com Tue Feb 23 15:08:03 1999 */ #include #include #include static int thread_count=0; typedef struct { void (*func) PROTO_LIST((void *)); void *arg; } helper; static void *r_thread_real_create PROTO_LIST((void *arg)); static void * r_thread_real_create (void *arg) { helper *h; h=(helper *)arg; thread_count++; h->func(h->arg); thread_count--; free(h); return(0); } int r_thread_fork(func,arg,id) void (*func) PROTO_LIST((void *)); void *arg; r_thread *id; { pthread_t thread; helper *h; int r,_status; h=(helper *)malloc(sizeof(helper)); h->func=func; h->arg=arg; if(r=pthread_create(&thread,0,r_thread_real_create,(void *)h)) ABORT(R_INTERNAL); _status=0; abort: return(_status); } int r_thread_yield (void) { pthread_yield(); } int r_thread_exit (void) { thread_count--; pthread_exit(0); return(0); } int r_thread_wait_last (void) { do { pthread_yield(); usleep(10000); DBG((0,"%d threads left",thread_count)); } while (thread_count); return(0); } int r_rwlock_create (r_rwlock **lockp) { pthread_rwlock_t *lock; int r; if(!(lock=(pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)))) ERETURN(R_NO_MEMORY); if(r=pthread_rwlock_init(lock,0)) ERETURN(R_INTERNAL); *lockp=(void *)lock; return(0); } int r_rwlock_destroy (r_rwlock **lock) { pthread_rwlock_t *plock; if(!lock || !*lock) return(0); plock=(pthread_rwlock_t *)(*lock); pthread_rwlock_destroy(plock); return(0); } int r_rwlock_lock (r_rwlock *lock, int action) { pthread_rwlock_t *plock; int r,_status; plock=(pthread_rwlock_t *)lock; switch(action){ case R_RWLOCK_UNLOCK: if(r=pthread_rwlock_unlock(plock)) ABORT(R_INTERNAL); break; case R_RWLOCK_RLOCK: if(r=pthread_rwlock_rdlock(plock)) ABORT(R_INTERNAL); break; case R_RWLOCK_WLOCK: if(r=pthread_rwlock_wrlock(plock)) ABORT(R_INTERNAL); break; default: ABORT(R_BAD_ARGS); } _status=0; abort: return(_status); }