zxfutex_requeue

总结

唤醒一些等待 futex 的线程,并将更多 Waiter 移至另一个等待队列。

声明

#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);

说明

重新加入队列是对唤醒的泛化。首先,内核会验证 current_value 中的值是否与 value_ptr 处的 futex 值匹配,如果不是,则报告 ZX_ERR_BAD_STATE。唤醒 wake_count 线程后,requeue_count 线程会从原始 futex 的等待队列移至与另一个 futex requeue_ptr 对应的等待队列。

这种重新排队行为可用于避免醒来时有雷象群。

所有权

重新排队操作针对两个 futex,即唤醒 futexrequeue futex。下文将分别讨论每个功能对所有权的影响。通常,如果调用因任何原因失败,系统不会针对任一 futex 更改所有权。

如需了解详情,请参阅 futex 中的所有权和优先级继承

wake futex 目标的影响

成功调用 zx_futex_requeue() 会导致 futex 的所有者被设为无任何值,无论唤醒计数是多少。如需转移 futex 的所有权,请改用 zx_futex_requeue_single_owner() 变体。zx_futex_requeue_single_owner() 会尝试从 futex 等待队列中仅唤醒一个线程。如果至少有一个线程要唤醒,futex 的所有者将被设置为已唤醒的线程。否则,Futex 将没有所有者。

requeue futex 目标的影响

如果成功调用 zx_futex_requeue()zx_futex_requeue_single_owner(),会导致 futex 的所有者被设置为 new_requeue_owner 句柄引用的线程;如果 new_requeue_ownerZX_HANDLE_INVALID,则不设置为任何值。

权限

无。

返回值

zx_futex_requeue() 会在成功时返回 ZX_OK

错误

ZX_ERR_INVALID_ARGS 以下情况之一为 true:

  • value_ptrrequeue_ptr 不是有效的用户空间指针
  • value_ptrrequeue_ptr 未与 sizeof(zx_futex_t) 边界对齐。
  • value_ptrrequeue_ptr 是相同的 futex
  • new_requeue_owner 当前是 value_ptrrequeue_ptr 的 Waiter 成员
  • new_requeue_owner 尚未启动。

ZX_ERR_BAD_HANDLE new_requeue_owner 不是 ZX_HANDLE_INVALID,不是有效的句柄,并且 current_valuevalue_ptr 中的值匹配

ZX_ERR_WRONG_TYPE new_requeue_owner 是有效的句柄,但不是线程的句柄。

ZX_ERR_BAD_STATE current_valuevalue_ptr 中的值不匹配。

另请参阅