Mesa (main): util: Add a Win32 futex impl

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 15 21:59:18 UTC 2022


Module: Mesa
Branch: main
Commit: c002bbeb2f7a1bf2d5c020abdddcf25909c447b6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c002bbeb2f7a1bf2d5c020abdddcf25909c447b6

Author: Jesse Natalie <jenatali at microsoft.com>
Date:   Fri Jul  8 11:16:44 2022 -0700

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 <jfonseca at vmware.com>
Reviewed-by: Yonggang Luo <luoyonggang at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17431>

---

 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 <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
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 = []



More information about the mesa-commit mailing list