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?