class FutexContext
Defined at line 73 of file ../../zircon/kernel/object/include/object/futex_context.h
FutexContex
A FutexContext is the object which manages the state of all of the active
futexes for a user-mode process. Each ProcessDispatcher in the system will
have a single FutexContext contained within it, and the objects should exist
no-where else in the system.
FutexContexts manage a pool of FutexContext::FutexStates which are
contributed by threads created within the process. This pool guarantees that
threads are guaranteed to be able to allocate a FutexState object in O(1)
time whenever they perform a FutexWait operation, as a Futex is only "active"
when it has any waiters. See (Grow|Shrink)FutexStatePool comments as well as
the FutexState's notes (below) for more details.
The remaining methods in the public interface implement the 3 primary futex
syscall operations (Wait, Wake, and Requeue) as well as the one
test/diagnostic operation (GetOwner). See the zircon syscall documentation
for further details.
Public Methods
void FutexContext ()
Defined at line 167 of file ../../zircon/kernel/object/futex_context.cc
void ~FutexContext ()
Defined at line 169 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t Init (ProcessType type)
Initialize this instance for use in the specified process type.
Must be called exactly once.
Defined at line 178 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t GrowFutexStatePool ()
Called as ThreadDispatchers are created and destroyed in order to ensure
that there are always two FutexStates for each ThreadDispatcher in a
process.
Why two and not one? Because of the FutexRequeue operation. Without
requeue, we would only need one, since a futex with waiters requires one
futex state, and there can be at most N futexes with waiters, where N is
the number of threads in a process.
During FutexRequeue, however, a thread needs to grab a hold of two futex
contexts at the same time. In addition, the thread performing this
operation is no longer holding a process wide futex context lock. Instead,
it simply locks in order to activate the FutexStates and then unlocks.
Another thread can attempt a requeue in parallel, or it could exit in
parallel. If only one FutexState were added for each thread, it would be
possible to run out of FutexStates if these operations were happening in
parallel.
Defined at line 206 of file ../../zircon/kernel/object/futex_context.cc
void ShrinkFutexStatePool ()
Defined at line 224 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t FutexWait (user_in_ptr<const zx_futex_t> value_ptr, zx_futex_t current_value, zx_handle_t new_futex_owner, const Deadline & deadline)
FutexWait first verifies that the integer pointed to by |value_ptr| still equals
|current_value|. If the test fails, FutexWait returns BAD_STATE. Otherwise it will block the
current thread until the |deadline| passes, or until the thread is woken by a FutexWake or
FutexRequeue operation on the same |value_ptr| futex.
Note that this method and FutexRequeue both take a user mode handle instead of having the
syscall dispatch layer resolve the handle into a thread before proceeding. This is because
we need to perform the current_value == *value_ptr check before attempting to validate the
thread handle, and this check needs to happen inside of the futex context lock. To do
otherwise leaves the potential to hit a race condition where we end up appearing to violate
the "bad handle" policy when actually we didn't. See https://fxbug.dev/42109683 for details.
May block on page requests and must be called without locks held.
Defined at line 270 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t FutexWake (user_in_ptr<const zx_futex_t> value_ptr, uint32_t wake_count, OwnerAction owner_action)
FutexWake will wake up to |wake_count| number of threads blocked on the |value_ptr| futex.
If owner_action is set to RELEASE, then the futex's owner will be set to nullptr in the
process. If the owner_action is set to ASSIGN_WOKEN, then the wake_count *must* be 1, and
the futex's owner will be set to the thread which was woken during the operation, or nullptr
if no thread was woken.
Defined at line 573 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t FutexRequeue (user_in_ptr<const zx_futex_t> wake_ptr, uint32_t wake_count, zx_futex_t current_value, OwnerAction owner_action, user_in_ptr<const zx_futex_t> requeue_ptr, uint32_t requeue_count, zx_handle_t new_requeue_owner_handle)
FutexRequeue first verifies that the integer pointed to by |wake_ptr| still equals
|current_value|. If the test fails, FutexRequeue returns BAD_STATE. Otherwise it will wake
up to |wake_count| number of threads blocked on the |wake_ptr| futex. If any other threads
remain blocked on on the |wake_ptr| futex, up to |requeue_count| of them will then be
requeued to the tail of the list of threads blocked on the |requeue_ptr| futex.
If owner_action is set to RELEASE, then the futex's owner will be set to nullptr in the
process. If the owner_action is set to ASSIGN_WOKEN, then the wake_count *must* be 1, and
the futex's owner will be set to the thread which was woken during the operation, or nullptr
if no thread was woken.
May block on page requests and must be called without locks held.
Defined at line 633 of file ../../zircon/kernel/object/futex_context.cc
zx_status_t FutexGetOwner (user_in_ptr<const zx_futex_t> value_ptr, user_out_ptr<zx_koid_t> koid)
Get the KOID of the current owner of the specified futex, if any, or ZX_KOID_INVALID if there
is no known owner.
Defined at line 783 of file ../../zircon/kernel/object/futex_context.cc
Enumerations
enum OwnerAction
| Name | Value |
|---|---|
| RELEASE | 0 |
| ASSIGN_WOKEN | 1 |
Owner action is an enum used to signal what to do when threads are woken
from a futex. The defined behaviors are as follows.
RELEASE
Remove any owner regardless of how many threads are woken (including zero
threads)
ASSIGN_WOKEN
Only permitted when wake_count is exactly 1. Assign ownership to the
thread who was woken if there was a thread to wake, and there are still
threads left in the futex after waking. Otherwise, set the futex queue
owner to nothing.
Defined at line 88 of file ../../zircon/kernel/object/include/object/futex_context.h
enum ProcessType
| Name | Value |
|---|---|
| Regular | 0 |
| Shared | 1 |
See |Init|.
Defined at line 94 of file ../../zircon/kernel/object/include/object/futex_context.h