/** 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); }