1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
/**
pthread.c
Copyright (C) 1999, RTFM, Inc.
All Rights Reserved.
ekr@rtfm.com Tue Feb 23 15:08:03 1999
*/
#include <r_common.h>
#include <r_thread.h>
#include <pthread.h>
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;
}
|