FUTEX
Section: Linux Programmer's Manual (2)
Updated: 2004-10-07
Index
JM Home Page
roff page
名前
futex - 高速ユーザ空間ロック機構のシステムコール
書式
#include <linux/futex.h>
#include <sys/time.h>
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
-
非同期の wake に対応するため、この操作はファイルディスクリプタを futex に
関連づける。
別のプロセスが
FUTEX_WAKE
を実行すると、プロセスは
val
で渡されたシグナル番号のシグナルを受信する。
呼び出しプロセスは使用後、返されたファイルディスクリプタを
クローズしなければならない。
引数
timeout,
uaddr2,
val3
は無視される。
競合状態を防止するため、呼び出しプロセスは
FUTEX_FD
が返ったあと
futex が up されたかどうかを確認しなければならない。
FUTEX_FD
はもともと競合が起きやすいため、
2007 年 6 月に削除される予定である。
これを使用しているアプリケーションは、すぐに修正すべきである。
- 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
で失敗する。
シグナルを受信すると (または他の偽の wake によって)
EINTR
を返す。
- FUTEX_WAKE
-
wake したプロセスの数を返す。
- FUTEX_FD
-
futex に関連づけられた新たなファイルディスクリプタを返す。
- FUTEX_REQUEUE
-
wake したプロセスの数を返す。
- FUTEX_CMP_REQUEUE
-
wake したプロセスの数を返す。
エラー
- EACCES
-
futex メモリに読み込みアクセス権がなかった。
- EAGAIN
-
FUTEX_CMP_REQUEUE
で予期しない futex 値が見つかった
(これは競合を示しているかもしれない。
この場合は安全な
FUTEX_WAKE
を使うこと)。
- EFAULT
-
ユーザ空間から
timeout
の情報を取得する際にエラーが発生した。
- EINVAL
-
操作が定義されていない。またはページ・アラインメントでエラーが発生した。
- ENFILE
-
オープンされているファイルの総数がシステムの制限に達した。
バージョン
最初の futex 対応は Linux 2.5.7 で組み込まれたが、
上記のセマンティクスとは異なる。
ここで示されているセマンティクスを持つ
4 つの引数のシステムコールは、Linux 2.5.40 で導入された。
Linux 2.5.70 では 1 つの引数が追加された。
Linux 2.6.7 では 6 番目の引数が追加された。
これは汚く、s390 アーキテクチャ上の特別のものである。
準拠
このシステムコールは Linux 独自である。
注意
繰り返すが、裸の futex はエンドユーザが容易に使うことのできる概念として
意図されたものではない。
実装者は、アセンブリ言語に慣れており、以下に挙げる futex ユーザ空間ライブラリの
ソースを読み終えていることが要求される。
関連項目
futex(7),
Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux
(proceedings of the Ottawa Linux Symposium 2002),
futex の使用例ライブラリ, futex-*.tar.bz2
<URL:ftp://ftp.nl.kernel.org/pub/linux/kernel/people/rusty/>.
Index
- 名前
-
- 書式
-
- 説明
-
- 返り値
-
- エラー
-
- バージョン
-
- 準拠
-
- 注意
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.
Time: 04:31:41 GMT, November 19, 2007