aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2020-12-13 11:01:52 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2020-12-16 01:58:33 +0100
commit59bb023c8361c0e12e8eee1810897c5e3ea223b3 (patch)
tree1b0ac0698b6f01aa8c69d0960f9bc1f49ec62f03
parentbec412424e949c900b01767ce32b6743bdaaac93 (diff)
downloadglibc-59bb023c8361c0e12e8eee1810897c5e3ea223b3.tar
glibc-59bb023c8361c0e12e8eee1810897c5e3ea223b3.tar.gz
glibc-59bb023c8361c0e12e8eee1810897c5e3ea223b3.tar.bz2
glibc-59bb023c8361c0e12e8eee1810897c5e3ea223b3.zip
hurd: Add __lll_abstimed_wait_intr
For semaphores, we need an interruptible version of low-level locks.
-rw-r--r--hurd/Makefile1
-rw-r--r--hurd/RPC_gsync_wait_intr.c4
-rw-r--r--hurd/Versions2
-rw-r--r--hurd/hurdlock.c11
-rw-r--r--hurd/hurdlock.h16
-rw-r--r--mach/lowlevellock.h18
6 files changed, 51 insertions, 1 deletions
diff --git a/hurd/Makefile b/hurd/Makefile
index 861bbf7842..02b2456aa0 100644
--- a/hurd/Makefile
+++ b/hurd/Makefile
@@ -93,6 +93,7 @@ CFLAGS-RPC_exec_startup_get_info.o = $(no-stack-protector)
# Make generated headers compatible with all support standards
migheaderpipe := | sed -e 's/\<ino64_t\>/__ino64_t/' -e 's/\<loff_t\>/__loff_t/'
include ../mach/Machrules
+libhurduser-routines += RPC_gsync_wait_intr
include ../Rules
# intr-rpc.defs defines the INTR_INTERFACE macro to make the generated RPC
diff --git a/hurd/RPC_gsync_wait_intr.c b/hurd/RPC_gsync_wait_intr.c
new file mode 100644
index 0000000000..51b63217d6
--- /dev/null
+++ b/hurd/RPC_gsync_wait_intr.c
@@ -0,0 +1,4 @@
+#include "intr-rpc.h"
+#define gsync_wait gsync_wait_intr
+#define __gsync_wait __gsync_wait_intr
+#include "RPC_gsync_wait.c"
diff --git a/hurd/Versions b/hurd/Versions
index f37e359ac8..1aad27d91f 100644
--- a/hurd/Versions
+++ b/hurd/Versions
@@ -149,7 +149,7 @@ libc {
GLIBC_PRIVATE {
# Used by other libs.
- __lll_abstimed_wait; __lll_abstimed_xwait;
+ __lll_abstimed_wait; __lll_abstimed_wait_intr; __lll_abstimed_xwait;
__lll_abstimed_lock; __lll_robust_lock;
__lll_robust_abstimed_lock; __lll_robust_trylock;
__lll_robust_unlock;
diff --git a/hurd/hurdlock.c b/hurd/hurdlock.c
index 3b9974bee5..e2a5312036 100644
--- a/hurd/hurdlock.c
+++ b/hurd/hurdlock.c
@@ -55,6 +55,17 @@ __lll_abstimed_wait (void *ptr, int val,
}
int
+__lll_abstimed_wait_intr (void *ptr, int val,
+ const struct timespec *tsp, int flags, int clk)
+{
+ if (clk != CLOCK_REALTIME)
+ return EINVAL;
+
+ int mlsec = compute_reltime (tsp, clk);
+ return mlsec < 0 ? KERN_TIMEDOUT : __lll_timed_wait_intr (ptr, val, mlsec, flags);
+}
+
+int
__lll_abstimed_xwait (void *ptr, int lo, int hi,
const struct timespec *tsp, int flags, int clk)
{
diff --git a/hurd/hurdlock.h b/hurd/hurdlock.h
index c1df42bea4..0a7f6eaf90 100644
--- a/hurd/hurdlock.h
+++ b/hurd/hurdlock.h
@@ -40,6 +40,11 @@ struct timespec;
__gsync_wait (__mach_task_self (), \
(vm_offset_t)ptr, val, 0, mlsec, flags | GSYNC_TIMED)
+/* Interruptible version. */
+#define __lll_timed_wait_intr(ptr, val, mlsec, flags) \
+ __gsync_wait_intr (__mach_task_self (), \
+ (vm_offset_t)ptr, val, 0, mlsec, flags | GSYNC_TIMED)
+
/* Same as '__lll_xwait', but only block for MLSEC milliseconds. */
#define __lll_timed_xwait(ptr, lo, hi, mlsec, flags) \
__gsync_wait (__mach_task_self (), (vm_offset_t)ptr, \
@@ -50,6 +55,10 @@ struct timespec;
extern int __lll_abstimed_wait (void *__ptr, int __val,
const struct timespec *__tsp, int __flags, int __clk);
+/* Interruptible version. */
+extern int __lll_abstimed_wait_intr (void *__ptr, int __val,
+ const struct timespec *__tsp, int __flags, int __clk);
+
/* Same as 'lll_xwait', but only block until TSP elapses,
using clock CLK. */
extern int __lll_abstimed_xwait (void *__ptr, int __lo, int __hi,
@@ -106,6 +115,13 @@ extern void __lll_robust_unlock (void *__ptr, int __flags);
__clk[sizeof (__clk) / sizeof (__clk[0]) - 1]); \
})
+#define lll_abstimed_wait_intr(var, val, tsp, flags, ...) \
+ ({ \
+ const clockid_t __clk[] = { CLOCK_REALTIME, ##__VA_ARGS__ }; \
+ __lll_abstimed_wait_intr (&(var), (val), (tsp), (flags), \
+ __clk[sizeof (__clk) / sizeof (__clk[0]) - 1]); \
+ })
+
#define lll_abstimed_xwait(var, lo, hi, tsp, flags, ...) \
({ \
const clockid_t __clk[] = { CLOCK_REALTIME, ##__VA_ARGS__ }; \
diff --git a/mach/lowlevellock.h b/mach/lowlevellock.h
index 0a22a030b4..b872d0fe1e 100644
--- a/mach/lowlevellock.h
+++ b/mach/lowlevellock.h
@@ -34,6 +34,17 @@
/* Static initializer for low-level locks. */
#define LLL_LOCK_INITIALIZER 0
+/* Interruptible version of __gsync_wait. */
+extern kern_return_t __gsync_wait_intr
+(
+ mach_port_t task,
+ vm_offset_t addr,
+ unsigned val1,
+ unsigned val2,
+ natural_t msec,
+ int flags
+);
+
/* Wait on address PTR, without blocking if its contents
* are different from VAL. */
#define __lll_wait(ptr, val, flags) \
@@ -42,6 +53,13 @@
#define lll_wait(var, val, flags) \
__lll_wait (&(var), val, flags)
+/* Interruptible version. */
+#define __lll_wait_intr(ptr, val, flags) \
+ __gsync_wait_intr (__mach_task_self (), \
+ (vm_offset_t)(ptr), (val), 0, 0, (flags))
+#define lll_wait_intr(var, val, flags) \
+ __lll_wait_intr ((&var), val, flags)
+
/* Wake one or more threads waiting on address PTR. */
#define __lll_wake(ptr, flags) \
__gsync_wake (__mach_task_self (), (vm_offset_t)(ptr), 0, (flags))