Fix MacOS and POSIX semaphores related issues
Recently got a MacBook Pro and decided to check how things build on MacOS. Discovered that POSIX unnamed semaphores weren't implemented, so I reimplemented them with conditional variable and mutex. Additionally, fixed scripts and CMake on MacOS
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
|
||||
#include <BH/Thread.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
|
||||
struct BH_Condition
|
||||
@@ -19,10 +19,22 @@ struct BH_Mutex
|
||||
};
|
||||
|
||||
|
||||
#if (_POSIX_SEMAPHORES >= 200112L)
|
||||
#include <semaphore.h>
|
||||
|
||||
struct BH_Semaphore
|
||||
{
|
||||
sem_t handle;
|
||||
};
|
||||
#else
|
||||
struct BH_Semaphore
|
||||
{
|
||||
int count;
|
||||
int waiters;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t condition;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct BH_Thread
|
||||
|
||||
Reference in New Issue
Block a user