Add condition variable support and reimplement PLT_EVENT with it for non-Win32 platforms

This commit is contained in:
Cameron Gutman 2021-06-09 19:28:46 -05:00
parent ccec4e8475
commit 61b4fc1fe7
2 changed files with 86 additions and 72 deletions

View File

@ -286,23 +286,14 @@ int PltCreateEvent(PLT_EVENT* event) {
if (!*event) {
return -1;
}
#elif defined(__vita__)
event->mutex = sceKernelCreateMutex("", 0, 0, NULL);
if (event->mutex < 0) {
return -1;
}
event->cond = sceKernelCreateCond("", 0, event->mutex, NULL);
if (event->cond < 0) {
sceKernelDeleteMutex(event->mutex);
return -1;
}
event->signalled = false;
#elif defined(__WIIU__)
OSFastMutex_Init(&event->mutex, "");
OSFastCond_Init(&event->cond, "");
#else
pthread_mutex_init(&event->mutex, NULL);
pthread_cond_init(&event->cond, NULL);
if (PltCreateMutex(&event->mutex) < 0) {
return -1;
}
if (PltCreateConditionVariable(&event->cond, &event->mutex) < 0) {
PltDeleteMutex(&event->mutex);
return -1;
}
event->signalled = false;
#endif
activeEvents++;
@ -313,35 +304,20 @@ void PltCloseEvent(PLT_EVENT* event) {
activeEvents--;
#if defined(LC_WINDOWS)
CloseHandle(*event);
#elif defined(__vita__)
sceKernelDeleteCond(event->cond);
sceKernelDeleteMutex(event->mutex);
#elif defined(__WIIU__)
#else
pthread_mutex_destroy(&event->mutex);
pthread_cond_destroy(&event->cond);
PltDeleteConditionVariable(&event->cond);
PltDeleteMutex(&event->mutex);
#endif
}
void PltSetEvent(PLT_EVENT* event) {
#if defined(LC_WINDOWS)
SetEvent(*event);
#elif defined(__vita__)
sceKernelLockMutex(event->mutex, 1, NULL);
event->signalled = true;
sceKernelUnlockMutex(event->mutex, 1);
sceKernelSignalCondAll(event->cond);
#elif defined(__WIIU__)
OSFastMutex_Lock(&event->mutex);
event->signalled = 1;
OSFastMutex_Unlock(&event->mutex);
OSFastCond_Signal(&event->cond);
#else
pthread_mutex_lock(&event->mutex);
PltLockMutex(&event->mutex);
event->signalled = true;
pthread_mutex_unlock(&event->mutex);
pthread_cond_broadcast(&event->cond);
PltUnlockMutex(&event->mutex);
PltSignalConditionVariable(&event->cond);
#endif
}
@ -365,33 +341,68 @@ int PltWaitForEvent(PLT_EVENT* event) {
LC_ASSERT(false);
return -1;
}
#elif defined(__vita__)
sceKernelLockMutex(event->mutex, 1, NULL);
while (!event->signalled) {
sceKernelWaitCond(event->cond, NULL);
}
sceKernelUnlockMutex(event->mutex, 1);
return PLT_WAIT_SUCCESS;
#elif defined(__WIIU__)
OSFastMutex_Lock(&event->mutex);
while (!event->signalled) {
OSFastCond_Wait(&event->cond, &event->mutex);
}
OSFastMutex_Unlock(&event->mutex);
return PLT_WAIT_SUCCESS;
#else
pthread_mutex_lock(&event->mutex);
PltLockMutex(&event->mutex);
while (!event->signalled) {
pthread_cond_wait(&event->cond, &event->mutex);
PltWaitForConditionVariable(&event->cond, &event->mutex);
}
pthread_mutex_unlock(&event->mutex);
PltUnlockMutex(&event->mutex);
return PLT_WAIT_SUCCESS;
#endif
}
int PltCreateConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex) {
#if defined(LC_WINDOWS)
InitializeConditionVariable(cond);
#elif defined(__vita__)
*cond = sceKernelCreateCond("", 0, *mutex, NULL);
if (*cond < 0) {
return -1;
}
#elif defined(__WIIU__)
OSFastCond_Init(cond, "");
#else
pthread_cond_init(cond, NULL);
#endif
return 0;
}
void PltDeleteConditionVariable(PLT_COND* cond) {
#if defined(LC_WINDOWS)
// No-op to delete a CONDITION_VARIABLE
#elif defined(__vita__)
sceKernelDeleteCond(*cond);
#elif defined(__WIIU__)
// No-op to delete an OSFastCondition
#else
pthread_cond_destroy(cond);
#endif
}
void PltSignalConditionVariable(PLT_COND* cond) {
#if defined(LC_WINDOWS)
WakeConditionVariable(cond);
#elif defined(__vita__)
sceKernelSignalCond(*cond);
#elif defined(__WIIU__)
OSFastCond_Signal(cond);
#else
pthread_cond_signal(cond);
#endif
}
void PltWaitForConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex) {
#if defined(LC_WINDOWS)
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
#elif defined(__vita__)
sceKernelWaitCond(*cond, NULL);
#elif defined(__WIIU__)
OSFastCond_Wait(cond, mutex);
#else
pthread_cond_wait(cond, mutex);
#endif
}
uint64_t PltGetMillis(void) {
#if defined(LC_WINDOWS)
return GetTickCount64();

View File

@ -7,18 +7,14 @@ typedef void(*ThreadEntry)(void* context);
#if defined(LC_WINDOWS)
typedef SRWLOCK PLT_MUTEX;
typedef HANDLE PLT_EVENT;
typedef CONDITION_VARIABLE PLT_COND;
typedef struct _PLT_THREAD {
HANDLE handle;
bool cancelled;
} PLT_THREAD;
#elif defined(__vita__)
typedef int PLT_MUTEX;
typedef struct _PLT_EVENT {
int mutex;
int cond;
bool signalled;
} PLT_EVENT;
typedef int PLT_COND;
typedef struct _PLT_THREAD {
int handle;
int cancelled;
@ -27,22 +23,14 @@ typedef struct _PLT_THREAD {
} PLT_THREAD;
#elif defined(__WIIU__)
typedef OSFastMutex PLT_MUTEX;
typedef struct _PLT_EVENT {
OSFastMutex mutex;
OSFastCondition cond;
int signalled;
} PLT_EVENT;
typedef OSFastCondition PLT_COND;
typedef struct _PLT_THREAD {
OSThread thread;
int cancelled;
} PLT_THREAD;
#elif defined (LC_POSIX)
typedef pthread_mutex_t PLT_MUTEX;
typedef struct _PLT_EVENT {
pthread_mutex_t mutex;
pthread_cond_t cond;
bool signalled;
} PLT_EVENT;
typedef pthread_cond_t PLT_COND;
typedef struct _PLT_THREAD {
pthread_t thread;
bool cancelled;
@ -51,6 +39,16 @@ typedef struct _PLT_THREAD {
#error Unsupported platform
#endif
#ifdef LC_WINDOWS
typedef HANDLE PLT_EVENT;
#else
typedef struct _PLT_EVENT {
PLT_MUTEX mutex;
PLT_COND cond;
bool signalled;
} PLT_EVENT;
#endif
int PltCreateMutex(PLT_MUTEX* mutex);
void PltDeleteMutex(PLT_MUTEX* mutex);
void PltLockMutex(PLT_MUTEX* mutex);
@ -68,6 +66,11 @@ void PltSetEvent(PLT_EVENT* event);
void PltClearEvent(PLT_EVENT* event);
int PltWaitForEvent(PLT_EVENT* event);
int PltCreateConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex);
void PltDeleteConditionVariable(PLT_COND* cond);
void PltSignalConditionVariable(PLT_COND* cond);
void PltWaitForConditionVariable(PLT_COND* cond, PLT_MUTEX* mutex);
#define PLT_WAIT_SUCCESS 0
#define PLT_WAIT_INTERRUPTED 1