6991c6c926
From-SVN: r69872
69 lines
1.6 KiB
C
69 lines
1.6 KiB
C
#ifndef GC_DARWIN_SEMAPHORE_H
|
|
#define GC_DARWIN_SEMAPHORE_H
|
|
|
|
#if !defined(GC_DARWIN_THREADS)
|
|
#error darwin_semaphore.h included with GC_DARWIN_THREADS not defined
|
|
#endif
|
|
|
|
/*
|
|
This is a very simple semaphore implementation for darwin. It
|
|
is implemented in terms of pthreads calls so it isn't async signal
|
|
safe. This isn't a problem because signals aren't used to
|
|
suspend threads on darwin.
|
|
*/
|
|
|
|
typedef struct {
|
|
pthread_mutex_t mutex;
|
|
pthread_cond_t cond;
|
|
int value;
|
|
} sem_t;
|
|
|
|
static int sem_init(sem_t *sem, int pshared, int value) {
|
|
int ret;
|
|
if(pshared)
|
|
GC_abort("sem_init with pshared set");
|
|
sem->value = value;
|
|
|
|
ret = pthread_mutex_init(&sem->mutex,NULL);
|
|
if(ret < 0) return -1;
|
|
ret = pthread_cond_init(&sem->cond,NULL);
|
|
if(ret < 0) return -1;
|
|
return 0;
|
|
}
|
|
|
|
static int sem_post(sem_t *sem) {
|
|
if(pthread_mutex_lock(&sem->mutex) < 0)
|
|
return -1;
|
|
sem->value++;
|
|
if(pthread_cond_signal(&sem->cond) < 0) {
|
|
pthread_mutex_unlock(&sem->mutex);
|
|
return -1;
|
|
}
|
|
if(pthread_mutex_unlock(&sem->mutex) < 0)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
static int sem_wait(sem_t *sem) {
|
|
if(pthread_mutex_lock(&sem->mutex) < 0)
|
|
return -1;
|
|
while(sem->value == 0) {
|
|
pthread_cond_wait(&sem->cond,&sem->mutex);
|
|
}
|
|
sem->value--;
|
|
if(pthread_mutex_unlock(&sem->mutex) < 0)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
static int sem_destroy(sem_t *sem) {
|
|
int ret;
|
|
ret = pthread_cond_destroy(&sem->cond);
|
|
if(ret < 0) return -1;
|
|
ret = pthread_mutex_destroy(&sem->mutex);
|
|
if(ret < 0) return -1;
|
|
return 0;
|
|
}
|
|
|
|
#endif
|