futexのヘルプ・マニュアル
日本語 英語
futex --help
man futex
FUTEX(2) Linux Programmer’s Manual FUTEX(2)
名前
futex - 高速ユーザ空間ロック機構のシステムコール
書式
#include
#include
int futex(int *uaddr, int op, int val, const struct timespec *timeout,
int *uaddr2, int val3);
説明
futex() システムコールは、指定したアドレスの値が変更されるのをプログラ
ムが待つ手段や特定のアドレスに対して待機中のプロセスを wake (起床) させ
る 手段を提供する (プロセスが異なれば同じメモリに対するアドレスも同じで
はないかもしれないが、カーネルは異なる位置にマップされた同じメ モ リ を
futex() で使えるよう内部でマップする)。典型的には、futex は futex(7) に
記されているように、共有メモリ中のロックが競合する場合の処理を実装す る
のに用いられる。
futex(7) の操作がユーザ空間で競合なく完了しなかった場合、カーネルに仲裁
させるためにシステムコールを呼ぶ必要がある。仲裁というのは、呼び出し プ
ロ セスを sleep (起床待ち) させたり、反対に待ちプロセスを wake させたり
することを意味する。
この関数を呼び出すプロセスは futex(7) に記述されているセマンティクス に
忠 実であることが要求される。このセマンティクスには移植不可能なアセンブ
リ命令を書くことが含まれる。このことは言い換えると futex のユーザのほと
ん どは実際はライブラリの作者であり、一般アプリケーションの開発者ではな
いということである。
uaddr 引き数は、カウンタを格納する、アラインメントの揃った int 型変数を
指している必要がある。実行する操作は op 引き数を介して、値 val とともに
渡される。
現在のところ 5 つの操作が定義されている:
FUTEX_WAIT
この操作は futex アドレス uaddr に指定された値 val がまだ格納 さ
れているかどうかを不可分操作で検証し、 sleep 状態でこの futex ア
ドレスに対して FUTEX_WAKE が実行されるのを待つ。 timeout 引き 数
が NULL でない場合、その内容は待ち時間の最大値を表す。NULL の場
合は無限大を表す。引き数 uaddr2 と val3 は無視される。
futex(7) に照らし合わせると、この呼び出しはカウントのデクリメ ン
トで負の値 (競合を表す) になった場合に実行され、別のプロセスがそ
の futex を解放し FUTEX_WAKE の操作を実行するまで sleep する。
FUTEX_WAKE
この操作では指定した futex アドレスに対して待ち状態の (すなわ ち
FUTEX_WAIT 中 の) 最大 val 個のプロセスを wake させる。引き数
timeout, uaddr2, val3 は無視される。
futex(4) に照らし合わせると、この操作はカウントのインクリメン ト
で待ちプロセスがあると判明し、 futex 値が 1 に設定された (利用可
能であることを表す) 場合に実行される。
FUTEX_FD (Linux 2.6.25 以前)
非同期の wake に対応するため、この操作はファイルディスクリプタを
futex に関連づける。別のプロセスが FUTEX_WAKE を実行すると、プロ
セスは val で渡されたシグナル番号のシグナルを受信する。呼び出 し
プロセスは使用後、返されたファイルディスクリプタをクローズしなけ
ればならない。引き数 timeout, uaddr2, val3 は無視される。
競合状態を防止するため、呼び出しプロセスは FUTEX_FD が返ったあと
futex が up されたかどうかを確認しなければならない。
FUTEX_FD はもともと競合が起きやすかったため、 Linux 2.6.26 以降
で削除されている。
FUTEX_REQUEUE (Linux 2.5.70 以降)
この操作は、 FUTEX_WAKE が使われていて、かつ wake されている全て
の プロセスが他の futex を取得する必要がある場合に、「獣の群れの
暴走 (thundering herd)」効果を避けるために導入された。この呼び出
しは val 個のプロセスを wake し、アドレス uaddr2 で futex を待っ
ている他の全てのプロセスを再度キューにいれる。引き数 timeout と
val3 は無視される。
FUTEX_CMP_REQUEUE (Linux 2.6.7 以降)
故 意 に FUTEX_REQUEUE を 使 う 場 合 に 競 合 が起こるため、
FUTEX_CMP_REQUEUE が導入された。これは FUTEX_REQUEUE と似てい る
が 、場所 uaddr に値 val3 がまだ保持されているかを最初にチェック
する。保持されていない場合、操作はエラー EAGAIN で失敗する。引き
数 timeout は無視される。
返り値
どの操作が実行されたかによって、成功時の返り値の意味が変わる。
FUTEX_WAIT
プ ロセスが FUTEX_WAKE の呼び出しで wake すると 0 を返す。タイム
アウトの場合、操作はエラー ETIMEOUT で失敗する。 futex が指定 さ
れ た値と等しくない場合、エラー EWOULDBLOCK で失敗する。シグナル
を受信するか (signal(7) 参照) 他の偽の wake があった場合には、エ
ラー EINTR で失敗する。
FUTEX_WAKE
wake したプロセスの数を返す。
FUTEX_FD
futex に関連づけられた新たなファイルディスクリプタを返す。
FUTEX_REQUEUE
wake したプロセスの数を返す。
FUTEX_CMP_REQUEUE
wake したプロセスの数を返す。
エラーの場合、全ての操作で -1 が返り、 errno がエラーの内容を示す値に設
定される。
エラー
EACCES futex メモリに読み込みアクセス権がなかった。
EAGAIN FUTEX_CMP_REQUEUE で予期しない futex 値が見つかった (これは競 合
を 示 しているかもしれない。この場合は安全な FUTEX_WAKE を使うこ
と)。
EFAULT ユーザ空間から timeout の情報を取得する際にエラーが発生した。
EINVAL 操作が定義されていない。またはページ・アラインメントでエラーが発
生した。
ENFILE オープンされているファイルの総数がシステムの制限に達した。
ENOSYS op に無効な操作が指定された。
バージョン
最 初の futex 対応は Linux 2.5.7 で組み込まれたが、上記のセマンティクス
とは異なる。ここで示されているセマンティクスを持つ 4 つの引き数のシステ
ム コールは、Linux 2.5.40 で導入された。 Linux 2.5.70 では 1 つの引き数
が追加された。 Linux 2.6.7 では 6 番目の引き数が追加された。これは汚 く
、s390 アーキテクチャ上の特別のものである。
準拠
このシステムコールは Linux 独自である。
注意
繰り返すが、裸の futex はエンドユーザが容易に使うことのできる概念として
意図されたものではない (glibc にはこのシステムコールに対するラッパー 関
数 はない)。実装者は、アセンブリ言語に慣れており、以下に挙げる futex ユ
ーザ空間ライブラリのソースを読み終えていることが要求される。
関連項目
futex(7)
Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux (proceed-
ings of the Ottawa Linux Symposium 2002), futex の使用例ライブラリ,
futex-*.tar.bz2 .
Linux 2008-11-27 FUTEX(2)
FUTEX(2) Linux Programmer’s Manual FUTEX(2)
NAME
futex - Fast Userspace Locking system call
SYNOPSIS
#include
#include
int futex(int *uaddr, int op, int val, const struct timespec *timeout,
int *uaddr2, int val3);
DESCRIPTION
The futex() system call provides a method for a program to wait for a
value at a given address to change, and a method to wake up anyone
waiting on a particular address (while the addresses for the same mem-
ory in separate processes may not be equal, the kernel maps them inter-
nally so the same memory mapped in different locations will correspond
for futex() calls). It is typically used to implement the contended
case of a lock in shared memory, as described in futex(7).
When a futex(7) operation did not finish uncontended in userspace, a
call needs to be made to the kernel to arbitrate. Arbitration can
either mean putting the calling process to sleep or, conversely, waking
a waiting process.
Callers of this function are expected to adhere to the semantics as set
out in futex(7). As these semantics involve writing non-portable
assembly instructions, this in turn probably means that most users will
in fact be library authors and not general application developers.
The uaddr argument needs to point to an aligned integer which stores
the counter. The operation to execute is passed via the op argument,
along with a value val.
Five operations are currently defined:
FUTEX_WAIT
This operation atomically verifies that the futex address uaddr
still contains the value val, and sleeps awaiting FUTEX_WAKE on
this futex address. If the timeout argument is non-NULL, its
contents describe the maximum duration of the wait, which is
infinite otherwise. The arguments uaddr2 and val3 are ignored.
For futex(7), this call is executed if decrementing the count
gave a negative value (indicating contention), and will sleep
until another process releases the futex and executes the
FUTEX_WAKE operation.
FUTEX_WAKE
This operation wakes at most val processes waiting on this futex
address (i.e., inside FUTEX_WAIT). The arguments timeout,
uaddr2 and val3 are ignored.
For futex(7), this is executed if incrementing the count showed
that there were waiters, once the futex value has been set to 1
(indicating that it is available).
FUTEX_FD (present up to and including Linux 2.6.25)
To support asynchronous wakeups, this operation associates a
file descriptor with a futex. If another process executes a
FUTEX_WAKE, the process will receive the signal number that was
passed in val. The calling process must close the returned file
descriptor after use. The arguments timeout, uaddr2 and val3
are ignored.
To prevent race conditions, the caller should test if the futex
has been upped after FUTEX_FD returns.
Because it was inherently racy, FUTEX_FD has been removed from
Linux 2.6.26 onwards.
FUTEX_REQUEUE (since Linux 2.5.70)
This operation was introduced in order to avoid a "thundering
herd" effect when FUTEX_WAKE is used and all processes woken up
need to acquire another futex. This call wakes up val pro-
cesses, and requeues all other waiters on the futex at address
uaddr2. The arguments timeout and val3 are ignored.
FUTEX_CMP_REQUEUE (since Linux 2.6.7)
There was a race in the intended use of FUTEX_REQUEUE, so
FUTEX_CMP_REQUEUE was introduced. This is similar to
FUTEX_REQUEUE, but first checks whether the location uaddr still
contains the value val3. If not, the operation fails with the
error EAGAIN. The argument timeout is ignored.
RETURN VALUE
Depending on which operation was executed, the returned value for a
successful call can have differing meanings.
FUTEX_WAIT
Returns 0 if the process was woken by a FUTEX_WAKE call. In
case of timeout, the operation fails with the error ETIMEDOUT.
If the futex was not equal to the expected value, the operation
fails with the error EWOULDBLOCK. Signals (see signal(7)) or
other spurious wakeups cause FUTEX_WAIT to fail with the error
EINTR.
FUTEX_WAKE
Returns the number of processes woken up.
FUTEX_FD
Returns the new file descriptor associated with the futex.
FUTEX_REQUEUE
Returns the number of processes woken up.
FUTEX_CMP_REQUEUE
Returns the number of processes woken up.
In the event of an error, all operations return -1, and set errno to
indicate the error.
ERRORS
EACCES No read access to futex memory.
EAGAIN FUTEX_CMP_REQUEUE found an unexpected futex value. (This proba-
bly indicates a race; use the safe FUTEX_WAKE now.)
EFAULT Error in getting timeout information from userspace.
EINVAL An operation was not defined or error in page alignment.
ENFILE The system limit on the total number of open files has been
reached.
ENOSYS Invalid operation specified in op.
VERSIONS
Initial futex support was merged in Linux 2.5.7 but with different
semantics from what was described above. A 4-argument system call with
the semantics given here was introduced in Linux 2.5.40. In Linux
2.5.70 one argument was added. In Linux 2.6.7 a sixth argument was
added — messy, especially on the s390 architecture.
CONFORMING TO
This system call is Linux-specific.
NOTES
To reiterate, bare futexes are not intended as an easy-to-use abstrac-
tion for end-users. (There is no wrapper function for this system call
in glibc.) Implementors are expected to be assembly literate and to
have read the sources of the futex userspace library referenced below.
SEE ALSO
futex(7)
Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux (proceed-
ings of the Ottawa Linux Symposium 2002), futex example library,
futex-*.tar.bz2 .
COLOPHON
This page is part of release 3.22 of the Linux man-pages project. A
description of the project, and information about reporting bugs, can
be found at http://www.kernel.org/doc/man-pages/.
Linux 2008-11-27 FUTEX(2)