← Documents Documentation/userspace-api/futex2.rst GitHub 원문 ↗

Linux 6.18.37 · Userspace API

futex2

futex_waitv waiter 배열, 검증 오류, timeout, private/shared futex와 지원 size를 설명합니다.

Source pathDocumentation/userspace-api/futex2.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

futex2.rst:1-86

futex_waitv waiter 배열, 검증 오류, timeout, private/shared futex와 지원 size를 설명합니다.

원문의 ABI symbol, error code, source path, 수치, code와 줄 좌표를 보존해 전문을 번역했습니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ======
4 futex2
5 ======
6
7 :Author: André Almeida <andrealmeid@collabora.com>
8
9 futex, or fast user mutex, is a set of syscalls to allow userspace to create
10 performant synchronization mechanisms, such as mutexes, semaphores and
11 conditional variables in userspace. C standard libraries, like glibc, uses it
12 as a means to implement more high level interfaces like pthreads.
13
14 futex2 is a followup version of the initial futex syscall, designed to overcome
15 limitations of the original interface.
16
17 User API
18 ========
19
20 ``futex_waitv()``
21 -----------------
22
23 Wait on an array of futexes, wake on any::
24
25 futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes,
26 unsigned int flags, struct timespec *timeout, clockid_t clockid)
27
28 struct futex_waitv {
29 __u64 val;
30 __u64 uaddr;
31 __u32 flags;
32 __u32 __reserved;
33 };
34
35 Userspace sets an array of struct futex_waitv (up to a max of 128 entries),
36 using ``uaddr`` for the address to wait for, ``val`` for the expected value
37 and ``flags`` to specify the type (e.g. private) and size of futex.
38 ``__reserved`` needs to be 0, but it can be used for future extension. The
39 pointer for the first item of the array is passed as ``waiters``. An invalid
40 address for ``waiters`` or for any ``uaddr`` returns ``-EFAULT``.
41
42 If userspace has 32-bit pointers, it should do a explicit cast to make sure
43 the upper bits are zeroed. ``uintptr_t`` does the tricky and it works for
44 both 32/64-bit pointers.
45
46 ``nr_futexes`` specifies the size of the array. Numbers out of [1, 128]
47 interval will make the syscall return ``-EINVAL``.
48
49 The ``flags`` argument of the syscall needs to be 0, but it can be used for
50 future extension.
51
52 For each entry in ``waiters`` array, the current value at ``uaddr`` is compared
53 to ``val``. If it's different, the syscall undo all the work done so far and
54 return ``-EAGAIN``. If all tests and verifications succeeds, syscall waits until
55 one of the following happens:
56
57 - The timeout expires, returning ``-ETIMEOUT``.
58 - A signal was sent to the sleeping task, returning ``-ERESTARTSYS``.
59 - Some futex at the list was woken, returning the index of some waked futex.
60
61 An example of how to use the interface can be found at ``tools/testing/selftests/futex/functional/futex_waitv.c``.
62
63 Timeout
64 -------
65
66 ``struct timespec *timeout`` argument is an optional argument that points to an
67 absolute timeout. You need to specify the type of clock being used at
68 ``clockid`` argument. ``CLOCK_MONOTONIC`` and ``CLOCK_REALTIME`` are supported.
69 This syscall accepts only 64bit timespec structs.
70
71 Types of futex
72 --------------
73
74 A futex can be either private or shared. Private is used for processes that
75 shares the same memory space and the virtual address of the futex will be the
76 same for all processes. This allows for optimizations in the kernel. To use
77 private futexes, it's necessary to specify ``FUTEX_PRIVATE_FLAG`` in the futex
78 flag. For processes that doesn't share the same memory space and therefore can
79 have different virtual addresses for the same futex (using, for instance, a
80 file-backed shared memory) requires different internal mechanisms to be get
81 properly enqueued. This is the default behavior, and it works with both private
82 and shared futexes.
83
84 Futexes can be of different sizes: 8, 16, 32 or 64 bits. Currently, the only
85 supported one is 32 bit sized futex, and it need to be specified using
86 ``FUTEX_32`` flag.
87

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

소개

1-16

Futex(fast user mutex)는 userspace에서 mutex, semaphore, condition variable 같은 고성능 synchronization mechanism을 만들게 하는 syscall 집합입니다. glibc 같은 C standard library는 이를 사용해 pthreads 같은 higher-level interface를 구현합니다.

futex2는 최초 futex syscall의 한계를 극복하도록 설계한 후속 interface입니다.

futex 역할
항목설명
Kernel primitivefutex syscall
Userspace mechanismsmutex, semaphore, condition variable
Library interfaceglibc pthreads
futex2기존 futex interface 한계 개선

Userspace synchronization과 library abstraction의 관계입니다.

.. SPDX-License-Identifier: GPL-2.0

======
futex2
======

:Author: André Almeida <andrealmeid@collabora.com>

futex, or fast user mutex, is a set of syscalls to allow userspace to create
performant synchronization mechanisms, such as mutexes, semaphores and
conditional variables in userspace. C standard libraries, like glibc, uses it
as a means to implement more high level interfaces like pthreads.

futex2 is a followup version of the initial futex syscall, designed to overcome
limitations of the original interface.

futex_waitv()와 waiter 배열

17-44

`futex_waitv()`는 futex array를 기다리다가 그중 하나가 wake되면 반환합니다. Signature는 `futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes, unsigned int flags, struct timespec *timeout, clockid_t clockid)`입니다.

각 `struct futex_waitv` entry에는 expected value `val`, 기다릴 address `uaddr`, futex type과 size를 지정하는 `flags`, future extension용 `__reserved`가 있습니다. `__reserved`는 현재 0이어야 합니다.

Userspace는 최대 128개 entry의 array를 설정하고 첫 항목 pointer를 `waiters`로 전달합니다. `waiters` 또는 어느 `uaddr`라도 invalid address이면 `-EFAULT`를 반환합니다.

32-bit pointer를 쓰는 userspace는 upper bit가 0이 되도록 explicit cast해야 합니다. `uintptr_t`는 32-bit와 64-bit pointer에서 모두 올바르게 처리합니다.

struct futex_waitv
항목설명
valExpected futex value
uaddr기다릴 futex address
flagsPrivate/shared type과 size
__reserved현재 0, future extension용

Waiter 하나의 field 의미입니다.

User API
========

``futex_waitv()``
-----------------

Wait on an array of futexes, wake on any::

  futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes,
              unsigned int flags, struct timespec *timeout, clockid_t clockid)

  struct futex_waitv {
        __u64 val;
        __u64 uaddr;
        __u32 flags;
        __u32 __reserved;
  };

Userspace sets an array of struct futex_waitv (up to a max of 128 entries),
using ``uaddr`` for the address to wait for, ``val`` for the expected value
and ``flags`` to specify the type (e.g. private) and size of futex.
``__reserved`` needs to be 0, but it can be used for future extension. The
pointer for the first item of the array is passed as ``waiters``. An invalid
address for ``waiters`` or for any ``uaddr`` returns ``-EFAULT``.

If userspace has 32-bit pointers, it should do a explicit cast to make sure
the upper bits are zeroed. ``uintptr_t`` does the tricky and it works for
both 32/64-bit pointers.

검증과 반환

45-62

`nr_futexes`는 array size이며 [1, 128] 범위를 벗어나면 syscall은 `-EINVAL`을 반환합니다. Syscall 자체의 `flags` argument는 현재 0이어야 하지만 future extension에 쓸 수 있습니다.

Kernel은 `waiters`의 각 entry에서 `uaddr`의 current value를 `val`과 비교합니다. 하나라도 다르면 지금까지 한 작업을 모두 되돌리고 `-EAGAIN`을 반환합니다.

모든 검사와 검증이 성공하면 timeout expiry에는 `-ETIMEOUT`, sleeping task에 signal이 오면 `-ERESTARTSYS`, list의 futex 하나가 wake되면 wake된 futex 중 하나의 index를 반환합니다.

사용 예제는 `tools/testing/selftests/futex/functional/futex_waitv.c`에 있습니다.

futex_waitv 처리
nr_futexes와 address 검증각 uaddr current value와 val 비교불일치 시 rollback 후 -EAGAIN모두 일치하면 sleepTimeout, signal 또는 futex wake로 반환

모든 waiter를 원자적으로 확인한 뒤 하나의 event를 기다립니다.

futex_waitv 오류와 결과
항목설명
Invalid address-EFAULT
nr_futexes outside 1..128-EINVAL
Current value mismatch-EAGAIN
Timeout-ETIMEOUT
Signal-ERESTARTSYS
Futex wakeWake된 futex 중 하나의 index

조건별 return value입니다.


``nr_futexes`` specifies the size of the array. Numbers out of [1, 128]
interval will make the syscall return ``-EINVAL``.

The ``flags`` argument of the syscall needs to be 0, but it can be used for
future extension.

For each entry in ``waiters`` array, the current value at ``uaddr`` is compared
to ``val``. If it's different, the syscall undo all the work done so far and
return ``-EAGAIN``. If all tests and verifications succeeds, syscall waits until
one of the following happens:

- The timeout expires, returning ``-ETIMEOUT``.
- A signal was sent to the sleeping task, returning ``-ERESTARTSYS``.
- Some futex at the list was woken, returning the index of some waked futex.

An example of how to use the interface can be found at ``tools/testing/selftests/futex/functional/futex_waitv.c``.

Timeout

63-70

`struct timespec *timeout`은 optional absolute timeout pointer입니다. `clockid`로 사용할 clock type을 지정하며 `CLOCK_MONOTONIC`과 `CLOCK_REALTIME`을 지원합니다.

이 syscall은 64-bit timespec struct만 받습니다.

Timeout 계약
항목설명
FormAbsolute timeout
ClockCLOCK_MONOTONIC 또는 CLOCK_REALTIME
Timespec64-bit only

시간 표현과 clock 선택입니다.

Timeout
-------

``struct timespec *timeout`` argument is an optional argument that points to an
absolute timeout. You need to specify the type of clock being used at
``clockid`` argument. ``CLOCK_MONOTONIC`` and ``CLOCK_REALTIME`` are supported.
This syscall accepts only 64bit timespec structs.

Private/shared 및 size

71-86

Futex는 private 또는 shared일 수 있습니다. Private futex는 같은 memory space를 공유하여 모든 process에서 futex virtual address가 같은 경우에 사용하며 kernel optimization이 가능합니다. Futex flag에 `FUTEX_PRIVATE_FLAG`를 지정해야 합니다.

Memory space를 공유하지 않아 같은 futex가 서로 다른 virtual address를 가질 수 있는 process, 예를 들어 file-backed shared memory를 쓰는 경우에는 올바른 enqueue를 위한 다른 internal mechanism이 필요합니다. 이것이 default behavior이며 private와 shared futex 모두에서 동작합니다.

Futex size는 8, 16, 32, 64 bit일 수 있지만 현재 지원하는 것은 32-bit futex뿐이며 `FUTEX_32` flag로 지정해야 합니다.

Futex type
항목설명
Private같은 memory space와 virtual address; FUTEX_PRIVATE_FLAG
Shared/default서로 다른 virtual address도 지원
Supported size현재 32 bit only; FUTEX_32

Address relation과 flag를 비교합니다.

Types of futex
--------------

A futex can be either private or shared. Private is used for processes that
shares the same memory space and the virtual address of the futex will be the
same for all processes. This allows for optimizations in the kernel. To use
private futexes, it's necessary to specify ``FUTEX_PRIVATE_FLAG`` in the futex
flag. For processes that doesn't share the same memory space and therefore can
have different virtual addresses for the same futex (using, for instance, a
file-backed shared memory) requires different internal mechanisms to be get
properly enqueued. This is the default behavior, and it works with both private
and shared futexes.

Futexes can be of different sizes: 8, 16, 32 or 64 bits. Currently, the only
supported one is 32 bit sized futex, and it need to be specified using
``FUTEX_32`` flag.