blob: e4f4a6140ab13a2284c6e96f00d029a658b97e0f [file] [log] [blame] [view]
# zx_futex_requeue
## NAME
<!-- Updated by update-docs-from-fidl, do not edit. -->
Wake some number of threads waiting on a futex, and move more waiters to another wait queue.
## SYNOPSIS
<!-- Updated by update-docs-from-fidl, do not edit. -->
```c
#include <zircon/syscalls.h>
zx_status_t zx_futex_requeue(const zx_futex_t* value_ptr,
uint32_t wake_count,
zx_futex_t current_value,
const zx_futex_t* requeue_ptr,
uint32_t requeue_count,
zx_handle_t new_requeue_owner);
```
## DESCRIPTION
Requeuing is a generalization of waking. First, the kernel verifies
that the value in *current_value* matches the value of the futex at
*value_ptr*, and if not reports **ZX_ERR_BAD_STATE**. After waking *wake_count*
threads, *requeue_count* threads are moved from the original futex's
wait queue to the wait queue corresponding to *requeue_ptr*, another
futex.
This requeueing behavior may be used to avoid thundering herds on wake.
## OWNERSHIP
A requeue operation targets two futexes, the _wake futex_ and the _requeue
futex_. The ownership implications for each are discussed separately.
Generally, if the call fails for any reason, no changes to ownership for either
futex are made.
See *Ownership and Priority Inheritance* in [futex](/docs/reference/kernel_objects/futex.md) for
details.
### Effects on the _wake futex_ target
A successful call to `zx_futex_requeue()` results in the owner of the futex being
set to nothing, regardless of the wake count. In order to transfer ownership of
a futex, use the [`zx_futex_requeue_single_owner()`] variant instead.
[`zx_futex_requeue_single_owner()`] will attempt to wake exactly one thread from the
futex wait queue. If there is at least one thread to wake, the owner of the futex will be
set to the thread which was woken. Otherwise, the futex
will have no owner.
### Effects on the _requeue futex_ target
A successful call to `zx_futex_requeue()` or [`zx_futex_requeue_single_owner()`]
results in the owner of the futex being set to the thread referenced by the
*new_requeue_owner* handle, or to nothing if *new_requeue_owner* is
**ZX_HANDLE_INVALID**.
## RIGHTS
<!-- Updated by update-docs-from-fidl, do not edit. -->
None.
## RETURN VALUE
`zx_futex_requeue()` returns **ZX_OK** on success.
## ERRORS
**ZX_ERR_INVALID_ARGS** One of the following is true:
+ Either *value_ptr* or *requeue_ptr* is not a valid userspace pointer
+ Either *value_ptr* or *requeue_ptr* is not aligned to a `sizeof(zx_futex_t)` boundary.
+ *value_ptr* is the same futex as *requeue_ptr*
+ *new_requeue_owner* is currently a member of the waiters for either *value_ptr* or *requeue_ptr*
+ *new_requeue_owner* has not been started yet.
**ZX_ERR_BAD_HANDLE** *new_requeue_owner* is not **ZX_HANDLE_INVALID**, and not a valid handle AND
*current_value* matches the value at *value_ptr*
**ZX_ERR_WRONG_TYPE** *new_requeue_owner* is a valid handle, but is not a handle to a thread.
**ZX_ERR_BAD_STATE** *current_value* does not match the value at *value_ptr*.
## SEE ALSO
- [futex objects](/docs/reference/kernel_objects/futex.md)
- [`zx_futex_requeue_single_owner()`]
- [`zx_futex_wait()`]
- [`zx_futex_wake()`]
<!-- References updated by update-docs-from-fidl, do not edit. -->
[`zx_futex_requeue_single_owner()`]: futex_requeue_single_owner.md
[`zx_futex_wait()`]: futex_wait.md
[`zx_futex_wake()`]: futex_wake.md