this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix ulock semantics

+12 -12
+11 -7
src/kernel/emulation/linux/psynch/ulock_wait.c
··· 1 1 #include "ulock_wait.h" 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 + #include "../duct_errno.h" 4 5 #include <linux-syscalls/linux.h> 5 6 #include "../../../../../platform-include/sys/errno.h" 6 7 #include <stdbool.h> ··· 26 27 } 27 28 28 29 op = operation & UL_OPCODE_MASK; 29 - if (op == UL_COMPARE_AND_WAIT) 30 + if (op == UL_COMPARE_AND_WAIT || op == UL_UNFAIR_LOCK) 30 31 { 31 32 ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, 32 33 value, (timeout != 0) ? & ts : NULL); 33 - } 34 - else if (op == UL_UNFAIR_LOCK) 35 - { 36 - // FIXME: This is not correct. Linux sets addr to TID, while libplatform expects Mach thread port 37 - ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG, 38 - value, (timeout != 0) ? & ts : NULL); 34 + 35 + // unlike ulock_wait(), futex(FUTEX_WAIT) does not return how many 36 + // other threads are now (still) waiting for the lock. 37 + // 38 + // This hack makes userspace believe that there are other pending threads 39 + // and always take the slow path, which is the safe thing to do if 40 + // we are unsure. 41 + if (ret == 0 || ret == -LINUX_EAGAIN) 42 + ret = 1; 39 43 } 40 44 else 41 45 return no_errno ? -(EINVAL | 0x800) : -EINVAL;
+1 -5
src/kernel/emulation/linux/psynch/ulock_wake.c
··· 13 13 bool no_errno = operation & ULF_NO_ERRNO; 14 14 15 15 op = operation & UL_OPCODE_MASK; 16 - if (op == UL_COMPARE_AND_WAIT) 16 + if (op == UL_COMPARE_AND_WAIT || op == UL_UNFAIR_LOCK) 17 17 { 18 18 int value; 19 19 ··· 26 26 27 27 ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 28 28 value); 29 - } 30 - else if (op == UL_UNFAIR_LOCK) 31 - { 32 - ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG); 33 29 } 34 30 else 35 31 return no_errno ? -(EINVAL | 0x800) : -EINVAL;