SylixOSにおけるselectの原理と使用分析
1.selectインタフェースの概要
1.1 selectインタフェース使用例
selectはオペレーティングシステムの多重I/O多重化技術を実現する方法の一つである.多重I/O多重化技術は、興味のあるファイル記述子のリストを作成し、多重化されたIOインタフェースを呼び出し、これらの記述子の1つがI/Oを行う準備ができているまでインタフェースをブロックします.selectがアプリケーションで使用する例は、次のセグメントコードに示す.
1.2 select関数プロトタイプ分析 iWidthは設定されたファイルセットで、最大のファイル番号+1です. pfdsetReadは、関心のある読み取り可能なファイルセットである. pfdsetWriteは関心のある書き込み可能なファイルセットである. pfdsetExceptは関心のある異常ファイルセットである. ptmvalTOは待ちタイムアウト時間、LW_NULLは永遠に待つことを表す. 戻り値:通常戻り待ちファイル数、エラー戻りPX_ERROR.
2.駆動中のselect実装
2.1駆動ioctl実装
SylixOSのselectインタフェース実装では、fdごとに対応するデバイス駆動のioctlインタフェースが呼び出され、次の表に示す2つのコマンドが呼び出されます.
コマンド#コマンド#
説明
FIOSELECT
SEL_を追加WAKE_NODEノード
FIOUNSELECT
SEL_の削除WAKE_NODEノード
2.2 SylixOSのselect待機チェーン
SEL_の追加と削除WAKE_NODEの操作は、実際にはSylixOSのselect待機チェーンを操作し、SEL_WAKE_NODE_ADDとSEL_WAKE_NODE_DELETEのシステムインタフェース.待機チェーンの役割は、起動するスレッドのセットをブロックすることであり、起動が必要な場合にシステムのSEL_を呼び出すことができる.WAKE_UPシリーズ関数はスレッドの起動を実現します.SylixOSが提供する起動コマンドを下表に示します.
コマンド#コマンド#
説明
SEL_WAKE_UP
待機スレッドを起動
SEL_WAKE_UP_ALL
あるタイプの操作を待つすべてのスレッドを起動します.
SEL_WAKE_UP_TYPE
取得ノードの待機タイプ
SEL_WAKE_UP_ERROR
エラーが発生したため、待機しているスレッドを起動します.
SEL_WAKE_UP_TERM
エラーが発生したため、あるタイプの操作を待機しているすべてのスレッドを起動します.
2.3 SylixOSのselectコンテキスト
なお、selectブロッキング動作で使用される信号量はselectコンテキストであり、駆動するFIOSELECTでもう1つの信号量を実現する必要はない.selectのコンテキストは次のセグメントに示す.
3.閉塞と起動の実現
3.1ブロック操作
selectのブロック動作は、その内部呼び出しpselect関数においてバイナリ信号量を呼び出すpend動作によって実現される.しかしpendを呼び出す前に、pselectはまずioctlを呼び出し、FIOSELECTパラメータを渡します.このインタフェースでは、selectの起動条件が現在満たされているかどうかを判断し、満たされている場合はpostを呼び出し、その後呼び出されたpendがブロックされないようにします.その流れを下図に示します.
3.2起動操作
起動が必要な場所でSEL_を呼び出すWAKE_UPシリーズインタフェース、例えば割り込みが発生した箇所、検出されたスレッド.
1.1 selectインタフェース使用例
selectはオペレーティングシステムの多重I/O多重化技術を実現する方法の一つである.多重I/O多重化技術は、興味のあるファイル記述子のリストを作成し、多重化されたIOインタフェースを呼び出し、これらの記述子の1つがI/Oを行う準備ができているまでインタフェースをブロックします.selectがアプリケーションで使用する例は、次のセグメントコードに示す.
#include
int main (int argc, char **argv)
{
fd_set fdset;
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
int fd = open("/dev/htm2", O_RDWR, 0666);
for (;;) {
FD_ZERO(&fdset);
FD_SET(fd, &fdset);
select(fd + 1, &fdset, &fdset, NULL, &timeout);
sleep(1);
}
return (0);
}
1.2 select関数プロトタイプ分析
LW_API INT select(INT iWidth,
fd_set *pfdsetRead,
fd_set *pfdsetWrite,
fd_set *pfdsetExcept,
struct timeval *ptmvalTO);
2.駆動中のselect実装
2.1駆動ioctl実装
SylixOSのselectインタフェース実装では、fdごとに対応するデバイス駆動のioctlインタフェースが呼び出され、次の表に示す2つのコマンドが呼び出されます.
コマンド#コマンド#
説明
FIOSELECT
SEL_を追加WAKE_NODEノード
FIOUNSELECT
SEL_の削除WAKE_NODEノード
2.2 SylixOSのselect待機チェーン
SEL_の追加と削除WAKE_NODEの操作は、実際にはSylixOSのselect待機チェーンを操作し、SEL_WAKE_NODE_ADDとSEL_WAKE_NODE_DELETEのシステムインタフェース.待機チェーンの役割は、起動するスレッドのセットをブロックすることであり、起動が必要な場合にシステムのSEL_を呼び出すことができる.WAKE_UPシリーズ関数はスレッドの起動を実現します.SylixOSが提供する起動コマンドを下表に示します.
コマンド#コマンド#
説明
SEL_WAKE_UP
待機スレッドを起動
SEL_WAKE_UP_ALL
あるタイプの操作を待つすべてのスレッドを起動します.
SEL_WAKE_UP_TYPE
取得ノードの待機タイプ
SEL_WAKE_UP_ERROR
エラーが発生したため、待機しているスレッドを起動します.
SEL_WAKE_UP_TERM
エラーが発生したため、あるタイプの操作を待機しているすべてのスレッドを起動します.
2.3 SylixOSのselectコンテキスト
なお、selectブロッキング動作で使用される信号量はselectコンテキストであり、駆動するFIOSELECTでもう1つの信号量を実現する必要はない.selectのコンテキストは次のセグメントに示す.
typedef struct {
LW_OBJECT_HANDLE SELCTX_hSembWakeup; /* */
BOOL SELCTX_bPendedOnSelect; /* select() */
fd_set *SELCTX_pfdsetReadFds; /* */
fd_set *SELCTX_pfdsetWriteFds; /* */
fd_set *SELCTX_pfdsetExceptFds; /* */
fd_set SELCTX_fdsetOrigReadFds; /* */
fd_set SELCTX_fdsetOrigWriteFds; /* */
fd_set SELCTX_fdsetOrigExceptFds; /* */
INT SELCTX_iWidth; /* select() */
} LW_SEL_CONTEXT;
typedef LW_SEL_CONTEXT *PLW_SEL_CONTEXT;
3.閉塞と起動の実現
3.1ブロック操作
selectのブロック動作は、その内部呼び出しpselect関数においてバイナリ信号量を呼び出すpend動作によって実現される.しかしpendを呼び出す前に、pselectはまずioctlを呼び出し、FIOSELECTパラメータを渡します.このインタフェースでは、selectの起動条件が現在満たされているかどうかを判断し、満たされている場合はpostを呼び出し、その後呼び出されたpendがブロックされないようにします.その流れを下図に示します.
3.2起動操作
起動が必要な場所でSEL_を呼び出すWAKE_UPシリーズインタフェース、例えば割り込みが発生した箇所、検出されたスレッド.