From ff6e3c025658a5fa1affd094f220b623e7e1b24b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 22:38:23 +0200 Subject: Adding upstream version 6.338.2. Signed-off-by: Daniel Baumann --- src/pl_thread_win32.h | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 src/pl_thread_win32.h (limited to 'src/pl_thread_win32.h') diff --git a/src/pl_thread_win32.h b/src/pl_thread_win32.h new file mode 100644 index 0000000..ef68d50 --- /dev/null +++ b/src/pl_thread_win32.h @@ -0,0 +1,182 @@ +/* + * This file is part of libplacebo. + * + * libplacebo is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * libplacebo is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with libplacebo. If not, see . + */ + +#pragma once + +#include +#include +#include +#include + +#include + +typedef CRITICAL_SECTION pl_mutex; +typedef CONDITION_VARIABLE pl_cond; + +static inline int pl_mutex_init_type_internal(pl_mutex *mutex, enum pl_mutex_type mtype) +{ + (void) mtype; + return !InitializeCriticalSectionEx(mutex, 0, 0); +} + +#define pl_mutex_init_type(mutex, mtype) \ + pl_assert(!pl_mutex_init_type_internal(mutex, mtype)) + +static inline int pl_mutex_destroy(pl_mutex *mutex) +{ + DeleteCriticalSection(mutex); + return 0; +} + +static inline int pl_mutex_lock(pl_mutex *mutex) +{ + EnterCriticalSection(mutex); + return 0; +} + +static inline int pl_mutex_unlock(pl_mutex *mutex) +{ + LeaveCriticalSection(mutex); + return 0; +} + +static inline int pl_cond_init(pl_cond *cond) +{ + InitializeConditionVariable(cond); + return 0; +} + +static inline int pl_cond_destroy(pl_cond *cond) +{ + // condition variables are not destroyed + (void) cond; + return 0; +} + +static inline int pl_cond_broadcast(pl_cond *cond) +{ + WakeAllConditionVariable(cond); + return 0; +} + +static inline int pl_cond_signal(pl_cond *cond) +{ + WakeConditionVariable(cond); + return 0; +} + +static inline int pl_cond_wait(pl_cond *cond, pl_mutex *mutex) +{ + return !SleepConditionVariableCS(cond, mutex, INFINITE); +} + +static inline int pl_cond_timedwait(pl_cond *cond, pl_mutex *mutex, uint64_t timeout) +{ + if (timeout == UINT64_MAX) + return pl_cond_wait(cond, mutex); + + timeout /= UINT64_C(1000000); + if (timeout > INFINITE - 1) + timeout = INFINITE - 1; + + BOOL bRet = SleepConditionVariableCS(cond, mutex, timeout); + if (bRet == FALSE) + { + if (GetLastError() == ERROR_TIMEOUT) + return ETIMEDOUT; + else + return EINVAL; + } + return 0; +} + +typedef SRWLOCK pl_static_mutex; +#define PL_STATIC_MUTEX_INITIALIZER SRWLOCK_INIT + +static inline int pl_static_mutex_lock(pl_static_mutex *mutex) +{ + AcquireSRWLockExclusive(mutex); + return 0; +} + +static inline int pl_static_mutex_unlock(pl_static_mutex *mutex) +{ + ReleaseSRWLockExclusive(mutex); + return 0; +} + +typedef HANDLE pl_thread; +#define PL_THREAD_VOID unsigned __stdcall +#define PL_THREAD_RETURN() return 0 + +static inline int pl_thread_create(pl_thread *thread, + PL_THREAD_VOID (*fun)(void *), + void *__restrict arg) +{ + *thread = (HANDLE) _beginthreadex(NULL, 0, fun, arg, 0, NULL); + return *thread ? 0 : -1; +} + +static inline int pl_thread_join(pl_thread thread) +{ + DWORD ret = WaitForSingleObject(thread, INFINITE); + if (ret != WAIT_OBJECT_0) + return ret == WAIT_ABANDONED ? EINVAL : EDEADLK; + CloseHandle(thread); + return 0; +} + +static inline bool pl_thread_sleep(double t) +{ + // Time is expected in 100 nanosecond intervals. + // Negative values indicate relative time. + LARGE_INTEGER time = { .QuadPart = -(LONGLONG) (t * 1e7) }; + + if (time.QuadPart >= 0) + return true; + + bool ret = false; + +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +# define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x2 +#endif + + HANDLE timer = CreateWaitableTimerEx(NULL, NULL, + CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, + TIMER_ALL_ACCESS); + + // CREATE_WAITABLE_TIMER_HIGH_RESOLUTION is supported in Windows 10 1803+, + // retry without it. + if (!timer) + timer = CreateWaitableTimerEx(NULL, NULL, 0, TIMER_ALL_ACCESS); + + if (!timer) + goto end; + + if (!SetWaitableTimer(timer, &time, 0, NULL, NULL, 0)) + goto end; + + if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0) + goto end; + + ret = true; + +end: + if (timer) + CloseHandle(timer); + return ret; +} -- cgit v1.2.3