Cleanup: remove trailing whitespaces at EOL
[urcu.git] / urcu / futex.h
index 98acc12855515e7ca0c5bf9ca42fd3fb988e0f30..4d16cfa5201453954dc7e6233372ea6969d23c26 100644 (file)
@@ -6,6 +6,8 @@
  *
  * Userspace RCU - sys_futex/compat_futex header.
  *
+ * Copyright 2011-2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
@@ -26,7 +28,7 @@
 
 #ifdef __cplusplus
 extern "C" {
-#endif 
+#endif
 
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
@@ -40,27 +42,74 @@ extern "C" {
  *
  * futex_async is signal-handler safe for the wakeup. It uses polling
  * on the wait-side in compatibility mode.
+ *
+ * BEWARE: sys_futex() FUTEX_WAIT may return early if interrupted
+ * (returns EINTR).
  */
 
-#ifdef CONFIG_RCU_HAVE_FUTEX
-#include <sys/syscall.h>
-#define futex(...)     syscall(__NR_futex, __VA_ARGS__)
-#define futex_noasync(uaddr, op, val, timeout, uaddr2, val3)   \
-               futex(uaddr, op, val, timeout, uaddr2, val3)
-#define futex_async(uaddr, op, val, timeout, uaddr2, val3)     \
-               futex(uaddr, op, val, timeout, uaddr2, val3)
-#else
 extern int compat_futex_noasync(int32_t *uaddr, int op, int32_t val,
-       const struct timespec *timeout, int32_t *uaddr2, int32_t val3);
-#define futex_noasync(uaddr, op, val, timeout, uaddr2, val3)   \
-               compat_futex_noasync(uaddr, op, val, timeout, uaddr2, val3)
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3);
 extern int compat_futex_async(int32_t *uaddr, int op, int32_t val,
-       const struct timespec *timeout, int32_t *uaddr2, int32_t val3);
-#define futex_async(uaddr, op, val, timeout, uaddr2, val3)     \
-               compat_futex_async(uaddr, op, val, timeout, uaddr2, val3)
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3);
+
+#ifdef CONFIG_RCU_HAVE_FUTEX
+
+#include <unistd.h>
+#include <errno.h>
+#include <urcu/compiler.h>
+#include <urcu/arch.h>
+
+static inline int futex(int32_t *uaddr, int op, int32_t val,
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+       return syscall(__NR_futex, uaddr, op, val, timeout,
+                       uaddr2, val3);
+}
+
+static inline int futex_noasync(int32_t *uaddr, int op, int32_t val,
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+       int ret;
+
+       ret = futex(uaddr, op, val, timeout, uaddr2, val3);
+       if (caa_unlikely(ret < 0 && errno == ENOSYS)) {
+               return compat_futex_noasync(uaddr, op, val, timeout,
+                               uaddr2, val3);
+       }
+       return ret;
+
+}
+
+static inline int futex_async(int32_t *uaddr, int op, int32_t val,
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+       int ret;
+
+       ret = futex(uaddr, op, val, timeout, uaddr2, val3);
+       if (caa_unlikely(ret < 0 && errno == ENOSYS)) {
+               return compat_futex_async(uaddr, op, val, timeout,
+                               uaddr2, val3);
+       }
+       return ret;
+}
+
+#else
+
+static inline int futex_noasync(int32_t *uaddr, int op, int32_t val,
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+       return compat_futex_noasync(uaddr, op, val, timeout, uaddr2, val3);
+}
+
+static inline int futex_async(int32_t *uaddr, int op, int32_t val,
+               const struct timespec *timeout, int32_t *uaddr2, int32_t val3)
+{
+       return compat_futex_async(uaddr, op, val, timeout, uaddr2, val3);
+}
+
 #endif
 
-#ifdef __cplusplus 
+#ifdef __cplusplus
 }
 #endif
 
This page took 0.0235 seconds and 4 git commands to generate.