| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /*
- * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
- * License: https://github.com/dbartolini/crown/blob/master/LICENSE
- */
- #include "core/error/error.h"
- #include "core/platform.h"
- #include "core/thread/semaphore.h"
- #if CROWN_PLATFORM_POSIX
- #include <pthread.h>
- #elif CROWN_PLATFORM_WINDOWS
- #include <windows.h>
- #include <limits.h> // LONG_MAX
- #endif
- namespace crown
- {
- struct Private
- {
- #if CROWN_PLATFORM_POSIX
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- s32 count;
- #elif CROWN_PLATFORM_WINDOWS
- HANDLE handle;
- #endif
- };
- Semaphore::Semaphore()
- {
- CE_STATIC_ASSERT(sizeof(_data) >= sizeof(Private));
- Private* priv = (Private*)_data;
- #if CROWN_PLATFORM_POSIX
- int err = 0;
- err = pthread_mutex_init(&priv->mutex, NULL);
- CE_ASSERT(err == 0, "pthread_mutex_init: errno = %d", err);
- err = pthread_cond_init(&priv->cond, NULL);
- CE_ASSERT(err == 0, "pthread_cond_init: errno = %d", err);
- CE_UNUSED(err);
- priv->count = 0;
- #elif CROWN_PLATFORM_WINDOWS
- priv->handle = CreateSemaphore(NULL, 0, LONG_MAX, NULL);
- CE_ASSERT(priv->handle != NULL, "CreateSemaphore: GetLastError = %d", GetLastError());
- CE_UNUSED(priv->handle);
- #endif
- }
- Semaphore::~Semaphore()
- {
- Private* priv = (Private*)_data;
- #if CROWN_PLATFORM_POSIX
- int err = pthread_cond_destroy(&priv->cond);
- CE_ASSERT(err == 0, "pthread_cond_destroy: errno = %d", err);
- CE_UNUSED(err);
- #elif CROWN_PLATFORM_WINDOWS
- BOOL err = CloseHandle(priv->handle);
- CE_ASSERT(err != 0, "CloseHandle: GetLastError = %d", GetLastError());
- CE_UNUSED(err);
- #endif
- }
- void Semaphore::post(u32 count)
- {
- Private* priv = (Private*)_data;
- #if CROWN_PLATFORM_POSIX
- pthread_mutex_lock(&priv->mutex);
- for (u32 i = 0; i < count; ++i)
- {
- int err = pthread_cond_signal(&priv->cond);
- CE_ASSERT(err == 0, "pthread_cond_signal: errno = %d", err);
- CE_UNUSED(err);
- }
- priv->count += count;
- pthread_mutex_unlock(&priv->mutex);
- #elif CROWN_PLATFORM_WINDOWS
- BOOL err = ReleaseSemaphore(priv->handle, count, NULL);
- CE_ASSERT(err != 0, "ReleaseSemaphore: GetLastError = %d", GetLastError());
- CE_UNUSED(err);
- #endif
- }
- void Semaphore::wait()
- {
- Private* priv = (Private*)_data;
- #if CROWN_PLATFORM_POSIX
- pthread_mutex_lock(&priv->mutex);
- while (priv->count <= 0)
- {
- int err = pthread_cond_wait(&priv->cond, &priv->mutex);
- CE_ASSERT(err == 0, "pthread_cond_wait: errno = %d", err);
- CE_UNUSED(err);
- }
- priv->count--;
- pthread_mutex_unlock(&priv->mutex);
- #elif CROWN_PLATFORM_WINDOWS
- DWORD err = WaitForSingleObject(priv->handle, INFINITE);
- CE_ASSERT(err == WAIT_OBJECT_0, "WaitForSingleObject: GetLastError = %d", GetLastError());
- CE_UNUSED(err);
- #endif
- }
- } // namespace crown
|