1 .\" Copyright (C) 2008 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" This program is free software; you can redistribute it and/or modify
4 .\" it under the terms of the GNU General Public License as published by
5 .\" the Free Software Foundation; either version 2 of the License, or
6 .\" (at your option) any later version.
8 .\" This program is distributed in the hope that it will be useful,
9 .\" but WITHOUT ANY WARRANTY; without even the implied warranty of
10 .\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 .\" GNU General Public License for more details.
13 .\" You should have received a copy of the GNU General Public License
14 .\" along with this program; if not, write to the Free Software
15 .\" Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 .\" Japanese Version Copyright (c) 2008 Akihiro MOTOKI
19 .\" all rights reserved.
20 .\" Translated 2008-11-19, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP v3.13
21 .\" Updated 2009-04-24, Akihiro MOTOKI <amotoki@dd.iij4u.or.jp>, LDP 3.20
23 .TH TIMERFD_CREATE 2 2009-03-10 Linux "Linux Programmer's Manual"
25 timerfd_create, timerfd_settime, timerfd_gettime \-
26 ファイルディスクリプタ経由で通知するタイマー
29 .B #include <sys/timerfd.h>
31 .BI "int timerfd_create(int " clockid ", int " flags );
33 .BI "int timerfd_settime(int " fd ", int " flags ,
34 .BI " const struct itimerspec *" new_value ,
35 .BI " struct itimerspec *" old_value );
37 .BI "int timerfd_gettime(int " fd ", struct itimerspec *" curr_value );
40 これらのシステムコールは、満了通知をファイルディスクリプタ経由で配送する
46 を用いる方法の代わりとなるものであり、このファイルディスクリプタを
54 .BR timer_settime (2),
57 .RB ( timer_getoverrun (2)
65 は新規のタイマーオブジェクトを生成し、そのタイマーを参照するファイル
68 引き数は、タイマーの進捗を管理するためのクロックを指定するもので、
74 はシステム全体で使用されるクロックで、このクロックは変更可能である。
76 は変更されることのないクロックで、(システム時刻の手動での変更などの)
77 システムクロックの不連続な変化の影響を受けない。
83 以下の値のいくつかをビット単位の論理和 (OR) で指定することで、
88 新しく生成されるオープンファイル記述 (open file description) の
108 バージョン 2.6.26 以前の Linux では、
110 引き数は未使用であり、0 を指定しなければならない。
111 .SS timerfd_settime()
112 .BR timerfd_settime ()
115 により参照されるタイマーを開始したり停止したりする。
118 引き数は、タイマーの満了時間 (expiration) の初期値と間隔 (interval) を
121 構造体には 2 つのフィールドがあり、各フィールドは
128 time_t tv_sec; /* Seconds */
129 long tv_nsec; /* Nanoseconds */
133 struct timespec it_interval; /* Interval for periodic timer */
134 struct timespec it_value; /* Initial expiration */
139 .I new_value.it_value
140 はタイマーの満了時間の初期値を、秒とナノ秒で指定する。
141 .I new_value.it_value
142 のフィールドのうち少なくとも一方に 0 以外の値を設定すると、
144 両方のフィールドに 0 を設定すると、タイマーが停止する。
146 .I new_value.it_interval
147 はタイマーの一回目の満了後に繰り返しタイマーの満了間隔を、秒とナノ秒で指定する。
148 .I new_value.it_interval
149 のフィールドのうち少なくとも一方に 0 以外の値を設定すると、
151 両方のフィールドに 0 を設定した場合、タイマーは
152 .I new_value.it_value
153 で指定された時間後に、一回だけ満了して停止する。
160 .I new_value.it_interval
163 で指定されたクロックの現在の値からの相対的な時刻を指定する。
166 .I new_value.it_interval
169 で指定されたクロックの絶対時刻を指定する。つまり、
171 .I new_value.it_interval
172 で指定された時刻に達したら、タイマーが満了する。
176 .BR timerfd_settime ()
177 を呼び出した時点でのタイマーの設定を保持した構造体が返される。
179 .BR timerfd_gettime ()
182 .SS timerfd_gettime()
183 .BR timerfd_gettime ()
193 フィールドは、タイマーが次に満了するまでの残り時間を返す。
194 この構造体の両方のフィールドが 0 であれば、タイマーは現在停止している。
197 フラグが指定されたかに関わらず、このフィールドは常に相対値が格納される。
201 この構造体の両方のフィールドが 0 であれば、タイマーは
202 .I new_value.it_value
203 で指定された時間後に一回だけ満了して停止するように設定されている。
204 .SS タイマー・ファイルディスクリプタに対する操作
205 .BR timerfd_create ()
206 が返すファイルディスクリプタは以下の操作をサポートしている。
209 .BR timerfd_settime ()
210 を使ってタイマーの設定が最後変更されて以降、または
212 の呼び出しに最後に成功して以降に、タイマーの満了が一回以上発生していれば、
214 に渡されたバッファに、タイマー満了回数を示す 8 バイトの unsigned 型の整数
217 (返される値はホストバイトオーダ、つまりそのホストマシンにおける
221 を行った時点でタイマーの満了が発生していなければ、
223 は停止 (block) する、もしくはファイルディスクリプタが
224 非停止 (nonblocking) に設定されている場合はエラー
234 渡されたバッファのサイズが 8 バイト未満の場合、
240 .BR poll "(2), " select "(2) (と同様の操作)"
242 ファイルディスクリプタは読み出し可能となる
252 このファイルディスクリプタは、他のファイルディスクリプタ多重 API である
259 ファイルディスクリプタがそれ以降は必要なくなった際には、クローズすべきである。
260 同じ timer オブジェクトに関連付けられたファイルディスクリプタが全て
261 クローズされると、そのタイマーは解除され、
262 そのオブジェクト用の資源がカーネルにより解放される。
267 .BR timerfd_create ()
268 により生成されたファイルディスクリプタのコピーを
269 継承する。そのファイルディスクリプタは、親プロセスの対応する
270 ファイルディスクリプタと同じタイマーオブジェクトを参照しており、
273 でも同じタイマーの満了に関する情報が返される。
278 .BR timerfd_create ()
279 により生成されたファイルディスクリプタは保持され、
280 タイマーが開始されていた場合にはタイマーの満了が発生し続ける。
283 .BR timerfd_create ()
289 .BR timerfd_settime ()
291 .BR timerfd_gettime ()
297 .BR timerfd_create ()
310 が無効である。もしくは、Linux 2.6.26 以前の場合は
315 オープン済みのファイルディスクリプタの数がプロセスあたりの上限に
319 オープン済みのファイル総数がシステム全体の上限に達していた。
322 (カーネル内の) 無名 inode デバイスをマウントできなかった。
325 タイマーを作成するのに十分なカーネルメモリがなかった。
327 .BR timerfd_settime ()
329 .BR timerfd_gettime ()
344 が有効な timerfd ファイルディスクリプタでない。
346 .BR timerfd_settime ()
353 の一つが 0 から 999,999,999 までの範囲に入っていない)。
356 .\" This case only checked since 2.6.29, and 2.2.2[78].some-stable-version.
357 .\" In older kernel versions, no check was made for invalid flags.
361 これらのシステムコールはカーネル 2.6.25 以降の Linux で利用可能である。
362 ライブラリ側のサポートはバージョン 2.8 以降の glibc で提供されている。
364 これらのシステムコールは Linux 固有である。
366 以下のプログラムは、タイマーを作成し、その進捗をモニターするものである。
367 このプログラムは最大で 3 個のコマンドライン引き数を取り、
368 第一引き数ではタイマーの満了時間の初期値 (秒数単位) を、
369 第二引き数ではタイマーの間隔 (秒数単位) を、
370 第三引き数ではタイマーが何回満了したらプログラムが終了するかを指定する。
373 以下のシェルのセッションはこのプログラムの使用例を示したものである。
377 .RB "$" " a.out 3 1 100"
379 3.000: read: 1; total=1
380 4.000: read: 1; total=2
381 .BR "^Z " " # type control-Z to suspend the program"
382 [1]+ Stopped ./timerfd3_demo 3 1 100
383 .RB "$ " "fg" " # Resume execution after a few seconds"
385 9.660: read: 5; total=7
386 10.000: read: 1; total=8
387 11.000: read: 1; total=9
388 .BR "^C " " # type control-C to suspend the program"
394 .\" The commented out code here is what we currently need until
395 .\" the required stuff is in glibc
398 .\"/* Link with -lrt */
399 .\"#define _GNU_SOURCE
400 .\"#include <sys/syscall.h>
401 .\"#include <unistd.h>
403 .\"#if defined(__i386__)
404 .\"#define __NR_timerfd_create 322
405 .\"#define __NR_timerfd_settime 325
406 .\"#define __NR_timerfd_gettime 326
410 .\"timerfd_create(int clockid, int flags)
412 .\" return syscall(__NR_timerfd_create, clockid, flags);
416 .\"timerfd_settime(int fd, int flags, struct itimerspec *new_value,
417 .\" struct itimerspec *curr_value)
419 .\" return syscall(__NR_timerfd_settime, fd, flags, new_value,
424 .\"timerfd_gettime(int fd, struct itimerspec *curr_value)
426 .\" return syscall(__NR_timerfd_gettime, fd, curr_value);
429 .\"#define TFD_TIMER_ABSTIME (1 << 0)
431 .\"////////////////////////////////////////////////////////////
432 #include <sys/timerfd.h>
437 #include <stdint.h> /* Definition of uint64_t */
439 #define handle_error(msg) \\
440 do { perror(msg); exit(EXIT_FAILURE); } while (0)
443 print_elapsed_time(void)
445 static struct timespec start;
446 struct timespec curr;
447 static int first_call = 1;
452 if (clock_gettime(CLOCK_MONOTONIC, &start) == \-1)
453 handle_error("clock_gettime");
456 if (clock_gettime(CLOCK_MONOTONIC, &curr) == \-1)
457 handle_error("clock_gettime");
459 secs = curr.tv_sec \- start.tv_sec;
460 nsecs = curr.tv_nsec \- start.tv_nsec;
465 printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
469 main(int argc, char *argv[])
471 struct itimerspec new_value;
474 uint64_t exp, tot_exp;
477 if ((argc != 2) && (argc != 4)) {
478 fprintf(stderr, "%s init\-secs [interval\-secs max\-exp]\\n",
483 if (clock_gettime(CLOCK_REALTIME, &now) == \-1)
484 handle_error("clock_gettime");
486 /* Create a CLOCK_REALTIME absolute timer with initial
487 expiration and interval as specified in command line */
489 new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
490 new_value.it_value.tv_nsec = now.tv_nsec;
492 new_value.it_interval.tv_sec = 0;
495 new_value.it_interval.tv_sec = atoi(argv[2]);
496 max_exp = atoi(argv[3]);
498 new_value.it_interval.tv_nsec = 0;
500 fd = timerfd_create(CLOCK_REALTIME, 0);
502 handle_error("timerfd_create");
504 if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == \-1)
505 handle_error("timerfd_settime");
507 print_elapsed_time();
508 printf("timer started\\n");
510 for (tot_exp = 0; tot_exp < max_exp;) {
511 s = read(fd, &exp, sizeof(uint64_t));
512 if (s != sizeof(uint64_t))
513 handle_error("read");
516 print_elapsed_time();
517 printf("read: %llu; total=%llu\\n",
518 (unsigned long long) exp,
519 (unsigned long long) tot_exp);
528 .BR timerfd_create ()
539 .BR timer_create (2),
540 .BR timer_gettime (2),
541 .BR timer_settime (2),