summaryrefslogtreecommitdiff
path: root/include/private/darwin_semaphore.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/private/darwin_semaphore.h')
-rw-r--r--include/private/darwin_semaphore.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/include/private/darwin_semaphore.h b/include/private/darwin_semaphore.h
new file mode 100644
index 0000000..0f43982
--- /dev/null
+++ b/include/private/darwin_semaphore.h
@@ -0,0 +1,68 @@
+#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