util: Add a Win32 futex impl
authorJesse Natalie <jenatali@microsoft.com>
Fri, 8 Jul 2022 18:16:44 +0000 (11:16 -0700)
committerMarge Bot <emma+marge@anholt.net>
Fri, 15 Jul 2022 21:31:51 +0000 (21:31 +0000)
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 <jfonseca@vmware.com>
Reviewed-by: Yonggang Luo <luoyonggang@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17431>

meson.build
meson_options.txt
src/util/futex.h
src/util/meson.build

index 85bd12f..466e31d 100644 (file)
@@ -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
index 7a56221..b8f753e 100644 (file)
@@ -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.'
+)
index 221eda9..2a2a00c 100644 (file)
@@ -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 <windows.h>
+#include <stdint.h>
+#include <c11/time.h>
+#include <assert.h>
+#include <errno.h>
+
+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
index aa12c6e..b99d75b 100644 (file)
@@ -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 = []