From: Hans-Kristian Arntzen Subject: [PATCH v6 2/2] vkd3d: Add simple pthread wrapper for MSVC Message-Id: <20191118185537.23698-2-post@arntzen-software.no> Date: Mon, 18 Nov 2019 19:55:37 +0100 In-Reply-To: <20191118185537.23698-1-post@arntzen-software.no> References: <20191118185537.23698-1-post@arntzen-software.no> Signed-off-by: Hans-Kristian Arntzen --- Makefile.am | 1 + include/private/vkd3d_threads.h | 154 ++++++++++++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 2 +- 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 include/private/vkd3d_threads.h diff --git a/Makefile.am b/Makefile.am index 2b0e8f3..92cc69a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -75,6 +75,7 @@ libvkd3d_shader_la_SOURCES = \ include/private/vkd3d_common.h \ include/private/vkd3d_debug.h \ include/private/vkd3d_memory.h \ + include/private/vkd3d_threads.h \ include/vkd3d_shader.h \ libs/vkd3d-shader/checksum.c \ libs/vkd3d-shader/dxbc.c \ diff --git a/include/private/vkd3d_threads.h b/include/private/vkd3d_threads.h new file mode 100644 index 0000000..6201f4d --- /dev/null +++ b/include/private/vkd3d_threads.h @@ -0,0 +1,154 @@ +/* + * Copyright 2019 Hans-Kristian Arntzen for Valve + * + * This library 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. + * + * This library 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_THREADS_H +#define __VKD3D_THREADS_H + +#include "config.h" +#include "vkd3d_memory.h" + +#if defined(HAVE_PTHREAD_H) +#include + +#elif defined(_WIN32) /* HAVE_PTHREAD_H */ + +#define WIN32_LEAN_AND_MEAN +#include + +/* pthread_t is passed by value in some functions, + * which implies we need pthread_t to be a pointer type here. */ +struct pthread +{ + HANDLE thread; + DWORD id; + void * (*routine)(void *); + void *arg; +}; +typedef struct pthread *pthread_t; + +/* pthread_mutex_t is not copyable, so embed CS inline. */ +typedef struct pthread_mutex +{ + CRITICAL_SECTION lock; +} pthread_mutex_t; + +/* pthread_cond_t is not copyable, so embed CV inline. */ +typedef struct pthread_cond +{ + CONDITION_VARIABLE cond; +} pthread_cond_t; + +static DWORD WINAPI win32_thread_wrapper_routine(void *arg) +{ + pthread_t thread = arg; + thread->routine(thread->arg); + return 0; +} + +static inline int pthread_create(pthread_t *out_thread, void *attr, void * (*thread_fun)(void *), void *arg) +{ + pthread_t thread = vkd3d_calloc(1, sizeof(*thread)); + if (!thread) + return -1; + + (void)attr; + thread->routine = thread_fun; + thread->arg = arg; + thread->thread = CreateThread(NULL, 0, win32_thread_wrapper_routine, thread, 0, &thread->id); + if (!thread->thread) + { + vkd3d_free(thread); + return -1; + } + *out_thread = thread; + return 0; +} + +static inline int pthread_join(pthread_t thread, void **ret) +{ + (void)ret; + int success = WaitForSingleObject(thread->thread, INFINITE) == WAIT_OBJECT_0; + if (success) + { + CloseHandle(thread->thread); + vkd3d_free(thread); + } + return success ? 0 : -1; +} + +static inline int pthread_mutex_init(pthread_mutex_t *lock, void *attr) +{ + (void)attr; + InitializeCriticalSection(&lock->lock); + return 0; +} + +static inline int pthread_mutex_lock(pthread_mutex_t *lock) +{ + EnterCriticalSection(&lock->lock); + return 0; +} + +static inline int pthread_mutex_unlock(pthread_mutex_t *lock) +{ + LeaveCriticalSection(&lock->lock); + return 0; +} + +static inline int pthread_mutex_destroy(pthread_mutex_t *lock) +{ + DeleteCriticalSection(&lock->lock); + return 0; +} + +static inline int pthread_cond_init(pthread_cond_t *cond, void *attr) +{ + (void)attr; + InitializeConditionVariable(&cond->cond); + return 0; +} + +static inline int pthread_cond_destroy(pthread_cond_t *cond) +{ + (void)cond; + return 0; +} + +static inline int pthread_cond_signal(pthread_cond_t *cond) +{ + WakeConditionVariable(&cond->cond); + return 0; +} + +static inline int pthread_cond_broadcast(pthread_cond_t *cond) +{ + WakeAllConditionVariable(&cond->cond); + return 0; +} + +static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *lock) +{ + BOOL ret = SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE); + return ret ? 0 : -1; +} + +#else /* HAVE_PTHREAD_H */ +#error "Threads are not supported. Cannot build." +#endif /* HAVE_PTHREAD_H */ + +#endif /* __VKD3D_THREADS_H */ diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index a90f7e5..cfc0e38 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -31,11 +31,11 @@ #include "vkd3d.h" #include "vkd3d_shader.h" +#include "vkd3d_threads.h" #include #include #include -#include #include #define VK_CALL(f) (vk_procs->f) -- 2.24.0