Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all bug

名前

       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);
       : このシステムコールには glibc のラッパー関数は存在しない。「注意」の節を参照。

説明

       futex()   システムコールは、 指定したアドレスの値が変更されるのをプログラムが待つ手段や 特
       定のアドレスに対して待機中のプロセスを wake (起床) させる手段を提供する  (プロセスが異なれ
       ば同じメモリーに対するアドレスも同じではないかもしれないが、  カーネルは異なる位置にマップ
       された同じメモリーを 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 の場合、  呼び出しは無限に停止する。  引き数
              uaddr2val3 は無視される。

              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  を待っている他の全てのプロセスを再度キューにいれる。  引き数 timeoutval3
              は無視される。

       FUTEX_CMP_REQUEUE (Linux 2.6.7 以降)
              故意に FUTEX_REQUEUE  を使う場合に競合が起こるため、  FUTEX_CMP_REQUEUE  が導入され
              た。これは  FUTEX_REQUEUE と似ているが、場所 uaddr に値 val3 がまだ保持されているか
              を最初にチェックする。 保持されていない場合、操作はエラー EAGAIN で失敗する。引き数
              timeout は無視される。

返り値

       エラーの場合、全ての操作で  -1 が返り、 errno がエラーの内容を示す値に設定される。成功時の
       返り値は操作によって異なり、以下のリストに書かれている通りである。

       FUTEX_WAIT
              そのプロセスが FUTEX_WAKE により wake された場合  0  を返す。発生する可能性があるエ
              ラーについては「エラー」の節を参照。

       FUTEX_WAKE
              wake したプロセスの数を返す。

       FUTEX_FD
              futex に関連づけられた新たなファイルディスクリプターを返す。

       FUTEX_REQUEUE
              wake したプロセスの数を返す。

       FUTEX_CMP_REQUEUE
              wake したプロセスの数を返す。

エラー

       EACCES futex メモリーに読み込みアクセス権がなかった。

       EAGAIN FUTEX_CMP_REQUEUE  で、uaddr が指す値が期待値 val3 と異なる状況が検出された。 (これ
              は競合を示しているかもしれない。この場合は安全な FUTEX_WAKE を使うこと。)

       EFAULT ユーザー空間から timeout の情報を取得する際にエラーが発生した。

       EINTR  FUTEX_WAIT 操作がシグナル (signal(7) 参照) もしくは偽の wakeup により中断された。

       EINVAL 無効な引き数。

       ENFILE オープンされているファイルの総数がシステムの制限に達した。

       ENOSYS op に無効な操作が指定された。

       ETIMEDOUT
              FUTEX_WAIT 操作でタイムアウトが発生した。

       EWOULDBLOCK
              opFUTEX_WAIT で、その呼び出しにおいて uaddr が指す値が期待値  val  と異なってい
              た。

バージョン

       最初の 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 ユーザー空間ライブラリの ソースを読み終えていることが要求
       される。

関連項目

       restart_syscall(2), futex(7)

       Fuss,  Futexes  and  Furwocks:  Fast Userlevel Locking in Linux (proceedings of the Ottawa
       Linux Symposium 2002), online at
       ⟨http://kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf⟩

       futex の使用例ライブラリ, futex-*.tar.bz2
       ⟨ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部  である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。