Manpages

名 前

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">http://kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf

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

こ の 文 書 に つ い て

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