From c002bbeb2f7a1bf2d5c020abdddcf25909c447b6 Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Fri, 8 Jul 2022 11:16:44 -0700 Subject: [PATCH] util: Add a Win32 futex impl This uses APIs that are not available on Win7. Since this is a build-time configuration, and since we can't use the SDK version as an indicator (since you can support Win7 via new SDKs), a new option is added to allow disabling it, to maintain Win7 support if desired. Reviewed-by: Jose Fonseca Reviewed-by: Yonggang Luo Part-of: --- meson.build | 9 +++++++++ meson_options.txt | 10 +++++++++- src/util/futex.h | 38 ++++++++++++++++++++++++++++++++++++++ src/util/meson.build | 3 ++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 85bd12ff000..466e31de0c2 100644 --- a/meson.build +++ b/meson.build @@ -1617,6 +1617,15 @@ if with_platform_haiku dep_network = cc.find_library('network') endif +dep_futex = null_dep +if host_machine.system() == 'windows' + if (get_option('min-windows-version') < 8) + dep_futex = declare_dependency(compile_args : ['-DWINDOWS_NO_FUTEX']) + else + dep_futex = cc.find_library('synchronization', required : true) + endif +endif + # Check for libdrm. Various drivers have different libdrm version requirements, # but we always want to use the same version for all libdrm modules. That means # even if driver foo requires 2.4.0 and driver bar requires 2.4.3, if foo and diff --git a/meson_options.txt b/meson_options.txt index 7a5622101e9..b8f753e2e1a 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -547,4 +547,12 @@ option( type : 'string', value : '', description : 'Override build id for shader cache keys (hex string). Can be extracted with readelf -x .note.gnu.build-id' -) \ No newline at end of file +) +option( + 'min-windows-version', + type : 'integer', + min : 7, + max : 11, + value : 8, + description : 'Minimum Windows version to support. Defaults to Windows 8.' +) diff --git a/src/util/futex.h b/src/util/futex.h index 221eda9db0c..2a2a00c5759 100644 --- a/src/util/futex.h +++ b/src/util/futex.h @@ -117,6 +117,44 @@ static inline int futex_wait(uint32_t *addr, int32_t value, const struct timespe return futex(addr, FUTEX_WAIT, value, &tsrel, NULL); } +#elif defined(_WIN32) && !defined(WINDOWS_NO_FUTEX) +#define UTIL_FUTEX_SUPPORTED 1 + +#include +#include +#include +#include +#include + +static inline int futex_wake(uint32_t *addr, int count) +{ + /* All current callers fall into one of these buckets, and we'll get the semantics + * wrong if someone tries to be more clever. + */ + assert(count == 1 || count == INT_MAX); + if (count == 1) + WakeByAddressSingle(addr); + else + WakeByAddressAll(addr); + return count; +} + +static inline int futex_wait(uint32_t *addr, int32_t value, const struct timespec *timeout) +{ + DWORD timeout_ms = INFINITE; + if (timeout != NULL) { + struct timespec tsnow; + timespec_get(&tsnow, TIME_UTC); + + timeout_ms = (timeout->tv_sec - tsnow.tv_nsec) * 1000 + + (timeout->tv_nsec - tsnow.tv_nsec) / 1000000; + } + + if (WaitOnAddress(addr, &value, sizeof(value), timeout_ms)) + return 0; + return GetLastError() == ERROR_TIMEOUT ? ETIMEDOUT : -1; +} + #else #define UTIL_FUTEX_SUPPORTED 0 #endif diff --git a/src/util/meson.build b/src/util/meson.build index aa12c6e8e6a..b99d75bcfd8 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -209,6 +209,7 @@ deps_for_libmesa_util = [ dep_zstd, dep_dl, dep_unwind, + dep_futex, idep_mesautilc11 ] @@ -275,7 +276,7 @@ _libmesa_util = static_library( idep_mesautil = declare_dependency( link_with : _libmesa_util, include_directories : [inc_util, inc_gallium], - dependencies : [dep_zlib, dep_clock, dep_thread, dep_atomic, dep_m, dep_valgrind], + dependencies : [dep_zlib, dep_clock, dep_thread, dep_atomic, dep_m, dep_valgrind, dep_futex], ) xmlconfig_deps = []