pondering pi futexes
- Reply: Konstantin Belousov : "Re: pondering pi futexes"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Jun 2021 19:39:35 UTC
Hi,
some time ago I have changed Linuxulator futexes from sx lock to mtx.
sx was used as it allows copyin/copyout with sx lock held.
to use mtx I have changed the code like:
1. lock mtx;
2. disable_pagefaults;
3. copyin()
4. enable_pagefaults;
5. if error
- unlock mtx;
copyin();
if error == 0 goto 1.
it works (needto replace copyin() by fueword32()), but pondering pi futexes
imlementation, I see that it is not possible to drop the futex lock on a return
from msleep() path.
below a simplified FUTEX_LOCK_PI operation, where on enter to the kernel current thread:
0. acquire futex lock (which is mtx)
1. cmpset(0 -> current thread TID), return (0) on success;
2. fetch() from futex *uaddr (for TID of owner):
- check EDEADLK case (the futex word at *uaddr is already locked by the caller);
- check that is no waiters on *uaddr exists which is waiting via FUTEX_WAIT or
FUTEX_WAIT_BITSET, return (EINVAL) if so;
- cmpset(TID -> (FUTEX_WAITERS|TID));
- on error, the futex owner changed in user-space, repeat from 1.
3. Here we have: the owner, one waiter (current thread) and 0 or more waiters
sleeping on a waiting_proc. FUTEX_WAITERS bit is set, so any new waiters go to
the kernel and owner should unlock futex via the FUTEX_UNLOCK_PI op;
4. Try to find the thread which is associated with the owner’s TID:
- on error, something bad happened, owner died? Clean owner state link?
return (ESRCH). Or if no other waiters? Check this...
- on success:
- save owner state link to the struct futex (save priority);
- check the owner's priority, bump it if needed;
- put the current thread to the waiters list in descending priority order;
- change priority of all waiters if needed;
- msleep on a futex waiting_proc; come back with futex lock held;
- restore own priority? If last waiter?; [ponders..]
- on timeout return (ETIMEDOUT);
- the current thread is the new owner:
bah!! - store() the owner TID to *uaddr; [check what should I do on error..]
- release futex lock;
- return (0).
is it possible to hold *uaddr page to prevent page faults?