From b2ddec4e98fea9b824e7258468e5b5da9ba848b0 Mon Sep 17 00:00:00 2001 From: Yonggang Luo Date: Sat, 19 Feb 2022 13:19:08 +0800 Subject: [PATCH] c11: Implement c11/time.h with c11/impl/time.c Create c11/time.h instead of put timespec_get in `c11/threads.h` Creating impl folder is used to avoid `#include ` point the c11/time.h file Detecting if `struct timespec` present with meson Define TIME_UTC in `c11/time.h` instead `c11/threads.h` Define `struct timespec` in `c11/time.h` when not present. Implement timespec_get in c11/impl/time.c instead threads.h Signed-off-by: Yonggang Luo Reviewed-by: Jason Ekstrand Part-of: --- include/c11/threads.h | 6 +--- include/c11/threads_posix.h | 16 ---------- include/c11/threads_win32.h | 27 ---------------- meson.build | 4 +++ src/c11/impl/meson.build | 38 +++++++++++++++++++++++ src/c11/impl/time.c | 43 ++++++++++++++++++++++++++ src/c11/time.h | 51 +++++++++++++++++++++++++++++++ src/mapi/es1api/meson.build | 2 +- src/mapi/es2api/meson.build | 2 +- src/mapi/glapi/meson.build | 2 +- src/mapi/shared-glapi/meson.build | 4 +-- src/meson.build | 1 + src/util/meson.build | 1 + 13 files changed, 144 insertions(+), 53 deletions(-) create mode 100644 src/c11/impl/meson.build create mode 100644 src/c11/impl/time.c create mode 100644 src/c11/time.h diff --git a/include/c11/threads.h b/include/c11/threads.h index 81f4b9b7c0945..75bd445faffbc 100644 --- a/include/c11/threads.h +++ b/include/c11/threads.h @@ -29,11 +29,7 @@ #ifndef EMULATED_THREADS_H_INCLUDED_ #define EMULATED_THREADS_H_INCLUDED_ -#include - -#ifndef TIME_UTC -#define TIME_UTC 1 -#endif +#include "c11/time.h" /*---------------------------- types ----------------------------*/ typedef void (*tss_dtor_t)(void*); diff --git a/include/c11/threads_posix.h b/include/c11/threads_posix.h index 802526a77c847..8e17686d51a46 100644 --- a/include/c11/threads_posix.h +++ b/include/c11/threads_posix.h @@ -378,19 +378,3 @@ tss_set(tss_t key, void *val) { return (pthread_setspecific(key, val) == 0) ? thrd_success : thrd_error; } - - -/*-------------------- 7.25.7 Time functions --------------------*/ -// 7.25.6.1 -#ifndef HAVE_TIMESPEC_GET -static inline int -timespec_get(struct timespec *ts, int base) -{ - if (!ts) return 0; - if (base == TIME_UTC) { - clock_gettime(CLOCK_REALTIME, ts); - return base; - } - return 0; -} -#endif diff --git a/include/c11/threads_win32.h b/include/c11/threads_win32.h index 13feb820d0794..dbda982f7d5b5 100644 --- a/include/c11/threads_win32.h +++ b/include/c11/threads_win32.h @@ -128,7 +128,6 @@ static time_t impl_timespec2msec(const struct timespec *ts) return (ts->tv_sec * 1000U) + (ts->tv_nsec / 1000000L); } -#ifdef HAVE_TIMESPEC_GET static DWORD impl_abs2relmsec(const struct timespec *abs_time) { const time_t abs_ms = impl_timespec2msec(abs_time); @@ -138,7 +137,6 @@ static DWORD impl_abs2relmsec(const struct timespec *abs_time) const DWORD rel_ms = (abs_ms > now_ms) ? (DWORD)(abs_ms - now_ms) : 0; return rel_ms; } -#endif #ifdef EMULATED_THREADS_USE_NATIVE_CALL_ONCE struct impl_call_once_param { void (*func)(void); }; @@ -253,14 +251,10 @@ cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time) assert(cond != NULL); assert(mtx != NULL); assert(abs_time != NULL); -#ifdef HAVE_TIMESPEC_GET const DWORD timeout = impl_abs2relmsec(abs_time); if (SleepConditionVariableCS(cond, mtx, timeout)) return thrd_success; return (GetLastError() == ERROR_TIMEOUT) ? thrd_timedout : thrd_error; -#else - return thrd_error; -#endif } // 7.25.3.6 @@ -312,7 +306,6 @@ mtx_timedlock(mtx_t *mtx, const struct timespec *ts) { assert(mtx != NULL); assert(ts != NULL); -#ifdef HAVE_TIMESPEC_GET while (mtx_trylock(mtx) != thrd_success) { if (impl_abs2relmsec(ts) == 0) return thrd_timedout; @@ -320,9 +313,6 @@ mtx_timedlock(mtx_t *mtx, const struct timespec *ts) thrd_yield(); } return thrd_success; -#else - return thrd_error; -#endif } // 7.25.4.5 @@ -502,20 +492,3 @@ tss_set(tss_t key, void *val) { return TlsSetValue(key, val) ? thrd_success : thrd_error; } - - -/*-------------------- 7.25.7 Time functions --------------------*/ -// 7.25.6.1 -#ifndef HAVE_TIMESPEC_GET -static inline int -timespec_get(struct timespec *ts, int base) -{ - assert(ts != NULL); - if (base == TIME_UTC) { - ts->tv_sec = time(NULL); - ts->tv_nsec = 0; - return base; - } - return 0; -} -#endif diff --git a/meson.build b/meson.build index d76cbe1123617..c1f3e06941adb 100644 --- a/meson.build +++ b/meson.build @@ -1453,6 +1453,10 @@ foreach f, prefix: functions_to_detect endif endforeach +if cc.has_header_symbol('time.h', 'struct timespec') + pre_args += '-DHAVE_STRUCT_TIMESPEC' +endif + if cc.has_header_symbol('errno.h', 'program_invocation_name', args : '-D_GNU_SOURCE') pre_args += '-DHAVE_PROGRAM_INVOCATION_NAME' diff --git a/src/c11/impl/meson.build b/src/c11/impl/meson.build new file mode 100644 index 0000000000000..ab8f17e33d02c --- /dev/null +++ b/src/c11/impl/meson.build @@ -0,0 +1,38 @@ +# Copyright © 2022 Yonggang Luo + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +files_mesa_util_c11 = files( + 'time.c', +) + +_libmesa_util_c11 = static_library( + 'mesa_util_c11', + [files_mesa_util_c11], + include_directories : [inc_include, inc_src], + c_args : [c_msvc_compat_args], + gnu_symbol_visibility : 'hidden', + build_by_default : false +) + +idep_mesautilc11 = declare_dependency( + link_with : _libmesa_util_c11, + include_directories : [inc_include, inc_src], + dependencies : [dep_clock, dep_thread, dep_atomic, dep_m, dep_valgrind], +) diff --git a/src/c11/impl/time.c b/src/c11/impl/time.c new file mode 100644 index 0000000000000..7c9cf6eead836 --- /dev/null +++ b/src/c11/impl/time.c @@ -0,0 +1,43 @@ +/* + * Copyright 2022 Yonggang Luo + * SPDX-License-Identifier: MIT + * + * C11 implementation + */ + +#include "c11/time.h" + +#ifndef HAVE_TIMESPEC_GET + +#if defined(_WIN32) && !defined(__CYGWIN__) + +#include + +int +timespec_get(struct timespec *ts, int base) +{ + assert(ts != NULL); + if (base == TIME_UTC) { + ts->tv_sec = time(NULL); + ts->tv_nsec = 0; + return base; + } + return 0; +} + +#else + +int +timespec_get(struct timespec *ts, int base) +{ + if (!ts) + return 0; + if (base == TIME_UTC) { + clock_gettime(CLOCK_REALTIME, ts); + return base; + } + return 0; +} +#endif + +#endif /* !HAVE_TIMESPEC_GET */ diff --git a/src/c11/time.h b/src/c11/time.h new file mode 100644 index 0000000000000..53d587c3eb6fb --- /dev/null +++ b/src/c11/time.h @@ -0,0 +1,51 @@ +/* + * Copyright 2022 Yonggang Luo + * SPDX-License-Identifier: MIT + * + * C11 emulation library + */ + +#ifndef C11_TIME_H_INCLUDED_ +#define C11_TIME_H_INCLUDED_ + +#include + +/*---------------------------- macros ---------------------------*/ + +#ifndef TIME_UTC +#define TIME_UTC 1 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*---------------------------- types ----------------------------*/ + +/* + * On MINGW `struct timespec` present but `timespec_get` may not present; + * On MSVC `struct timespec` and `timespec_get` present at the same time; + * So detecting `HAVE_STRUCT_TIMESPEC` in meson script dynamically. + */ +#ifndef HAVE_STRUCT_TIMESPEC +struct timespec +{ + time_t tv_sec; // Seconds - >= 0 + long tv_nsec; // Nanoseconds - [0, 999999999] +}; +#endif + +/*-------------------------- functions --------------------------*/ + +#ifndef HAVE_TIMESPEC_GET +/*-------------------- 7.25.7 Time functions --------------------*/ +// 7.25.6.1 +int +timespec_get(struct timespec *ts, int base); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* C11_TIME_H_INCLUDED_ */ diff --git a/src/mapi/es1api/meson.build b/src/mapi/es1api/meson.build index 4bca37b5e32f7..7910d32729d2b 100644 --- a/src/mapi/es1api/meson.build +++ b/src/mapi/es1api/meson.build @@ -56,7 +56,7 @@ libglesv1_cm = shared_library( link_args : [ld_args_gc_sections], include_directories : [inc_src, inc_include, inc_mapi], link_with : libglapi, - dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl], + dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl, idep_mesautilc11], soversion : host_machine.system() == 'windows' ? '' : '1', version : '1.1.0', darwin_versions : '3.0.0', diff --git a/src/mapi/es2api/meson.build b/src/mapi/es2api/meson.build index 8b133daa13127..65a4803ff1df5 100644 --- a/src/mapi/es2api/meson.build +++ b/src/mapi/es2api/meson.build @@ -56,7 +56,7 @@ libgles2 = shared_library( link_args : [ld_args_gc_sections], include_directories : [inc_src, inc_include, inc_mapi], link_with : libglapi, - dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl], + dependencies : [dep_thread, dep_libdrm, dep_m, dep_dl, idep_mesautilc11], soversion : host_machine.system() == 'windows' ? '' : '2', version : '2.0.0', darwin_versions : '3.0.0', diff --git a/src/mapi/glapi/meson.build b/src/mapi/glapi/meson.build index 9f06207fe0a24..d2523bc19fe06 100644 --- a/src/mapi/glapi/meson.build +++ b/src/mapi/glapi/meson.build @@ -81,7 +81,7 @@ libglapi_static = static_library( static_glapi_files, include_directories : [inc_mesa, inc_include, inc_src, inc_mapi], c_args : [c_msvc_compat_args, static_glapi_args], - dependencies : [dep_thread, dep_selinux], + dependencies : [dep_thread, dep_selinux, idep_mesautilc11], build_by_default : false, ) diff --git a/src/mapi/shared-glapi/meson.build b/src/mapi/shared-glapi/meson.build index 4a13bace6bccf..26166d7ddbc97 100644 --- a/src/mapi/shared-glapi/meson.build +++ b/src/mapi/shared-glapi/meson.build @@ -54,7 +54,7 @@ libglapi = shared_library( gnu_symbol_visibility : 'hidden', link_args : [ld_args_gc_sections], include_directories : [inc_src, inc_include, inc_mapi], - dependencies : [dep_thread, dep_selinux], + dependencies : [dep_thread, dep_selinux, idep_mesautilc11], soversion : host_machine.system() == 'windows' ? '' : '0', version : '0.0.0', name_prefix : 'lib', @@ -71,7 +71,7 @@ if with_any_opengl and with_tests cpp_args : [cpp_msvc_compat_args], include_directories : [inc_src, inc_include, inc_mapi], link_with : [libglapi], - dependencies : [dep_thread, idep_gtest], + dependencies : [dep_thread, idep_gtest, idep_mesautilc11], ), suite : ['mapi'], protocol : gtest_test_protocol, diff --git a/src/meson.build b/src/meson.build index 1d42e08df30bb..ebff41635be26 100644 --- a/src/meson.build +++ b/src/meson.build @@ -64,6 +64,7 @@ else idep_getopt = null_dep endif subdir('android_stub') +subdir('c11/impl') subdir('util') subdir('mapi') # TODO: opengl diff --git a/src/util/meson.build b/src/util/meson.build index 5b60a5d767577..e5283ff7f7919 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -206,6 +206,7 @@ deps_for_libmesa_util = [ dep_zstd, dep_dl, dep_unwind, + idep_mesautilc11 ] if with_platform_android