From: Nathan Froyd Date: Mon, 3 Aug 2009 15:43:29 +0000 (-0700) Subject: linux-user: make FUTEX_* calls honor timeout parameter X-Git-Tag: TizenStudio_2.0_p2.3~8105 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=218e5cb6b28161b7ce93cca7c3f32ae6917f4011;p=sdk%2Femulator%2Fqemu.git linux-user: make FUTEX_* calls honor timeout parameter Signed-off-by: Nathan Froyd Signed-off-by: malc --- diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b5f669e..673eed4 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4026,14 +4026,16 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, target_ulong uaddr2, int val3) { struct timespec ts, *pts; + int base_op; /* ??? We assume FUTEX_* constants are the same on both host and target. */ #ifdef FUTEX_CMD_MASK - switch ((op&FUTEX_CMD_MASK)) { + base_op = op & FUTEX_CMD_MASK; #else - switch (op) { + base_op = op; #endif + switch (base_op) { case FUTEX_WAIT: if (timeout) { pts = &ts; @@ -4045,16 +4047,22 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, pts, NULL, 0)); case FUTEX_WAKE: return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0)); - case FUTEX_WAKE_OP: - return get_errno(sys_futex(g2h(uaddr), op, val, NULL, g2h(uaddr2), val3 )); case FUTEX_FD: return get_errno(sys_futex(g2h(uaddr), op, val, NULL, NULL, 0)); case FUTEX_REQUEUE: - return get_errno(sys_futex(g2h(uaddr), op, val, - NULL, g2h(uaddr2), 0)); case FUTEX_CMP_REQUEUE: - return get_errno(sys_futex(g2h(uaddr), op, val, - NULL, g2h(uaddr2), tswap32(val3))); + case FUTEX_WAKE_OP: + /* For FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, and FUTEX_WAKE_OP, the + TIMEOUT parameter is interpreted as a uint32_t by the kernel. + But the prototype takes a `struct timespec *'; insert casts + to satisfy the compiler. We do not need to tswap TIMEOUT + since it's not compared to guest memory. */ + pts = (struct timespec *)(uintptr_t) timeout; + return get_errno(sys_futex(g2h(uaddr), op, val, pts, + g2h(uaddr2), + (base_op == FUTEX_CMP_REQUEUE + ? tswap32(val3) + : val3))); default: return -TARGET_ENOSYS; }