aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/nptl/futex-internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/nptl/futex-internal.h')
-rw-r--r--sysdeps/nptl/futex-internal.h203
1 files changed, 0 insertions, 203 deletions
diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
deleted file mode 100644
index be7a33f460..0000000000
--- a/sysdeps/nptl/futex-internal.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/* futex operations for glibc-internal use. Stub version; do not include
- this file directly.
- Copyright (C) 2014-2017 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef STUB_FUTEX_INTERNAL_H
-#define STUB_FUTEX_INTERNAL_H
-
-#include <sys/time.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <libc-diag.h>
-
-/* This file defines futex operations used internally in glibc. A futex
- consists of the so-called futex word in userspace, which is of type
- unsigned int and represents an application-specific condition, and kernel
- state associated with this particular futex word (e.g., wait queues). The
- futex operations we provide are wrappers for the futex syscalls and add
- glibc-specific error checking of the syscall return value. We abort on
- error codes that are caused by bugs in glibc or in the calling application,
- or when an error code is not known. We return error codes that can arise
- in correct executions to the caller. Each operation calls out exactly the
- return values that callers need to handle.
-
- The private flag must be either FUTEX_PRIVATE or FUTEX_SHARED.
- FUTEX_PRIVATE is always supported, and the implementation can internally
- use FUTEX_SHARED when FUTEX_PRIVATE is requested. FUTEX_SHARED is not
- necessarily supported (use futex_supports_pshared to detect this).
-
- We expect callers to only use these operations if futexes and the
- specific futex operations being used are supported (e.g., FUTEX_SHARED).
-
- Given that waking other threads waiting on a futex involves concurrent
- accesses to the futex word, you must use atomic operations to access the
- futex word.
-
- Both absolute and relative timeouts can be used. An absolute timeout
- expires when the given specific point in time on the CLOCK_REALTIME clock
- passes, or when it already has passed. A relative timeout expires when
- the given duration of time on the CLOCK_MONOTONIC clock passes. Relative
- timeouts may be imprecise (see futex_supports_exact_relative_timeouts).
-
- Due to POSIX requirements on when synchronization data structures such
- as mutexes or semaphores can be destroyed and due to the futex design
- having separate fast/slow paths for wake-ups, we need to consider that
- futex_wake calls might effectively target a data structure that has been
- destroyed and reused for another object, or unmapped; thus, some
- errors or spurious wake-ups can happen in correct executions that would
- not be possible in a program using just a single futex whose lifetime
- does not end before the program terminates. For background, see:
- https://sourceware.org/ml/libc-alpha/2014-04/msg00075.html
- https://lkml.org/lkml/2014/11/27/472 */
-
-/* Defined this way for interoperability with lowlevellock.
- FUTEX_PRIVATE must be zero because the initializers for pthread_mutex_t,
- pthread_rwlock_t, and pthread_cond_t initialize the respective field of
- those structures to zero, and we want FUTEX_PRIVATE to be the default. */
-#define FUTEX_PRIVATE LLL_PRIVATE
-#define FUTEX_SHARED LLL_SHARED
-#if FUTEX_PRIVATE != 0
-# error FUTEX_PRIVATE must be equal to 0
-#endif
-
-/* Returns EINVAL if PSHARED is neither PTHREAD_PROCESS_PRIVATE nor
- PTHREAD_PROCESS_SHARED; otherwise, returns 0 if PSHARED is supported, and
- ENOTSUP if not. */
-static __always_inline int
-futex_supports_pshared (int pshared);
-
-/* Returns true if relative timeouts are robust to concurrent changes to the
- system clock. If this returns false, relative timeouts can still be used
- but might be effectively longer or shorter than requested. */
-static __always_inline bool
-futex_supports_exact_relative_timeouts (void);
-
-/* Atomically wrt other futex operations on the same futex, this blocks iff
- the value *FUTEX_WORD matches the expected value. This is
- semantically equivalent to:
- l = <get lock associated with futex> (FUTEX_WORD);
- wait_flag = <get wait_flag associated with futex> (FUTEX_WORD);
- lock (l);
- val = atomic_load_relaxed (FUTEX_WORD);
- if (val != expected) { unlock (l); return EAGAIN; }
- atomic_store_relaxed (wait_flag, true);
- unlock (l);
- // Now block; can time out in futex_time_wait (see below)
- while (atomic_load_relaxed(wait_flag) && !<spurious wake-up>);
-
- Note that no guarantee of a happens-before relation between a woken
- futex_wait and a futex_wake is documented; however, this does not matter
- in practice because we have to consider spurious wake-ups (see below),
- and thus would not be able to reliably reason about which futex_wake woke
- us.
-
- Returns 0 if woken by a futex operation or spuriously. (Note that due to
- the POSIX requirements mentioned above, we need to conservatively assume
- that unrelated futex_wake operations could wake this futex; it is easiest
- to just be prepared for spurious wake-ups.)
- Returns EAGAIN if the futex word did not match the expected value.
- Returns EINTR if waiting was interrupted by a signal.
-
- Note that some previous code in glibc assumed the underlying futex
- operation (e.g., syscall) to start with or include the equivalent of a
- seq_cst fence; this allows one to avoid an explicit seq_cst fence before
- a futex_wait call when synchronizing similar to Dekker synchronization.
- However, we make no such guarantee here. */
-static __always_inline int
-futex_wait (unsigned int *futex_word, unsigned int expected, int private);
-
-/* Like futex_wait but does not provide any indication why we stopped waiting.
- Thus, when this function returns, you have to always check FUTEX_WORD to
- determine whether you need to continue waiting, and you cannot detect
- whether the waiting was interrupted by a signal. Example use:
- while (atomic_load_relaxed (&futex_word) == 23)
- futex_wait_simple (&futex_word, 23, FUTEX_PRIVATE);
- This is common enough to make providing this wrapper worthwhile. */
-static __always_inline void
-futex_wait_simple (unsigned int *futex_word, unsigned int expected,
- int private)
-{
- ignore_value (futex_wait (futex_word, expected, private));
-}
-
-
-/* Like futex_wait but is a POSIX cancellation point. */
-static __always_inline int
-futex_wait_cancelable (unsigned int *futex_word, unsigned int expected,
- int private);
-
-/* Like futex_wait, but will eventually time out (i.e., stop being
- blocked) after the duration of time provided (i.e., RELTIME) has
- passed. The caller must provide a normalized RELTIME. RELTIME can also
- equal NULL, in which case this function behaves equivalent to futex_wait.
-
- Returns the same values as futex_wait under those same conditions;
- additionally, returns ETIMEDOUT if the timeout expired.
- */
-static __always_inline int
-futex_reltimed_wait (unsigned int* futex_word, unsigned int expected,
- const struct timespec* reltime, int private);
-
-/* Like futex_reltimed_wait but is a POSIX cancellation point. */
-static __always_inline int
-futex_reltimed_wait_cancelable (unsigned int* futex_word,
- unsigned int expected,
- const struct timespec* reltime, int private);
-
-/* Like futex_reltimed_wait, but the provided timeout (ABSTIME) is an
- absolute point in time; a call will time out after this point in time. */
-static __always_inline int
-futex_abstimed_wait (unsigned int* futex_word, unsigned int expected,
- const struct timespec* abstime, int private);
-
-/* Like futex_reltimed_wait but is a POSIX cancellation point. */
-static __always_inline int
-futex_abstimed_wait_cancelable (unsigned int* futex_word,
- unsigned int expected,
- const struct timespec* abstime, int private);
-
-/* Atomically wrt other futex operations on the same futex, this unblocks the
- specified number of processes, or all processes blocked on this futex if
- there are fewer than the specified number. Semantically, this is
- equivalent to:
- l = <get lock associated with futex> (FUTEX_WORD);
- lock (l);
- for (res = 0; PROCESSES_TO_WAKE > 0; PROCESSES_TO_WAKE--, res++) {
- if (<no process blocked on futex>) break;
- wf = <get wait_flag of a process blocked on futex> (FUTEX_WORD);
- // No happens-before guarantee with woken futex_wait (see above)
- atomic_store_relaxed (wf, 0);
- }
- return res;
-
- Note that we need to support futex_wake calls to past futexes whose memory
- has potentially been reused due to POSIX' requirements on synchronization
- object destruction (see above); therefore, we must not report or abort
- on most errors. */
-static __always_inline void
-futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
-
-/* Calls __libc_fatal with an error message. Convenience function for
- concrete implementations of the futex interface. */
-static __always_inline __attribute__ ((__noreturn__)) void
-futex_fatal_error (void)
-{
- __libc_fatal ("The futex facility returned an unexpected error code.");
-}
-
-#endif /* futex-internal.h */