···11#include "ulock_wait.h"
22#include "../base.h"
33#include "../errno.h"
44+#include "../duct_errno.h"
45#include <linux-syscalls/linux.h>
56#include "../../../../../platform-include/sys/errno.h"
67#include <stdbool.h>
···2627 }
27282829 op = operation & UL_OPCODE_MASK;
2929- if (op == UL_COMPARE_AND_WAIT)
3030+ if (op == UL_COMPARE_AND_WAIT || op == UL_UNFAIR_LOCK)
3031 {
3132 ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_WAIT | FUTEX_PRIVATE_FLAG,
3233 value, (timeout != 0) ? & ts : NULL);
3333- }
3434- else if (op == UL_UNFAIR_LOCK)
3535- {
3636- // FIXME: This is not correct. Linux sets addr to TID, while libplatform expects Mach thread port
3737- ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG,
3838- value, (timeout != 0) ? & ts : NULL);
3434+3535+ // unlike ulock_wait(), futex(FUTEX_WAIT) does not return how many
3636+ // other threads are now (still) waiting for the lock.
3737+ //
3838+ // This hack makes userspace believe that there are other pending threads
3939+ // and always take the slow path, which is the safe thing to do if
4040+ // we are unsure.
4141+ if (ret == 0 || ret == -LINUX_EAGAIN)
4242+ ret = 1;
3943 }
4044 else
4145 return no_errno ? -(EINVAL | 0x800) : -EINVAL;
+1-5
src/kernel/emulation/linux/psynch/ulock_wake.c
···1313 bool no_errno = operation & ULF_NO_ERRNO;
14141515 op = operation & UL_OPCODE_MASK;
1616- if (op == UL_COMPARE_AND_WAIT)
1616+ if (op == UL_COMPARE_AND_WAIT || op == UL_UNFAIR_LOCK)
1717 {
1818 int value;
1919···26262727 ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_WAKE | FUTEX_PRIVATE_FLAG,
2828 value);
2929- }
3030- else if (op == UL_UNFAIR_LOCK)
3131- {
3232- ret = LINUX_SYSCALL(__NR_futex, addr, FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG);
3329 }
3430 else
3531 return no_errno ? -(EINVAL | 0x800) : -EINVAL;