2015-01-31 09:13:33 +00:00
|
|
|
/**
|
|
|
|
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));
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
static void *
|
|
|
|
r_thread_real_create (void *arg)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_thread_yield (void)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
pthread_yield();
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_thread_exit (void)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
thread_count--;
|
|
|
|
pthread_exit(0);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_thread_wait_last (void)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
do {
|
|
|
|
pthread_yield();
|
|
|
|
usleep(10000);
|
|
|
|
DBG((0,"%d threads left",thread_count));
|
|
|
|
} while (thread_count);
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_rwlock_create (r_rwlock **lockp)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_rwlock_destroy (r_rwlock **lock)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
pthread_rwlock_t *plock;
|
|
|
|
|
|
|
|
if(!lock || !*lock)
|
|
|
|
return(0);
|
|
|
|
|
|
|
|
plock=(pthread_rwlock_t *)(*lock);
|
|
|
|
|
|
|
|
pthread_rwlock_destroy(plock);
|
|
|
|
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2023-08-14 08:57:16 +00:00
|
|
|
int
|
|
|
|
r_rwlock_lock (r_rwlock *lock, int action)
|
2015-01-31 09:13:33 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|