名 前
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 の 場 合 、 呼
び 出 し は 無 限
に 停 止 す る 。
引 き 数 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 は 無 視 さ れ
る 。
返 り 値
エ ラ ー の 場 合 、 全 て の 操 作 で −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 を 使 う こ と 。 )
ユ ー ザ
ー 空 間 か ら timeout
の 情 報 を 取 得
す る 際 に エ ラ
ー が 発 生 し た
。 FUTEX_WAIT 操 作 が シ グ ナ ル (signal(7) 参 照 ) も し く は 偽 の wakeup に よ り 中 断 さ れ た 。 EINVAL 無 効 な 引 き 数 。
op に 無 効 な 操 作 が 指 定 さ れ た 。 ETIMEDOUT FUTEX_WAIT 操 作 で タ イ ム ア ウ ト が 発 生 し た 。 EWOULDBLOCK op が FUTEX_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 ユ ー ザ ー 空 間 ラ イ ブ ラ リ の ソ ー ス を 読 み 終 え て い る こ と が 要 求 さ れ る 。 関 連 項 目Fuss,
Futexes and Furwocks: Fast Userlevel Locking in Linux
(proceedings of the Ottawa Linux Symposium 2002), online at
futex の
使 用 例 ラ イ ブ
ラ リ , futex−*.tar.bz2 こ の 文 書 に つ い てこ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。 |