Mesa (main): c11: Move the implementation of threads.h into c source code
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jun 15 18:05:01 UTC 2022
Module: Mesa
Branch: main
Commit: e6392fcf3d8b8dd7e3a8427755d8be2f2332366a
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=e6392fcf3d8b8dd7e3a8427755d8be2f2332366a
Author: Yonggang Luo <luoyonggang at gmail.com>
Date: Sat Feb 19 13:19:08 2022 +0800
c11: Move the implementation of threads.h into c source code
By doing this, now the global variable impl_tss_dtor_tbl are only defined one time.
So the memory usage would reduced
Signed-off-by: Yonggang Luo <luoyonggang at gmail.com>
Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15087>
---
docs/license.rst | 2 +-
include/c11/threads.h | 67 ----------
{include/c11 => src/c11/impl}/.editorconfig | 2 +-
src/c11/impl/meson.build | 6 +
.../c11/impl/threads_posix.c | 85 +++++--------
.../c11/impl/threads_win32.c | 130 ++++++++------------
src/c11/threads.h | 136 +++++++++++++++++++++
7 files changed, 226 insertions(+), 202 deletions(-)
diff --git a/docs/license.rst b/docs/license.rst
index 99f8dab3e25..e24cfe5f48b 100644
--- a/docs/license.rst
+++ b/docs/license.rst
@@ -80,7 +80,7 @@ Mesa Component Licenses
+-----------------+------------------------+-----------------------------+
| GLX client code | src/glx/ | SGI Free Software License B |
+-----------------+------------------------+-----------------------------+
-| C11 thread | include/c11/threads*.h | Boost (permissive) |
+| C11 thread | src/c11/impl/threads* | Boost (permissive) |
| emulation | | |
+-----------------+------------------------+-----------------------------+
diff --git a/include/c11/threads.h b/include/c11/threads.h
deleted file mode 100644
index 75bd445faff..00000000000
--- a/include/c11/threads.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * C11 <threads.h> emulation library
- *
- * (C) Copyright yohhoy 2012.
- * Distributed under the Boost Software License, Version 1.0.
- *
- * Permission is hereby granted, free of charge, to any person or organization
- * obtaining a copy of the software and accompanying documentation covered by
- * this license (the "Software") to use, reproduce, display, distribute,
- * execute, and transmit the Software, and to prepare [[derivative work]]s of the
- * Software, and to permit third-parties to whom the Software is furnished to
- * do so, all subject to the following:
- *
- * The copyright notices in the Software and this entire statement, including
- * the above license grant, this restriction and the following disclaimer,
- * must be included in all copies of the Software, in whole or in part, and
- * all derivative works of the Software, unless such copies or derivative
- * works are solely in the form of machine-executable object code generated by
- * a source language processor.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#ifndef EMULATED_THREADS_H_INCLUDED_
-#define EMULATED_THREADS_H_INCLUDED_
-
-#include "c11/time.h"
-
-/*---------------------------- types ----------------------------*/
-typedef void (*tss_dtor_t)(void*);
-typedef int (*thrd_start_t)(void*);
-
-
-/*-------------------- enumeration constants --------------------*/
-enum {
- mtx_plain = 0,
- mtx_try = 1,
- mtx_timed = 2,
- mtx_recursive = 4
-};
-
-enum {
- thrd_success = 0, // succeeded
- thrd_timedout, // timed out
- thrd_error, // failed
- thrd_busy, // resource busy
- thrd_nomem // out of memory
-};
-
-/*-------------------------- functions --------------------------*/
-
-#if defined(_WIN32) && !defined(__CYGWIN__)
-#include "threads_win32.h"
-#elif defined(HAVE_PTHREAD)
-#include "threads_posix.h"
-#else
-#error Not supported on this platform.
-#endif
-
-
-
-#endif /* EMULATED_THREADS_H_INCLUDED_ */
diff --git a/include/c11/.editorconfig b/src/c11/impl/.editorconfig
similarity index 78%
rename from include/c11/.editorconfig
rename to src/c11/impl/.editorconfig
index bdbea000b53..7b12a40ca00 100644
--- a/include/c11/.editorconfig
+++ b/src/c11/impl/.editorconfig
@@ -1,3 +1,3 @@
-[*.h]
+[*.{c,h}]
indent_style = space
indent_size = 4
diff --git a/src/c11/impl/meson.build b/src/c11/impl/meson.build
index ab8f17e33d0..dbd9ecfdd05 100644
--- a/src/c11/impl/meson.build
+++ b/src/c11/impl/meson.build
@@ -22,6 +22,12 @@ files_mesa_util_c11 = files(
'time.c',
)
+if host_machine.system() == 'windows'
+ files_mesa_util_c11 += 'threads_win32.c'
+else
+ files_mesa_util_c11 += 'threads_posix.c'
+endif
+
_libmesa_util_c11 = static_library(
'mesa_util_c11',
[files_mesa_util_c11],
diff --git a/include/c11/threads_posix.h b/src/c11/impl/threads_posix.c
similarity index 86%
rename from include/c11/threads_posix.h
rename to src/c11/impl/threads_posix.c
index 8e17686d51a..736fc587be2 100644
--- a/include/c11/threads_posix.h
+++ b/src/c11/impl/threads_posix.c
@@ -27,15 +27,15 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
-#ifndef assert
#include <assert.h>
-#endif
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <sched.h>
#include <stdint.h> /* for intptr_t */
+#include "c11/threads.h"
+
/*
Configuration macro:
@@ -47,27 +47,7 @@ Configuration macro:
#define EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
#endif
-
-#include <pthread.h>
-
-/*---------------------------- macros ----------------------------*/
-#define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
-#ifdef INIT_ONCE_STATIC_INIT
-#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
-#else
-#define TSS_DTOR_ITERATIONS 1 // assume TSS dtor MAY be called at least once.
-#endif
-
-// FIXME: temporary non-standard hack to ease transition
-#define _MTX_INITIALIZER_NP PTHREAD_MUTEX_INITIALIZER
-
/*---------------------------- types ----------------------------*/
-typedef pthread_cond_t cnd_t;
-typedef pthread_t thrd_t;
-typedef pthread_key_t tss_t;
-typedef pthread_mutex_t mtx_t;
-typedef pthread_once_t once_flag;
-
/*
Implementation limits:
@@ -79,7 +59,7 @@ struct impl_thrd_param {
void *arg;
};
-static inline void *
+static void *
impl_thrd_routine(void *p)
{
struct impl_thrd_param pack = *((struct impl_thrd_param *)p);
@@ -90,7 +70,7 @@ impl_thrd_routine(void *p)
/*--------------- 7.25.2 Initialization functions ---------------*/
// 7.25.2.1
-static inline void
+void
call_once(once_flag *flag, void (*func)(void))
{
pthread_once(flag, func);
@@ -99,7 +79,7 @@ call_once(once_flag *flag, void (*func)(void))
/*------------- 7.25.3 Condition variable functions -------------*/
// 7.25.3.1
-static inline int
+int
cnd_broadcast(cnd_t *cond)
{
assert(cond != NULL);
@@ -107,7 +87,7 @@ cnd_broadcast(cnd_t *cond)
}
// 7.25.3.2
-static inline void
+void
cnd_destroy(cnd_t *cond)
{
assert(cond);
@@ -115,7 +95,7 @@ cnd_destroy(cnd_t *cond)
}
// 7.25.3.3
-static inline int
+int
cnd_init(cnd_t *cond)
{
assert(cond != NULL);
@@ -123,7 +103,7 @@ cnd_init(cnd_t *cond)
}
// 7.25.3.4
-static inline int
+int
cnd_signal(cnd_t *cond)
{
assert(cond != NULL);
@@ -131,7 +111,7 @@ cnd_signal(cnd_t *cond)
}
// 7.25.3.5
-static inline int
+int
cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time)
{
int rt;
@@ -147,7 +127,7 @@ cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time)
}
// 7.25.3.6
-static inline int
+int
cnd_wait(cnd_t *cond, mtx_t *mtx)
{
assert(mtx != NULL);
@@ -158,7 +138,7 @@ cnd_wait(cnd_t *cond, mtx_t *mtx)
/*-------------------- 7.25.4 Mutex functions --------------------*/
// 7.25.4.1
-static inline void
+void
mtx_destroy(mtx_t *mtx)
{
assert(mtx != NULL);
@@ -192,7 +172,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
#endif
// 7.25.4.2
-static inline int
+int
mtx_init(mtx_t *mtx, int type)
{
pthread_mutexattr_t attr;
@@ -216,21 +196,15 @@ mtx_init(mtx_t *mtx, int type)
}
// 7.25.4.3
-static inline int
+int
mtx_lock(mtx_t *mtx)
{
assert(mtx != NULL);
return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error;
}
-static inline int
-mtx_trylock(mtx_t *mtx);
-
-static inline void
-thrd_yield(void);
-
// 7.25.4.4
-static inline int
+int
mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
{
assert(mtx != NULL);
@@ -259,7 +233,7 @@ mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
}
// 7.25.4.5
-static inline int
+int
mtx_trylock(mtx_t *mtx)
{
assert(mtx != NULL);
@@ -267,7 +241,7 @@ mtx_trylock(mtx_t *mtx)
}
// 7.25.4.6
-static inline int
+int
mtx_unlock(mtx_t *mtx)
{
assert(mtx != NULL);
@@ -277,7 +251,7 @@ mtx_unlock(mtx_t *mtx)
/*------------------- 7.25.5 Thread functions -------------------*/
// 7.25.5.1
-static inline int
+int
thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
{
struct impl_thrd_param *pack;
@@ -294,35 +268,36 @@ thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
}
// 7.25.5.2
-static inline thrd_t
+thrd_t
thrd_current(void)
{
return pthread_self();
}
// 7.25.5.3
-static inline int
+int
thrd_detach(thrd_t thr)
{
return (pthread_detach(thr) == 0) ? thrd_success : thrd_error;
}
// 7.25.5.4
-static inline int
+int
thrd_equal(thrd_t thr0, thrd_t thr1)
{
return pthread_equal(thr0, thr1);
}
// 7.25.5.5
-static inline void
+_Noreturn
+void
thrd_exit(int res)
{
pthread_exit((void*)(intptr_t)res);
}
// 7.25.5.6
-static inline int
+int
thrd_join(thrd_t thr, int *res)
{
void *code;
@@ -334,15 +309,15 @@ thrd_join(thrd_t thr, int *res)
}
// 7.25.5.7
-static inline void
+int
thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
{
assert(time_point != NULL);
- nanosleep(time_point, remaining);
+ return nanosleep(time_point, remaining);
}
// 7.25.5.8
-static inline void
+void
thrd_yield(void)
{
sched_yield();
@@ -351,7 +326,7 @@ thrd_yield(void)
/*----------- 7.25.6 Thread-specific storage functions -----------*/
// 7.25.6.1
-static inline int
+int
tss_create(tss_t *key, tss_dtor_t dtor)
{
assert(key != NULL);
@@ -359,21 +334,21 @@ tss_create(tss_t *key, tss_dtor_t dtor)
}
// 7.25.6.2
-static inline void
+void
tss_delete(tss_t key)
{
pthread_key_delete(key);
}
// 7.25.6.3
-static inline void *
+void *
tss_get(tss_t key)
{
return pthread_getspecific(key);
}
// 7.25.6.4
-static inline int
+int
tss_set(tss_t key, void *val)
{
return (pthread_setspecific(key, val) == 0) ? thrd_success : thrd_error;
diff --git a/include/c11/threads_win32.h b/src/c11/impl/threads_win32.c
similarity index 84%
rename from include/c11/threads_win32.h
rename to src/c11/impl/threads_win32.c
index dbda982f7d5..08c9475d81c 100644
--- a/include/c11/threads_win32.h
+++ b/src/c11/impl/threads_win32.c
@@ -26,14 +26,19 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-#ifndef assert
#include <assert.h>
-#endif
#include <limits.h>
#include <errno.h>
#include <process.h> // MSVCRT
#include <stdlib.h>
+#include "c11/threads.h"
+
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif
+#include <windows.h>
+
/*
Configuration macro:
@@ -54,50 +59,17 @@ Configuration macro:
#endif
#define EMULATED_THREADS_TSS_DTOR_SLOTNUM 64 // see TLS_MINIMUM_AVAILABLE
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN 1
-#endif
-#include <windows.h>
-
// check configuration
#if defined(EMULATED_THREADS_USE_NATIVE_CALL_ONCE) && (_WIN32_WINNT < 0x0600)
#error EMULATED_THREADS_USE_NATIVE_CALL_ONCE requires _WIN32_WINNT>=0x0600
#endif
-/*---------------------------- macros ----------------------------*/
-#ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE
-#define ONCE_FLAG_INIT INIT_ONCE_STATIC_INIT
-#else
-#define ONCE_FLAG_INIT {0}
-#endif
-#define TSS_DTOR_ITERATIONS 1
-
-// FIXME: temporary non-standard hack to ease transition
-#define _MTX_INITIALIZER_NP {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0}
-
-/*---------------------------- types ----------------------------*/
-typedef CONDITION_VARIABLE cnd_t;
-typedef HANDLE thrd_t;
-
-typedef DWORD tss_t;
-
-typedef CRITICAL_SECTION mtx_t;
-
-#ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE
-typedef INIT_ONCE once_flag;
-#else
-typedef struct once_flag_t {
- volatile LONG status;
-} once_flag;
-#endif
-
-
-static inline void * tss_get(tss_t key);
-static inline void thrd_yield(void);
-static inline int mtx_trylock(mtx_t *mtx);
-static inline int mtx_lock(mtx_t *mtx);
-static inline int mtx_unlock(mtx_t *mtx);
+static_assert(sizeof(cnd_t) == sizeof(CONDITION_VARIABLE), "The size of cnd_t must equal to CONDITION_VARIABLE");
+static_assert(sizeof(thrd_t) == sizeof(HANDLE), "The size of thrd_t must equal to HANDLE");
+static_assert(sizeof(tss_t) == sizeof(DWORD), "The size of tss_t must equal to DWORD");
+static_assert(sizeof(mtx_t) == sizeof(CRITICAL_SECTION), "The size of mtx_t must equal to CRITICAL_SECTION");
+static_assert(sizeof(once_flag) == sizeof(INIT_ONCE), "The size of once_flag must equal to INIT_ONCE");
/*
Implementation limits:
@@ -168,7 +140,7 @@ static int impl_tss_dtor_register(tss_t key, tss_dtor_t dtor)
return 0;
}
-static void impl_tss_dtor_invoke()
+static void impl_tss_dtor_invoke(void)
{
int i;
for (i = 0; i < EMULATED_THREADS_TSS_DTOR_SLOTNUM; i++) {
@@ -183,7 +155,7 @@ static void impl_tss_dtor_invoke()
/*--------------- 7.25.2 Initialization functions ---------------*/
// 7.25.2.1
-static inline void
+void
call_once(once_flag *flag, void (*func)(void))
{
assert(flag && func);
@@ -191,12 +163,12 @@ call_once(once_flag *flag, void (*func)(void))
{
struct impl_call_once_param param;
param.func = func;
- InitOnceExecuteOnce(flag, impl_call_once_callback, (PVOID)¶m, NULL);
+ InitOnceExecuteOnce((PINIT_ONCE)flag, impl_call_once_callback, (PVOID)¶m, NULL);
}
#else
- if (InterlockedCompareExchange(&flag->status, 1, 0) == 0) {
+ if (InterlockedCompareExchangePointer((PVOID volatile *)&flag->status, (PVOID)1, (PVOID)0) == 0) {
(func)();
- InterlockedExchange(&flag->status, 2);
+ InterlockedExchangePointer((PVOID volatile *)&flag->status, (PVOID)2);
} else {
while (flag->status == 1) {
// busy loop!
@@ -209,16 +181,16 @@ call_once(once_flag *flag, void (*func)(void))
/*------------- 7.25.3 Condition variable functions -------------*/
// 7.25.3.1
-static inline int
+int
cnd_broadcast(cnd_t *cond)
{
assert(cond != NULL);
- WakeAllConditionVariable(cond);
+ WakeAllConditionVariable((PCONDITION_VARIABLE)cond);
return thrd_success;
}
// 7.25.3.2
-static inline void
+void
cnd_destroy(cnd_t *cond)
{
(void)cond;
@@ -227,58 +199,58 @@ cnd_destroy(cnd_t *cond)
}
// 7.25.3.3
-static inline int
+int
cnd_init(cnd_t *cond)
{
assert(cond != NULL);
- InitializeConditionVariable(cond);
+ InitializeConditionVariable((PCONDITION_VARIABLE)cond);
return thrd_success;
}
// 7.25.3.4
-static inline int
+int
cnd_signal(cnd_t *cond)
{
assert(cond != NULL);
- WakeConditionVariable(cond);
+ WakeConditionVariable((PCONDITION_VARIABLE)cond);
return thrd_success;
}
// 7.25.3.5
-static inline int
+int
cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time)
{
assert(cond != NULL);
assert(mtx != NULL);
assert(abs_time != NULL);
const DWORD timeout = impl_abs2relmsec(abs_time);
- if (SleepConditionVariableCS(cond, mtx, timeout))
+ if (SleepConditionVariableCS((PCONDITION_VARIABLE)cond, (PCRITICAL_SECTION)mtx, timeout))
return thrd_success;
return (GetLastError() == ERROR_TIMEOUT) ? thrd_timedout : thrd_error;
}
// 7.25.3.6
-static inline int
+int
cnd_wait(cnd_t *cond, mtx_t *mtx)
{
assert(cond != NULL);
assert(mtx != NULL);
- SleepConditionVariableCS(cond, mtx, INFINITE);
+ SleepConditionVariableCS((PCONDITION_VARIABLE)cond, (PCRITICAL_SECTION)mtx, INFINITE);
return thrd_success;
}
/*-------------------- 7.25.4 Mutex functions --------------------*/
// 7.25.4.1
-static inline void
+void
mtx_destroy(mtx_t *mtx)
{
assert(mtx);
- DeleteCriticalSection(mtx);
+ DeleteCriticalSection((PCRITICAL_SECTION)mtx);
}
// 7.25.4.2
-static inline int
+int
mtx_init(mtx_t *mtx, int type)
{
assert(mtx != NULL);
@@ -287,21 +259,21 @@ mtx_init(mtx_t *mtx, int type)
&& type != (mtx_timed|mtx_recursive)
&& type != (mtx_try|mtx_recursive))
return thrd_error;
- InitializeCriticalSection(mtx);
+ InitializeCriticalSection((PCRITICAL_SECTION)mtx);
return thrd_success;
}
// 7.25.4.3
-static inline int
+int
mtx_lock(mtx_t *mtx)
{
assert(mtx != NULL);
- EnterCriticalSection(mtx);
+ EnterCriticalSection((PCRITICAL_SECTION)mtx);
return thrd_success;
}
// 7.25.4.4
-static inline int
+int
mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
{
assert(mtx != NULL);
@@ -316,26 +288,26 @@ mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
}
// 7.25.4.5
-static inline int
+int
mtx_trylock(mtx_t *mtx)
{
assert(mtx != NULL);
- return TryEnterCriticalSection(mtx) ? thrd_success : thrd_busy;
+ return TryEnterCriticalSection((PCRITICAL_SECTION)mtx) ? thrd_success : thrd_busy;
}
// 7.25.4.6
-static inline int
+int
mtx_unlock(mtx_t *mtx)
{
assert(mtx != NULL);
- LeaveCriticalSection(mtx);
+ LeaveCriticalSection((PCRITICAL_SECTION)mtx);
return thrd_success;
}
/*------------------- 7.25.5 Thread functions -------------------*/
// 7.25.5.1
-static inline int
+int
thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
{
struct impl_thrd_param *pack;
@@ -397,7 +369,7 @@ thrd_current(void)
#endif
// 7.25.5.3
-static inline int
+int
thrd_detach(thrd_t thr)
{
CloseHandle(thr);
@@ -405,14 +377,15 @@ thrd_detach(thrd_t thr)
}
// 7.25.5.4
-static inline int
+int
thrd_equal(thrd_t thr0, thrd_t thr1)
{
return GetThreadId(thr0) == GetThreadId(thr1);
}
// 7.25.5.5
-static inline void
+_Noreturn
+void
thrd_exit(int res)
{
impl_tss_dtor_invoke();
@@ -420,7 +393,7 @@ thrd_exit(int res)
}
// 7.25.5.6
-static inline int
+int
thrd_join(thrd_t thr, int *res)
{
DWORD w, code;
@@ -439,17 +412,18 @@ thrd_join(thrd_t thr, int *res)
}
// 7.25.5.7
-static inline void
+int
thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
{
(void)remaining;
assert(time_point);
assert(!remaining); /* not implemented */
Sleep((DWORD)impl_timespec2msec(time_point));
+ return 0;
}
// 7.25.5.8
-static inline void
+void
thrd_yield(void)
{
SwitchToThread();
@@ -458,7 +432,7 @@ thrd_yield(void)
/*----------- 7.25.6 Thread-specific storage functions -----------*/
// 7.25.6.1
-static inline int
+int
tss_create(tss_t *key, tss_dtor_t dtor)
{
assert(key != NULL);
@@ -473,21 +447,21 @@ tss_create(tss_t *key, tss_dtor_t dtor)
}
// 7.25.6.2
-static inline void
+void
tss_delete(tss_t key)
{
TlsFree(key);
}
// 7.25.6.3
-static inline void *
+void *
tss_get(tss_t key)
{
return TlsGetValue(key);
}
// 7.25.6.4
-static inline int
+int
tss_set(tss_t key, void *val)
{
return TlsSetValue(key, val) ? thrd_success : thrd_error;
diff --git a/src/c11/threads.h b/src/c11/threads.h
new file mode 100644
index 00000000000..23495cd197c
--- /dev/null
+++ b/src/c11/threads.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2022 Yonggang Luo
+ * SPDX-License-Identifier: MIT
+ *
+ * C11 <threads.h> emulation library
+ */
+
+#ifndef C11_THREADS_H_INCLUDED_
+#define C11_THREADS_H_INCLUDED_
+
+#include "c11/time.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <io.h> /* close */
+# include <process.h> /* _exit */
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+# include <unistd.h> /* close, _exit */
+#else
+# error Not supported on this platform.
+#endif
+
+/*---------------------------- macros ---------------------------*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------- types ----------------------------*/
+typedef void (*tss_dtor_t)(void *);
+typedef int (*thrd_start_t)(void *);
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+typedef struct
+{
+ void *Ptr;
+} cnd_t;
+typedef void *thrd_t;
+typedef unsigned long tss_t;
+typedef struct
+{
+ void *DebugInfo;
+ long LockCount;
+ long RecursionCount;
+ void *OwningThread;
+ void *LockSemaphore;
+ uintptr_t SpinCount;
+} mtx_t; /* Mock of CRITICAL_SECTION */
+typedef struct
+{
+ volatile uintptr_t status;
+} once_flag;
+// FIXME: temporary non-standard hack to ease transition
+# define _MTX_INITIALIZER_NP {(void*)-1, -1, 0, 0, 0, 0}
+# define ONCE_FLAG_INIT {0}
+# define TSS_DTOR_ITERATIONS 1
+#elif defined(HAVE_PTHREAD)
+typedef pthread_cond_t cnd_t;
+typedef pthread_t thrd_t;
+typedef pthread_key_t tss_t;
+typedef pthread_mutex_t mtx_t;
+typedef pthread_once_t once_flag;
+// FIXME: temporary non-standard hack to ease transition
+# define _MTX_INITIALIZER_NP PTHREAD_MUTEX_INITIALIZER
+# define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
+# ifdef INIT_ONCE_STATIC_INIT
+# define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
+# else
+# define TSS_DTOR_ITERATIONS 1 // assume TSS dtor MAY be called at least once.
+# endif
+#else
+# error Not supported on this platform.
+#endif
+
+/*-------------------- enumeration constants --------------------*/
+enum
+{
+ mtx_plain = 0,
+ mtx_try = 1,
+ mtx_timed = 2,
+ mtx_recursive = 4
+};
+
+enum
+{
+ thrd_success = 0, // succeeded
+ thrd_timedout, // timed out
+ thrd_error, // failed
+ thrd_busy, // resource busy
+ thrd_nomem // out of memory
+};
+
+/*-------------------------- functions --------------------------*/
+
+void call_once(once_flag *, void (*)(void));
+int cnd_broadcast(cnd_t *);
+void cnd_destroy(cnd_t *);
+int cnd_init(cnd_t *);
+int cnd_signal(cnd_t *);
+int cnd_timedwait(cnd_t *__restrict, mtx_t *__restrict __mtx,
+ const struct timespec *__restrict);
+int cnd_wait(cnd_t *, mtx_t *__mtx);
+void mtx_destroy(mtx_t *__mtx);
+int mtx_init(mtx_t *__mtx, int);
+int mtx_lock(mtx_t *__mtx);
+int mtx_timedlock(mtx_t *__restrict __mtx,
+ const struct timespec *__restrict);
+int mtx_trylock(mtx_t *__mtx);
+int mtx_unlock(mtx_t *__mtx);
+int thrd_create(thrd_t *, thrd_start_t, void *);
+thrd_t thrd_current(void);
+int thrd_detach(thrd_t);
+int thrd_equal(thrd_t, thrd_t);
+#if defined(__cplusplus)
+[[ noreturn ]]
+#else
+_Noreturn
+#endif
+void thrd_exit(int);
+int thrd_join(thrd_t, int *);
+int thrd_sleep(const struct timespec *, struct timespec *);
+void thrd_yield(void);
+int tss_create(tss_t *, tss_dtor_t);
+void tss_delete(tss_t);
+void *tss_get(tss_t);
+int tss_set(tss_t, void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* C11_THREADS_H_INCLUDED_ */
More information about the mesa-commit
mailing list