For whatever reason this patch does not work and tst-async.cc fails like below:
diff --git a/linux.cc b/linux.cc
index 522ed8ba..d91feb89 100644
--- a/linux.cc
+++ b/linux.cc
@@ -62,23 +62,37 @@ static mutex queues_mutex;
enum {
FUTEX_WAIT = 0,
FUTEX_WAKE = 1,
+ FUTEX_WAIT_BITSET = 9,
FUTEX_PRIVATE_FLAG = 128,
FUTEX_CLOCK_REALTIME = 256,
FUTEX_CMD_MASK = ~(FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME),
};
+#define FUTEX_BITSET_MATCH_ANY 0xffffffff
+
int futex(int *uaddr, int op, int val, const struct timespec *timeout,
- int *uaddr2, int val3)
+ int *uaddr2, uint32_t val3)
{
switch (op & FUTEX_CMD_MASK) {
+ case FUTEX_WAIT_BITSET:
+ if (val3 != FUTEX_BITSET_MATCH_ANY) {
+ abort("Unimplemented futex() operation %d\n", op);
+ }
+
case FUTEX_WAIT:
WITH_LOCK(queues_mutex) {
if (*uaddr == val) {
waitqueue &q = queues[uaddr];
if (timeout) {
sched::timer tmr(*sched::thread::current());
- tmr.set(std::chrono::seconds(timeout->tv_sec) +
- std::chrono::nanoseconds(timeout->tv_nsec));
+ if ((op & FUTEX_CMD_MASK) == FUTEX_WAIT_BITSET) {
+ osv::clock::wall::time_point abs_time(std::chrono::seconds(timeout->tv_sec) +
+ std::chrono::nanoseconds(timeout->tv_nsec));
+ tmr.set(abs_time);
+ } else {
+ tmr.set(std::chrono::seconds(timeout->tv_sec) +
std::chrono::nanoseconds(timeout->tv_nsec));
+ }
sched::thread::wait_for(queues_mutex, tmr, q);
// FIXME: testing if tmr was expired isn't quite right -
// we could have had both a wakeup and timer expiration
@@ -403,7 +417,7 @@ long syscall(long number, ...)
SYSCALL0(gettid);
SYSCALL2(clock_gettime, clockid_t, struct timespec *);
SYSCALL2(clock_getres, clockid_t, struct timespec *);
- SYSCALL6(futex, int *, int, int, const struct timespec *, int *, int);
+ SYSCALL6(futex, int *, int, int, const struct timespec *, int *, uint32_t);
SYSCALL1(close, int);
SYSCALL2(pipe2, int *, int);
SYSCALL1(epoll_create1, int);
./scripts/run.py -e '/tests/tst-async.so'
OSv v0.55.0-285-g660345d5
eth0: 192.168.122.15
Booted up in 259.57 ms
Cmdline: /tests/tst-async.so
Running 18 test cases...
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_one_shot_task_fires_soon": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_async_task_fires": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_async_task_can_be_reprogrammed_while_armed": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_async_task_can_be_reprogrammed_after_cancelled": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_desctructor_does_not_block_when_called_after_task_is_done": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_destructor_waits_for_callback_to_finish": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_async_task_can_be_reprogrammed_after_done": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_async_task_can_be_reprogrammed_from_the_callback": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_destructor_waits_for_callbacks_which_have_rescheduled_themselves": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_a_task_which_is_set_far_in_future_does_not_block_new_task": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_task_which_is_scheduled_second_but_with_sooner_expiration_time_fires_first": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_timers_with_same_expiration_time_fire_separately": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
/git-repos/osv/tests/tst-async.cc(24): fatal error: in "test_serial_timer__cancel_sync_waits_for_callback": critical check promise.get_future().wait_for(duration) == std::future_status::ready has failed
Assertion failed: _n_scheduled == 0 (core/async.cc: ~serial_timer_task: 386)
[backtrace]
0x00000000402382a8 <__assert_fail+24>
0x000000004042736c <async::serial_timer_task::~serial_timer_task()+44>
0x000010000000c6f8 <???+50936>
0x0000100000019b26 <???+105254>
0x00000000408a278f <vtable for std::basic_streambuf<char, std::char_traits<char> >+15>
What is interesting if I set relative timer for FUTEX_WAIT_BITSET instead of the absolute one as the spec demands, the test passes.
What am I doing wrong?
Waldek