#author("2017-11-05T22:37:04+09:00","default:afuruta","afuruta") #author("2017-11-07T12:13:02+09:00","default:afuruta","afuruta") * HPET API [#be6692a3] [[HPET API English page>HPET API]] このページは HPET driver が提供する API をまとめたページです。map ページに似た書式を使います。man page の書式に次の修正・追加をしています。 このページは HPET driver が提供する API をまとめたページです。man ページに似た書式を使います。man page の書式に次の修正・追加をしています。 - "SYNOPSIS" 定数あるいは望ましい引数で示している箇所が有ります。 - "PRECONDITION" 関数を呼び出す前に満たす必要がある条件を示しています。 - "RETURN VALUE" and "ERROR" HPET ドライバ固有の仕様だけ示しています。基本的な system call 仕様は man ページを見て下さい。 - "KERNEL CONFIGURATION and PARAMETER" API の機能に影響するカーネル構築条件、カーネル起動パラメータを示します。 - "KERNEL SOURCE" 関係する kernel のソース・コード位置を示します。 ** 機能一覧 [#w04c2733] HPET ドライバには次の機能が備わっています。 - [[HPET timer を確保する>#td026212]]。 - [[timer の機能・状態を調べる>#pdce19e5]]。 - [[割り込み周波数を設定する>#bd9cfaa7]]。 - ハードウエアで実装された周期割り込みを [[有効化>#m7832c4e]]/[[無効化>#y3465016]] する。&br;(ハードウエア実装で周期割り込みを実現するかソフトウエア実装で周期割り込みを実現するか選択します) - timer 割り込みを [[有効化>#ma83f3b9]]/[[無効化>#rcb4bb60]] します。 - poll()/select() で待っているプロセス・スレッドに対してイベントを起こします。[[HPET_IE_ON>#ma83f3b9]] を参照して下さい。 - シグナルを送ります。fcntl() 機能を使います。[[F_SETOWN>#u578f126]], [[F_SETFL>#g6b699cd]], [[FSET_OWN>#ub0566d7]] を参照して下さい。 - [[割り込み回数を読み出し・クリアします>#x52e9d21]]。 - [[HPET レジスタをメモリ・アドレス空間にマップします>#g68651f3]]。&br;(CONFIG_HPET_MMAP を付けて構築した kernel で使用できます) より詳細な情報は [[HPET 仕様書>https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf]] を見て下さい。 ** サンプルプログラム [#nd179a17] HPET ドライバ &ogfileone(/drivers/char/hpet.c); API の仕様を知るためにサンプルプログラム &ref(hpet_example - HPET sample Application/hpet_example.tar.gz); を用意しました。このプログラムは &ogfileone(/Documentation/timers/hpet_example.c); に基づいて作成されています。修正と機能拡張が施されています。 ** Device path [#cc1eca9f] 多くの Linux ディストリビューション では HPET ドライバを有効化して構築されています。/dev/hpet ノードが用意されています。/dev/hpet ノードはキャラクタ・デバイス・ノードで major=10, minor=228 という番号が付いています。"misc device" の一つです。 ** device を開く [#cc1eca9f] HPET を使うには /dev/hpet を O_RDONLY モードで開きます。未使用の HPET timer が有れば、一つの timer を開いたファイル・ディスクリプタに割り当てます。timer は HPET 回路ブロックに複数ある timer のうちの一つです。ioctl() システム・コールでファイル・ディスクリプタに割り当てられた timer を操作します。 ** Header files [#g51b6a6f] user space (Linux アプリケーション) から HPET device を使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#define _GNU_SOURCE}; &span(ConsoleOut){#include <features.h>}; &span(ConsoleOut){#include <sys/types.h>}; &span(ConsoleOut){#include <sys/stat.h>}; &span(ConsoleOut){#include <sys/ioctl.h>}; &span(ConsoleOut){#include <unistd.h>}; &span(ConsoleOut){#include <fcntl.h>}; &span(ConsoleOut){#include <linux/hpet.h>}; }} poll() を使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#include <poll.h>}; }} select() を使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#include <sys/time.h>}; &span(ConsoleOut){#include <sys/select.h>}; }} signal() を使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#include <signal.h>}; }} mmap() を使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#include <sys/mman.h>}; }} システム・コール エラーを使うには次のヘッダファイルを取り込んで下さい。 #pre(soft){{ &span(ConsoleOut){#include <string.h>}; /* strerror() */ &span(ConsoleOut){#include <errno.h>}; /* errno, Exxx macros. */ }} ** HPET ドライバの ioctl API [#ycda765a] ここでは HPET ドライバの ioctl() API を示します。HPET ドライバは次に示す ioctl() API を提供しています。 |ioctl 要求番号|説明|h |HPET_INFO|timer の情報を取得します&br;int ioctl(int fd, HPET_INFO, /* out */ struct hpet_info *info);| |HPET_IRQFREQ|割り込み周波数(Hz)を設定します&br;int ioctl(int fd, HPET_IRQFREQ, unsigned long frequency);| |HPET_EPI|ハードウエアによる周期割り込み機能を使うようにします&br;int ioctl(int fd, HPET_EPI);| |HPET_DPI|ハードウエアによる周期割り込み機能を使わないようにします&br;(ソフトウエアによって周期割り込みを起こします)&br;int ioctl(int fd, HPET_DPI);| |HPET_IE_ON|timer からの割り込みを許可します&br;int ioctl(int fd, HPET_IE_ON);| |HPET_IE_OFF|timer からの割り込みを禁止します&br;int ioctl(int fd, HPET_IE_OFF);| このページでは HPET ドライバ固有の仕様を示します。ioctl() システム・コールの基本的な仕様については [[man 2 ioctl>https://www.google.co.jp/search?num=100&newwindow=1&q=man+2+ioctl&oq=man+2+ioctl]] を参照して下さい。 *** HPET_INFO - timer の情報を取得します [#pdce19e5] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){struct hpet_info {}; &span(ConsoleOut){ unsigned long hi_ireqfreq; /* Period or time in Hz */}; &span(ConsoleOut){ unsigned long hi_flags; /* Information: 0x0: Not supported periodic int., 0x10: Supported periodic int. */}; &span(ConsoleOut){ unsigned short hi_hpet; /* HPET device number, [0..TheNumberOfHPETDevicesInPlatform-1] */}; &span(ConsoleOut){ unsigned short hi_timer; /* Timer number in HPET device, [0..31] */}; &span(ConsoleOut){};}; &span(ConsoleOut){int ioctl(int fd, HPET_INFO, /* out */ struct hpet_info *info);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer の情報を取得します。リクエスト・コード HPET_INFO で ioctl() を呼び出すと、timer の情報を *info に格納します。hpet_info 構造体の各メンバは次に示す値になります。 |メンバ|説明|h |hi_ireqfreq|周波数(Hz)で表した割り込み周期| |hi_flags|timer の機能。 次の値のいずれかになります。&br;''0x00UL'' ハードウエアで実装された周期割り込み機能がありません。&br;''0x10UL'' ハードウエアで実装された周期割り込み機能が有ります。&br;''解析で気づいたこと: '' 将来的にはビットフィールドで示される可能性がありそうです。| |hi_hpet|プラットホーム上で番号づけられた HPET デバイス番号です。(hi_hpet >= 0) && (hi_hpet < M) を満たします。M はプラットホーム上に存在する HPET デバイス(回路ブロック) 番号です。&br;''注:'' HPET デバイス(回路ブロック) の中に複数の timer があります。| |hi_timer|HPET デバイス(回路ブロック) 中の timer 番号です。(hi_timer >= 0) && (hi_timer < N) を満たします。N は HPET デバイス(回路ブロック) 中で数えた timer 番号です。N <= 32 を満たします。&br;''NOTE: ''恐らく一番初めに開いた HPET timer は {hi_hpet, hi_timer} == {0, 2} となっているでしょう。これは timer 0 と timer 1 が PIT(programmable Interval Timer) と RTC(Real Time Clock) をそれぞれ置き換えるために使われているからです。| - ''RETURN VALUE'' -- ''0:'' 成功 -- ''-1:'' エラー - ''ERRORS'' -- ''EBADF:'' ファイル・ディスクリプタの値が正しくない。 -- ''EFAULT:'' info が指しているメモリにアクセスできない。 - ''KERNEL SOURCE''&br; &ogrefs(HPET_INFO,HPET_INFO,hpet.c); *** HPET_IRQFREQ - 割り込み周波数(Hz)を設定します [#bd9cfaa7] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int ioctl(int fd, HPET_IRQFREQ, unsigned long frequency);}; }} - ''PRECONDITION''&br; -- timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。 - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer に割り込み周波数(Hz) で設定します。割り込み周期は 1/frequency 秒になります。プロセスに CAP_SYS_RESOURCE ケーパビリティが付与されていない場合は、周波数は /proc/sys/dev/hpet/max-user-freq から読んだ値以下で設定できます。 max-user-freq の初期値は 64 (==&ogdefs(HPET_USER_FREQ);) です。&br;割り込み許可状態で割り込み周期を更新しないで下さい。 - ''RETURN''&br; -- ''0:'' 成功 -- ''-1:'' エラー - ''ERRORS'' -- ''EACCESS'' プロセスに &ogdefs(CAP_SYS_RESOURCE); ケーパビリティが付与されていないのに、/proc/sys/dev/hpet/max-user-freq から読んだ値より大きい周波数を設定しようとしました。max-user-freq から読んだ値の初期値は 64 (==&ogdefs(HPET_USER_FREQ);) です。 -- ''EINVAL:'' 周波数を 0 にしようとしました。 - ''FILES''&br; -- /proc/sys/dev/hpet/max-user-freq - ''KERNEL SOURCE''&br; &ogrefs(HPET_IRQFREQ,HPET_IRQFREQ,hpet.c);, &ogdefs(hpet_max_freq);, &ogdefs(HPET_USER_FREQ);, &ogdefs(hpet_interrupt()); *** HPET_EPI - ハードウエアによる周期割り込み機能を使うようにします [#m7832c4e] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int ioctl(int fd, HPET_EPI);}; }} - ''PRECONDITION''&br; -- timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。 - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer のハードウエアによる周期割り込み機能を使用するようにします。ソフトウエアによる周期割り込み機能は使わないようになります。この ioctl() HPET_EPI 要求は timer の割り込みを許可する HPET_IE_ON をする前に使って下さい。 - ''RETURN VALUE''&br; -- ''0:'' 成功 -- ''-1:'' エラー - ''ERRORS'' -- ''EBADF:'' ファイル・ディスクリプタ fd が無効です。 -- ''ENXIO:'' ファイル・ディスクリプタ fd に割り当てられた timer にハードウエアによる周期割り込み機能が無い。 - ''KERNEL SOURCE''&br; &ogrefs(HPET_EPI,HPET_EPI,hpet.c); *** HPET_DPI - ハードウエアによる周期割り込み機能を使わないようにします [#y3465016] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int ioctl(int fd, HPET_DPI);}; }} - ''PRECONDITION''&br; -- timer 割り込みを禁止して下さい。HPET_IE_OFF を使います。 - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer のハードウエアによる周期割り込み機能を使用しないようにします。ソフトウエアによる周期割り込み機能を使うようにします。この ioctl() HPET_FPI 要求は timer の割り込みを許可する HPET_IE_ON をする前に使って下さい。&br;timer を HPET_DPI (ハードウエアによる周期割り込み禁止) で使う場合、HPET ドライバは timer を割り込みハンドラ中で更新し、次の割り込みを発生させるようにします。従って timer 割り込みはソフトウエアが応答するのに掛かる時間を含んだ周期で周期的に割り込みが発生します。 - ''RETURN VALUE''&br; -- ''0:'' 成功 -- ''-1:'' エラー - ''ERRORS'' -- ''EBADF:'' ファイル・ディスクリプタ fd が無効です。 -- ''ENXIO:'' ファイル・ディスクリプタ fd に割り当てられた timer にハードウエアによる周期割り込み機能が無い。 - ''KERNEL SOURCE''&br; &ogrefs(HPET_DPI,HPET_DPI,hpet.c);, &ogdefs(hpet_interrupt()); *** HPET_IE_ON - timer からの割り込みを許可します [#ma83f3b9] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int ioctl(int fd, HPET_IE_ON);}; }} - ''PRECONDITION''&br; -- 割り込み周期を ioctl HPET_IRQFREQ リクエストで設定して下さい。 -- ハードウエアによる周期割り込み機能を使うか (HPET_EPI)・使わない (HPET_DPI) か設定して下さい。&br;''注:'' ハードウエアによる周期割り込み機能が無い場合はソフトウエアにより周期割り込みが発生します。 - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer の割り込みを許可します。timer がプロセッサに割り込みを掛けたならば、ファイル・ディスクリプタ fd は (POLLIN|POLLRDNORM) イベントにて準備済み状態になります(待ちが解除されます)、同時にファイル・ステータス・フラグに O_ASYNC、有効なオーナー、有効なシグナル番号が設定されているならばシグナルが送られます。 - ''RETURN VALUE'' -- ''0:'' 成功 -- ''-1:'' 失敗 - ''ERRORS'' -- ''EBADF:'' ファイル・ディスクリプタ fd が無効です。 -- ''EIO:'' 次のうちいずれかの状態です。 --- 割り込み周波数が無効です。 --- 割り込み周波数が設定されていません。 --- 割り込みハンドラを登録要求できません。チップセットか BIOS のバグが原因になっている可能性があります。 -- ''EBUSY:'' --- 割り込みは既に許可状態です。 - ''KERNEL SOURCE''&br; &ogrefs(HPET_IE_ON,HPET_IE_ON,hpet.c);, &ogdefs(hpet_interrupt()); *** HPET_IE_OFF - timer からの割り込みを禁止します [#rcb4bb60] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int ioctl(int fd, HPET_IE_OFF);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer からの割り込みを禁止します。 - ''RETURN VALUE'' -- ''0:'' 成功 -- ''-1:'' エラー - ''ERRORS'' -- ''EBADF:'' ファイル・ディスクリプタ fd が無効です。 - ''KERNEL SOURCE''&br; &ogrefs(HPET_IE_OFF,HPET_IE_OFF,hpet.c); ** HPET と関係する ファイル・システム と メモリ・マップ API [#xcd77816] この節では HPET ドライバに関係するファイル・システムとメモリ・マップ API について説明します。open(), close(), read(), mmap(), munmap(), fcntl() とこれらの類似関数を HPET に対して使うと、HPET 特有の動作をします。ここでは HPET 特有の動作を示します。ファイル・システムの基本的な動作と詳細はシステム・コールの man page を参照してください。ファイル・ディスクリプタからシグナルを送る詳細は [[man 2 fcntl>https://www.google.co.jp/search?num=100&newwindow=1&q=man+2+fcntl&oq=man+2+fcntl]] を参照してください。 *** open - HPET timer を開く [#td026212] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int open(const char *hpet_path, /* open mode */ O_RDONLY);}; }} - ''DESCRIPTION''&br; 未使用の HPET timer を開きます。殆どの Linux ディストリビューションで hpet_path は "/dev/hpet" となります。このパスは major = 10, minor = 228 のキャラクタデバイスノードです。未使用の HPET timer がない場合は、open は失敗し EBUSY エラーになります。オープン・モードに O_RDONLY を使用してください。 - ''RETURN VALUE'' -- ''return_value >= 0:'' HPET timer が割り当てられたファイル・ディスクリプタです。 -- ''-1:'' エラー - ''ERROR (HPET デバイス固有)'' -- ''EINVAL:'' オープン・モードに書き込みモードが含まれている。 -- ''EBUSY:'' 未使用の HPET timer がない。すなわち、すべての HPET timer が使われている。 - ''FILES'' -- /dev/hpet - ''KERNEL SOURCE'' -- &ogdefs(hpet_open()); *** close - HPET timer を閉じる [#q45d3eac] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int close(int fd);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に割り当てられた timer をクローズします。ファイル・ディスクリプタ fd に割り当てられた timer を開放し、timer は未使用状態になります。厳密に言えば、ファイル・ディスクリプタ fd に対する参照が全て無くなった時に timer は開放されます。ファイル・ディスクリプタ fd を二重化したり、メモリ・マッピングを行った時にファイル・ディスクリプタ fd に対する参照が増えます。timer を開放するときに次の処理を行います。 -- timer からの割り込みを止めます。 -- ハードウエアによる周期割り込み機能を使わない設定にします。 -- IRQ ハンドラを開放します。 - ''KERNEL SOURCE'' -- &ogdefs(hpet_release()); *** read - 割り込み回数を読みだしクリアする [#x52e9d21] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int read(int fd, unsigned long *buf, /* size */ sizeof(unsigned long));}; }} - ''DESCRIPTION''&br; 割り込み回数を読みだしてクリアします。割り込み回数は *buf に格納されます。size 引数に sizeof(unsigned long) を使ってください。サイズ引数は sizeof(unsigned long) 以上の値を指定できます。しかし、関数が成功した場合の戻り値は sizeof(unsigned long) と同じになります。 -- O_NONBLOCK モードで HPET timer をオープンした場合は read() は次のように動作します。 --- timer の割り込みが前回の read() から、今の read() までに発生していたならば、割り込み回数を *buf に格納し戻ります。 --- timer の割り込みが前回の read() から、今の read() までに発生していないならば、read() は EAGAIN エラーで失敗します。 -- O_NONBLOCK モード無しで HPET timer をオープンした場合は read() は次のように動作します。 --- timer の割り込みが前回の read() から、今の read() までに発生していたならば、割り込み回数を *buf に格納し戻ります。 --- timer の割り込みが前回の read() から、今の read() までに発生していないならば、read() は割り込み発生まで戻りません。 - ''RETURN VALUE'' -- ''sizeof(unsigned long):'' 成功 -- ''-1:'' エラー - ''ERROR (HPET デバイス固有)'' -- ''EIO:'' 割り込み周波数が設定されていません。 -- ''EFAULT:'' buf で指したアドレス空間はアクセスできません。 -- ''EINVAL:'' size の値が sizeof(unsigned long) より小さい。 -- ''EAGAIN:'' 前回の read() システム・コールから割り込みは発生していません。 -- ''EINTR:'' シグナルを受けました。 - ''KERNEL SOURCE''&br; &ogdefs(hpet_read()); *** mmap - HPET レジスタをメモリ・アドレス空間にマップする [#g68651f3] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){void *mmap(void *addr, size_t length, int prot, int flags, int fd, /* offset */ 0);}; &span(ConsoleOut){int munmap(void *addr, size_t length);}; }} - ''DESCRIPTION''&br; mmap() と munmap() でファイル・ディスクリプタ fd に割り付けられた timer を含む HPET レジスタをメモリ・アドレス空間にマップします。このシステム・コールは fd に割り付けた timer を含んだ HPET ブロックの全てのレジスタをメモリ空間にマップします。mmap() が有効なポインタを返したならば、ポインタは HPET の "General Capabilities and ID Register" を指しています。&br; length に指定できる値の範囲は [ 0x1 .. page size (equal to sysconf(_SC_PAGESIZE)) ] です。しかし、HPET の全てのレジスタと場合によっては他のデバイスのレジスタを含んだ範囲をページサイズあるいはそれ以上の範囲でメモリ・アドレス空間へマップします。&br; offset は 0 にして下さい。 - ''RETURN VALUE '' -- ''return_value != MAP_FAILED:'' 関数が返したポインタは HPET "General Capabilities and ID Register" を指しています。 -- ''MAP_FAILED:'' HPET レジスタをマップ出来ません。 - ''ERROR (HPET デバイス固有)'' -- ''EACCESS:'' mmap() に対応していません。kernel が CONFIG_HPET_MMAP_DEFAULT を指定せずに構築されたか、kernel の boot パラメータに "hpet_mmap=0" が指定された状態で起動されました。HPET の mmap() 機能を使うには kernel の boot パラメータに "hpet_mmap=1" を指定して下さい。 -- ''ENOSYS:'' --- kernel に HPET レジスタを mmap() でメモリ・アドレス空間にマップする機能が有りません。kernel が CONFIG_HPET_MMAP を指定されずに構築されています。この場合、kernl の boot パラメータに "hpet_mmap=1" を指定してもエラーになります。 --- HPET のハードウエア実装に起因する問題があります。HPET レジスタの位置がページ境界に合っていません。 - ''KERNEL CONFIGURATION and PARAMETER''&br; HPET レジスタを mmap() 出来るようにするには次の条件を満たして下さい。 -- CONFIG_HPET_MMAP=y を指定して kernel を構築して下さい。 -- CONFIG_HPET_MMAP_DEFAULT=y を指定せずに構築された kernel ならば kernel boot パラメータに "hpet_mmap=1" を指定して下さい。 - ''SEE ALSO'' -- [[HPET specification>https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf]]. - ''KERNEL SOURCE''&br; &ogdefs(hpet_mmap()); *** F_GETOWN - ファイル・ディスクリプタのオーナーを取得する[#sb3baf92] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_GETOWN);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd のオーナーを取得します。オーナーはシグナルの送り先になります。 - ''RETURN VALUE''&br; -- ''0:'' オーナーはありません。シグナルは送られません。 -- ''return_value > 0:'' プロセス ID 番号です。 -- ''return_value < 0:'' 負のプロセス・グループ ID です。エラーとして扱われる可能性があるので注意が必要です。F_GETOWN_EX を使うのが良いです。 - ''KERNEL SOURCE''&br; &ogrefs(F_GETOWN,F_GETOWN,fcntl.c); *** F_GETOWN_EX - ファイル・ディスクリプタのオーナーを拡張仕様を使って取得する [#fff26c5c] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){struct f_owner_ex {}; &span(ConsoleOut){ int type; /* F_OWNER_PID, F_OWNER_PGRP, or F_OWNER_TID */}; &span(ConsoleOut){ pid_t pid; /* process id, process group id, or thread id. */}; &span(ConsoleOut){}}; &span(ConsoleOut){int fcntl(int fd, F_GETOWN_EX, /* out */ struct f_owner_ex *owner_ex);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd のオーナーを取得します。*owner_e に結果が格納されます。詳細は F_SETOWN_EX を参照して下さい。 - ''KERNEL SOURCE''&br; &ogrefs(F_GETOWN_EX,F_GETOWN_EX,fcntl.c); *** F_SETOWN - ファイル・ディスクリプタのオーナーを設定する [#u578f126] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_SETOWN, int owner);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd のオーナーを設定します。オーナーはプロセス ID、負の値にしたプロセス・グループ ID です。fd に割り付けられた timer からプロセッサに割り込みが入りファイル・ステータス・フラグに O_ASYNC が論理和されていたならば、シグナルがオーナーに送られます。 - ''KERNEL SOURCE''&br; &ogrefs(F_SETOWN,F_SETOWN,fcntl.c); *** F_SETOWN_EX - ファイル・ディスクリプタのオーナーを拡張仕様を使って設定します [#rf3b6390] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){struct f_owner_ex {}; &span(ConsoleOut){ int type; /* F_OWNER_PID, F_OWNER_PGRP, or F_OWNER_TID */}; &span(ConsoleOut){ pid_t pid; /* process id, process group id, or thread id. */}; &span(ConsoleOut){}}; &span(ConsoleOut){int fcntl(int fd, F_GETOWN_EX, /* in */ struct f_owner_ex *owner_ex);}; }} - ''DESCRIPTION''&br; ファイル・ディスクリプタ fd に プロセス ID, プロセス・グループ ID, スレッド ID のいずれかを設定します。owner_ex->type で owner_ex->pid の種別を指定します。owner_ex->type は F_OWNER_PID (プロセス ID), F_OWNER_PGRP (プロセス・グループ ID), F_OWNER_TID (スレッド ID) のいずれかを指定します。owner_ex->pid には先の type の指定に従って値を設定します。&br;fd に割り付けられた timer からプロセッサに割り込みが入りファイル・ステータス・フラグに O_ASYNC が論理和されていたならば、シグナルがオーナーに送られます。 - ''KERNEL SOURCE''&br; &ogrefs(F_SETOWN_EX,F_SETOWN_EX,fcntl.c); *** F_GETFL - ファイル・ステータス・フラグを取得する [#yc1882fd] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_GETFL);}; }} - ''DESCRIPTION''&br; この関数はファイル・ディスクリプタ fd の ファイル・ステータス・フラグに O_ASYNC フラグをセットまたはクリアするために使います。使用方法は F_SETFL の説明を参考にして下さい。 - ''KERNEL SOURCE''&br; &ogrefs(F_GETFL,F_GETFL,fcntl.c); *** F_SETFL - ファイル・ステータス・フラグを設定する [#g6b699cd] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_SETFL, int flags);}; }} - ''DESCRIPTION''&br; timer からの割り込みでシグナルを送るには、ファイル・ディスクリプタ fd のファイル・ステータス・フラグに O_ASYNC を論理和した値を設定して下さい。設定は次の擬似コード片のようにします。 #code(c){{ { int flags; flags = fcntl(fd, F_GETFL); if (flags < 0) { /* error handling. */ } flags |= O_ASYNC; if (fcntl(fd, F_SETFL, flags) != 0) { /* error handling. */ } } }} - ''KERNEL SOURCE''&br; &ogrefs(F_SETFL,F_SETFL,fcntl.c);, &ogdefs(setfl());, #define O_ASYNC &ogdefs(FASYNC); *** F_GETSIG - 送ろうとするシグナル番号を取得する[#zfddc3a9] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_GETSIG);}; }} - ''DESCRIPTION''&br; timer 割り込み発生時に送るシグナル番号を取得します。 - ''KERNEL SOURCE''&br; &ogrefs(F_GETSIG,F_GETSIG,fcntl.c); *** F_SETSIG - 送ろうとするシグナル番号を設定する[#ub0566d7] - ''SYNOPSIS'' #pre(soft){{ &span(ConsoleOut){int fcntl(int fd, F_SETSIG, int signal);}; }} - ''DESCRIPTION''&br; timer 割り込み発生時に送るシグナル番号を設定します。 - ''KERNEL SOURCE''&br; &ogrefs(F_SETSIG,F_SETSIG,fcntl.c);, &ogdefs(send_sigio());