mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 00:26:16 +03:00
fix: broken futex syscall when FUTEX_WAIT is used
This commit is contained in:
13
src/Makefile
13
src/Makefile
@@ -49,13 +49,24 @@
|
||||
#
|
||||
# INTERCEPT_SYSCALL
|
||||
# - (On GNU/Linux only) intercept glibc's syscall() for known relevant syscalls.
|
||||
# If enabled, this currently only works to divert the getrandom syscall.
|
||||
# If enabled, this currently only works a few types of syscalls,
|
||||
# including FUTEX (see below), clock_gettime, etc.
|
||||
#
|
||||
# - note that on unusual architectures, if INTERCEPT_SYSCALL is set, you may
|
||||
# need to explicitly define variadic_promotion_t (e.g. by putting
|
||||
# -Dvariadic_promotion_t=int into CFLAGS). See src/faketime_common.h for
|
||||
# more info.
|
||||
#
|
||||
# INTERCEPT_FUTEX
|
||||
# - (On GNU/Linux only) intercept glibc's syscall() for relevant FUTEX syscalls.
|
||||
# If enabled, FUTEX syscalls will be intercepted and translated correspondingly.
|
||||
# - when FUTEX_WAIT_BITSET (with absolute deadline) is set, the deadline will
|
||||
# be adjusted based on the faketime.
|
||||
# - when FUTEX_WAKE (with relative deadline) is set, the deadline will be
|
||||
# adjusted based on the time rate alone.
|
||||
# - for other FUTEX operations, no adjustment is made for now.
|
||||
#
|
||||
#
|
||||
# FAKE_STATELESS
|
||||
# - Remove support for any functionality that requires sharing state across
|
||||
# threads of a process, or different processes. This decreases the risk of
|
||||
|
||||
@@ -4445,12 +4445,13 @@ long handle_futex_syscall(long number, uint32_t* uaddr, int futex_op, uint32_t v
|
||||
goto futex_fallback;
|
||||
}
|
||||
|
||||
// if ((futex_op & FUTEX_CMD_MASK) == FUTEX_WAIT_BITSET) {
|
||||
if (1) {
|
||||
clockid_t clk_id = CLOCK_MONOTONIC;
|
||||
if (futex_op & FUTEX_CLOCK_REALTIME)
|
||||
clk_id = CLOCK_REALTIME;
|
||||
int futex_cmd = futex_op & FUTEX_CMD_MASK;
|
||||
clockid_t clk_id = CLOCK_MONOTONIC;
|
||||
if (futex_op & FUTEX_CLOCK_REALTIME)
|
||||
clk_id = CLOCK_REALTIME;
|
||||
|
||||
if (futex_cmd == FUTEX_WAIT_BITSET) {
|
||||
// FUTEX_WAIT_BITSET uses absolute timeout
|
||||
struct timespec real_tp, fake_tp;
|
||||
|
||||
DONT_FAKE_TIME((*real_clock_gettime)(clk_id, &real_tp));
|
||||
@@ -4513,8 +4514,20 @@ long handle_futex_syscall(long number, uint32_t* uaddr, int futex_op, uint32_t v
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (futex_cmd == FUTEX_WAIT) {
|
||||
// FUTEX_WAIT uses relative timeout - scale by time rate
|
||||
struct timespec adjusted_timeout;
|
||||
|
||||
if (user_rate_set && !dont_fake && ((clk_id == CLOCK_REALTIME) || (clk_id == CLOCK_MONOTONIC))) {
|
||||
timespecmul(timeout, 1.0 / user_rate, &adjusted_timeout);
|
||||
} else {
|
||||
adjusted_timeout = *timeout;
|
||||
}
|
||||
|
||||
return real_syscall(number, uaddr, futex_op, val, &adjusted_timeout, uaddr2, val3);
|
||||
} else {
|
||||
return real_syscall(number, uaddr, futex_op, val, timeout, uaddr2, val3);
|
||||
// Other futex operations - pass through unchanged
|
||||
goto futex_fallback;
|
||||
}
|
||||
|
||||
futex_fallback:
|
||||
|
||||
Reference in New Issue
Block a user