1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

Refactor PI mutexes internal definitions

This patch adds the generic futex_lock_pi and futex_unlock_pi to wrap
around the syscall machinery required to issue the syscall calls. It
simplifies a bit the futex code required to implement PI mutexes.

No function changes, checked on x86_64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
This commit is contained in:
Adhemerval Zanella
2019-10-30 13:29:40 -03:00
parent fbb4a31437
commit 6b1472eb2e
7 changed files with 136 additions and 68 deletions

View File

@@ -381,4 +381,90 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private)
}
}
/* The operation checks the value of the futex, if the value is 0, then
it is atomically set to the caller's thread ID. If the futex value is
nonzero, it is atomically sets the FUTEX_WAITERS bit, which signals wrt
other futex owner that it cannot unlock the futex in user space by
atomically by setting its value to 0.
If more than one wait operations is issued, the enqueueing of the waiters
are done in descending priority order.
The ABSTIME arguments provides an absolute timeout (measured against the
CLOCK_REALTIME clock). If TIMEOUT is NULL, the operation will block
indefinitely.
Returns:
- 0 if woken by a PI unlock operation or spuriously.
- EAGAIN if the futex owner thread ID is about to exit, but has not yet
handled the state cleanup.
- EDEADLK if the futex is already locked by the caller.
- ESRCH if the thread ID int he futex does not exist.
- EINVAL is the state is corrupted or if there is a waiter on the
futex.
- ETIMEDOUT if the ABSTIME expires.
*/
static __always_inline int
futex_lock_pi (unsigned int *futex_word, const struct timespec *abstime,
int private)
{
int err = lll_futex_timed_lock_pi (futex_word, abstime, private);
switch (err)
{
case 0:
case -EAGAIN:
case -EINTR:
case -ETIMEDOUT:
case -ESRCH:
case -EDEADLK:
case -EINVAL: /* This indicates either state corruption or that the kernel
found a waiter on futex address which is waiting via
FUTEX_WAIT or FUTEX_WAIT_BITSET. This is reported on
some futex_lock_pi usage (pthread_mutex_timedlock for
instance). */
return -err;
case -EFAULT: /* Must have been caused by a glibc or application bug. */
case -ENOSYS: /* Must have been caused by a glibc bug. */
/* No other errors are documented at this time. */
default:
futex_fatal_error ();
}
}
/* Wakes the top priority waiter that called a futex_lock_pi operation on
the futex.
Returns the same values as futex_lock_pi under those same conditions;
additionally, returns EPERM when the caller is not allowed to attach
itself to the futex. */
static __always_inline int
futex_unlock_pi (unsigned int *futex_word, int private)
{
int err = lll_futex_timed_unlock_pi (futex_word, private);
switch (err)
{
case 0:
case -EAGAIN:
case -EINTR:
case -ETIMEDOUT:
case -ESRCH:
case -EDEADLK:
case -ENOSYS:
case -EPERM: /* The caller is not allowed to attach itself to the futex.
Used to check if PI futexes are supported by the
kernel. */
return -err;
case -EINVAL: /* Either due to wrong alignment or due to the timeout not
being normalized. Must have been caused by a glibc or
application bug. */
case -EFAULT: /* Must have been caused by a glibc or application bug. */
/* No other errors are documented at this time. */
default:
futex_fatal_error ();
}
}
#endif /* futex-internal.h */