aboutsummaryrefslogtreecommitdiff
path: root/src/Platform/Posix/Semaphore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Platform/Posix/Semaphore.c')
-rw-r--r--src/Platform/Posix/Semaphore.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/Platform/Posix/Semaphore.c b/src/Platform/Posix/Semaphore.c
index cd40ad1..a37684c 100644
--- a/src/Platform/Posix/Semaphore.c
+++ b/src/Platform/Posix/Semaphore.c
@@ -5,6 +5,7 @@
#include <time.h>
+#if (_POSIX_SEMAPHORES >= 200112L)
BH_Semaphore *BH_SemaphoreNew(int value)
{
BH_Semaphore *semaphore;
@@ -70,3 +71,125 @@ int BH_SemaphoreWaitFor(BH_Semaphore *semaphore,
default: return BH_ERROR;
}
}
+#else
+BH_Semaphore *BH_SemaphoreNew(int value)
+{
+ BH_Semaphore *semaphore;
+
+ /* Allocate space for mutex and initialize it */
+ semaphore = malloc(sizeof(BH_Semaphore));
+ if (semaphore)
+ {
+ semaphore->count = value;
+ semaphore->waiters = 0;
+
+ if (pthread_mutex_init(&semaphore->mutex, NULL))
+ {
+ free(semaphore);
+ return NULL;
+ }
+
+ if (pthread_cond_init(&semaphore->condition, NULL))
+ {
+ pthread_mutex_destroy(&semaphore->mutex);
+ free(semaphore);
+ return NULL;
+ }
+ }
+
+ return semaphore;
+}
+
+
+void BH_SemaphoreFree(BH_Semaphore *semaphore)
+{
+ /* Destroy condition variable and mutex */
+ pthread_cond_destroy(&semaphore->condition);
+ pthread_mutex_destroy(&semaphore->mutex);
+ free(semaphore);
+}
+
+
+int BH_SemaphorePost(BH_Semaphore *semaphore)
+{
+ /* Increase semaphore value */
+ pthread_mutex_lock(&semaphore->mutex);
+ semaphore->count++;
+ if (semaphore->waiters)
+ pthread_cond_signal(&semaphore->condition);
+ pthread_mutex_unlock(&semaphore->mutex);
+
+ return BH_OK;
+}
+
+
+int BH_SemaphoreWait(BH_Semaphore *semaphore)
+{
+ int result;
+
+ /* Wait until semaphore count is not zero */
+ result = BH_ERROR;
+ pthread_mutex_lock(&semaphore->mutex);
+ semaphore->waiters++;
+ while (!semaphore->count)
+ pthread_cond_wait(&semaphore->condition, &semaphore->mutex);
+ semaphore->waiters--;
+ semaphore->count--;
+ pthread_mutex_unlock(&semaphore->mutex);
+
+ return result;
+}
+
+
+int BH_SemaphoreWaitTry(BH_Semaphore *semaphore)
+{
+ int result;
+
+ result = BH_OK;
+
+ /* Check if semaphore count is not zero and decrement it */
+ pthread_mutex_lock(&semaphore->mutex);
+ if (!semaphore->count)
+ result = BH_ERROR;
+ else
+ semaphore->count--;
+ pthread_mutex_unlock(&semaphore->mutex);
+
+ return result;
+}
+
+
+int BH_SemaphoreWaitFor(BH_Semaphore *semaphore,
+ uint32_t timeout)
+{
+ int result;
+ struct timespec ts;
+
+ /* Setup timeout */
+ ts.tv_sec = timeout / 1000;
+ ts.tv_nsec = (timeout - ts.tv_sec * 1000) * 1000000;
+ result = BH_OK;
+
+ /* Wait until semaphore count is not zero or timeout */
+ pthread_mutex_lock(&semaphore->mutex);
+ semaphore->waiters++;
+ while (!semaphore->count && result == BH_OK)
+ {
+ switch (pthread_cond_timedwait(&semaphore->condition, &semaphore->mutex, &ts))
+ {
+ case 0: result = BH_OK; break;
+ case ETIMEDOUT: result = BH_TIMEOUT; break;
+ default: result = BH_ERROR; break;
+ }
+ }
+ semaphore->waiters--;
+
+ /* If everything went fine - decrement semaphore counter */
+ if (!result)
+ semaphore->count--;
+
+ pthread_mutex_unlock(&semaphore->mutex);
+
+ return result;
+}
+#endif