Comments
Description
Transcript
2006チューニングカー
SUSE®Linux Enterprise RealTime User’s Guide 0898204-000 August 2006 Copyright 2006 by Concurrent Computer Corporation. All rights reserved. This publication or any part thereof is intended for use with Concurrent products by Concurrent personnel, customers, and end–users. It may not be reproduced in any form without the written permission of the publisher. The information contained in this document is believed to be correct at the time of publication. It is subject to change without notice. Concurrent makes no warranties, expressed or implied, concerning the information contained in this document. To report an error or comment on a specific portion of the manual, photocopy the page in question and mark the correction or comment on the copy. Mail the copy (and any additional comments) to Concurrent Computer Corporation, 2881 Gateway Drive, Pompano Beach, Florida, 33069. Mark the envelope “Attention: Publications Department.” This publication may not be reproduced for any other reason in any form without written permission of the publisher. Concurrent Computer Corporation and its logo are registered trademarks of Concurrent Computer Corporation. All other Concurrent product names are trademarks of Concurrent while all other product names are trademarks or registered trademarks of their respective owners. Linux® is used pursuant to a sublicense from the Linux Mark Institute.Linux is a registered trademark of Linus Torvalds. Printed in U. S. A. Revision History: Date Initial Release Level 000 Effective With SUSE Linux Enterprise Real Time 10 序文 マニュアルの範囲 このガイドは SUSE Linux Enterprise Real Time10 オペレーティング・システムを記述し ます。 このガイドの情報は SUSE Linux and SUSE Linux Enterprise Server 、SUSE Linux Enterprise Real Time の両方に適用します。 このマニュアルは3つの部分から成り立ちます。 第1部での情報はリアルタイムユーザーに向けられます。 第2部はシステム管理者に向けられます。 第3部は後付付録、用語集とインデックスから成り立ちます。 マニュアルの中身の概観が 続きます。 マニュアルの構成 このガイドは以下のセクションから構成されています。 1章 SUSE Linux Enterprise Real Time operating system の紹介、 SUSE Linux Enterprise Real Time operating system のイントロダクションを提供し、リアルタイムの 機能の概要も含まれています。 2章 リアルタイム動作は、割込み反応、プロセスディスパッチレイテンシィ、及び決定的プ ログラム実行を含むリアルタイム動作を達成するにあたっての事柄について論じます。シ ールドされた CPU モデルについて述べられています。 3章 リアルタイム・プロセス間通信、 POSIX 及び System V メッセージ引渡し、そして共 有メモリ機能について論じます。 4章 プロセス・スケジューリング 、 プロセス・スケジューリングの概要を提供し、そして、 POSIX®スケジューリング・ポリシー及びプライオリティについて述べます。 5章 プロセス間同期化、 共有リソースへのアクセスを同期化する共同プロセスにおける、 SUSE Linux Enterprise Real Time により与えられているインターフェイスについて述べま す。述べられていることは: POSIX カウンティング・セマフォ、System V セマフォ、再スケ ジューリング制御ツール、及び状態同期化ツールです。 6章 プログラマブルクロック及びタイマー、 SUSE Linux Enterprise Real Time 下で利用 可能な、RCIM 及び POSIX タイミング機能のいくつかの概要を提供します。 7章 システム・クロック及びタイマーは、CPU あたりのローカル・タイマー及びシステム・グ ローバル・タイマーについて述べます。 8章 ファイル・システム及び Disk IO は、SUSE Linux Enterprise Real Time オペレーテ ィング・システム上の直接ディスク IO の動作における、xfs ジャーナル・ファイル・システム 及び手順について説明します。 9章 メモリ・マッピングは、SUSE Linux Enterprise Real Time により与えられている、他のプロセスのアドレス空間の内容 へアクセスするプロセスに関する方法について述べます。 10章 非ユニフォームメモリアクセス( NUMA ) 、はある特定のシステムで利用可能な NUMA サポートについて述べます。 SUSE Linux Enterprise Real Time Linux User’s Guide パート2 -管理者 11 章、カーネルのコンフィグレーション及びビルディングは、SUSE Linux Enterprise Real Time のカーネルをどのようにコンフィグし、構築するかに関する情報を提供します。 12 章、プラグ可能な認証モジュール(PAM)は、SUSE Linux Enterprise Real Time の PAM 認証ケーパビリティについて述べます。 13 章、デバイス・ドライバは、SUSE Linux Enterprise Real Time の機能性、及びデバイ ス・ドライバを作るにあたってのリアルタイムの事項について述べます。 パート3 -共通資料 付録A、プログラム例 - メッセージキューは、POSIX 及び System V メッセージキュー機 能を説明するプログラム例を含みます。 付録B、SUSE Linux Enterprise Real Time の機能にチューニング可能なカーネルは、 SUSE Linux Enterprise Real Time のユニークな機能を制御するチューニング可能なカー ネルのリスト、及び、構築前のカーネルのそれらのデフォルト値を含みます。 付録C、SUSE Linux Enterprise Real Time の機能は、SUSE Linux Enterprise Real Time に含まれるケーパビリティ、及び、それぞれが互いに与える許可について列挙しま す。 付録D、カーネル・トレース・イベントは、ディフォルト定義のカーネル・トレース・ポイント、及 び、カーネル・モジュール内でカスタム・イベントを定義及びログする方法について、列挙し ます。 付録E、32ビットから64ビット・コードへの移行は、32 ビット CPU から64ビット CPU への 変移の処理に必要な情報を提供します。 付録F、CPU シールド下のカーネル・レベルのデーモンは、どのようにしてカーネル・レベ ルのデーモンがシールドされている CPU 上で実行するのかについて述べ、パフォーマンス を改良する方法を提供します。 付録G、CPU シールド下の CPU 間割り込みは、どのようにしてシールドされた CPU 上で CPU 間の割込みを実行するのかについて述べ、そして、パフォーマンスを改良する方法を 提供します。 付録H、シリアルコンソールセットアップ、がシリアルコンソールの構成を設定するために使 -i- SUSE Linux Enterprise Real Time Linux User’s Guide 用説明書を提供します。 付録 I 、ブートコマンドラインパラメータ、は SUSE Linux Enterprise Real Time に特有な GRUB ブートパラメータを論じます。 Glossally は、このガイドの中で使われている用語の定義を提供します。 索引は、キーワード、コンセプト、及びテキストの何ページにそれらがあるのかについての アルファベット順の参照です。 - ii - SUSE Linux Enterprise Real Time Linux User’s Guide シンタックス表記法 以下の表記法がこのマニュアルでは使用されています。 イタリック 書籍、参照カード、及びユーザが指定しなければならない アイテムはイタリックで表されます。特別な語もイタリックで表されます。 list bold ユーザの入力は list bold の文字で表されます。表示され ている通りに入力されなければなりません。ディレクトリ、ファイル、コマンド、オプションの 名前、及び man page 参照も list bold 文字で表されます。 list オペレーティング・システム、及び、プロンプト、メ ッセージ、そしてファイルのリストのようなプログラムの出力、及び、プログラムは、list タイ プで表されます。 [] コマンド・オプションやオプション的な引数は、ブラケットで 囲まれます。もしそれらのオプションや引数を指定しなければならない場合、ブラケットを入 力する必要はありません。 ハイパーテキスト・リンク このドキュメントをオンラインで見ている場合、章、セクショ ン、図、表、及びページ番号参照の上をクリックすると、対応したテキストが表示されます。 青文字のインターネット URL をクリックすると、ウェブ・ブラウザが起動し、ウェブ・サイトを 表示します。出版物名、及び赤文字の番号は、もしアクセス可能なら、対応するマニュアル PDF を表示します。 Concurrent Documentation Pub No. SUSE Linux Enterprise Real Time 10 Release Notes 0898206 SUSE Linux Enterprise Real Time FAQ N/A iHawk Optimization Guide 0898011 Partner Documentation Guide to SNARE for Linux - iii - N/A SUSE Linux Enterprise Real Time Linux User’s Guide 目次 1 概要....................................................................................................................... 1-1 概要.........................................................................................................................1-1 SUSE Linux Enterprise Real Timeカーネル .........................................................1-4 システム・アップデート ...............................................................................................1-5 リアルタイム機能 ......................................................................................................1-5 CPU・シールディング................................................................................................1-5 CPU結合.................................................................................................................1-5 ユーザ・レベル・プリエンプション制御 .........................................................................1-5 高速ブロック/ウェイクアップサービス .......................................................................1-6 FBS.........................................................................................................................1-6 /proc修正.................................................................................................................1-6 カーネル・トレース機能..............................................................................................1-6 ptrace拡張 ..............................................................................................................1-6 カーネル・プリエンプション .........................................................................................1-7 リアルタイム・スケジューラ ........................................................................................1-7 低待ち時間(Low Latency)向上................................................................................1-7 プライオリティ継承 ....................................................................................................1-7 高精度プロセス・アカウント........................................................................................1-8 ケーパビリティサポート..............................................................................................1-8 カーネル・デバッガ ....................................................................................................1-8 ユーザ・レベル・スピン・ロック ....................................................................................1-9 usermap及び/proc mmap .......................................................................................1-9 ハイパー・スレッディング .........................................................................................1-10 ファイル・システムのXFSジャーナル........................................................................1-10 POSIXリアルタイム拡張.........................................................................................1-10 ユーザ・プライオリティ・スケジューリング................................................................... 1-11 メモリ常駐プロセス.................................................................................................. 1-11 メモリ・マッピング及びデータ共有............................................................................. 1-11 プロセス同期化 ...................................................................................................... 1-11 非同期的入力/出力..............................................................................................1-12 同期化入力/出力 .................................................................................................1-12 リアルタイム・シグナル動作 .....................................................................................1-12 クロック及びタイマー ...............................................................................................1-13 メッセージキュー .....................................................................................................1-13 - iv - SUSE Linux Enterprise Real Time Linux User’s Guide 2 リアルタイム動作..................................................................................................... 2-1 シールドされているCPUモデルの概要 ......................................................................2-1 決定性の概要 ..........................................................................................................2-2 プロセスディスパッチレイテンシィ ...............................................................................2-3 割り込み禁止の効果.................................................................................................2-4 割り込みの効果........................................................................................................2-6 プリエンプションの禁止の効果...................................................................................2-9 オープン・ソース・デバイス・ドライバの効果...............................................................2-10 シールディングはどのようにしてリアルタイム動作を向上させるのか..........................2-10 バックグランド・プロセスのシールディング................................................................. 2-11 割り込みのシールディング ......................................................................................2-12 ローカル割り込みからのシールディング ...................................................................2-13 CPUシールディングへのインターフェイス.................................................................2-14 シールド・コマンド ....................................................................................................2-14 シールド・コマンドの例.............................................................................................2-15 終了ステータス .......................................................................................................2-16 シールド・コマンドの進歩した機能 ............................................................................2-16 CPUシールディングへの/procインターフェイス.........................................................2-16 CPUへのプロセスの割り当て..................................................................................2-17 mpadviseを使用してのマルチCPU・コントrole ........................................................2-19 initへのCPUバインドの割り当て ............................................................................2-22 シールドされているCPUのセット・アップの例............................................................2-23 決定性を向上させる手順 ........................................................................................2-26 メモリ内のページのロッキング .................................................................................2-26 プログラム・プライオリティの設定 .............................................................................2-27 遅延されている割込みプロセスのプライオリティの設定.............................................2-28 他のプロセスのウェイクアップ..................................................................................2-28 キャッシュアクセスの制御........................................................................................2-29 物理メモリの予約....................................................................................................2-29 NUMAシステム上での、ローカルメモリへのプログラム割付.....................................2-35 Quad Opteron システムの入出力スループット.......................................................2-36 ハイパー・スレッディングの理解 ...............................................................................2-37 システム・コンフィグレーション..................................................................................2-39 推奨CPUコンフィグレーション .................................................................................2-39 標準的なシールドされているCPUモデル .................................................................2-40 割り込みアイソレーションでのシールディング ...........................................................2-41 -v- SUSE Linux Enterprise Real Time Linux User’s Guide ハイパー・スレッドされているシールディング .............................................................2-42 浮動少数点/整数共有 ..........................................................................................2-43 共有データ・キャッシュ ............................................................................................2-43 シールドされた単一CPU.........................................................................................2-44 空きメモリが少ない状態を避ける .............................................................................2-44 Linuxの決定性の知られた事項..............................................................................2-44 3 リアルタイム・プロセス間通信 ................................................................................... 3-1 概要.........................................................................................................................3-1 POSIXメッセージキュー............................................................................................3-2 基本的概念 ..............................................................................................................3-2 高度な概念 ..............................................................................................................3-6 メッセージキューライブラリ・ルーチン..........................................................................3-6 メッセージキュー属性構造.........................................................................................3-7 ライブラリ・ルーチンの使用........................................................................................3-7 mq_openルーチン....................................................................................................3-8 mq_closeルーチン.................................................................................................. 3-11 mq_unlinkルーチン...............................................................................................3-13 mq_send及びmq_timedsendルーチン...................................................................3-13 mq_receive及びmq_timedreceiveルーチン ...........................................................3-16 mq_notifyルーチン ................................................................................................3-19 mq_setattrルーチン ..............................................................................................3-22 mq_getattrルーチン ..............................................................................................3-23 Ststem Vメッセージ................................................................................................3-23 メッセージの使用 ....................................................................................................3-24 msggetシステムコール ...........................................................................................3-28 msgctlシステムコール ............................................................................................3-30 msgsnd及びmsgrcvシステムコール .......................................................................3-32 メッセージを送信する ..............................................................................................3-32 メッセージを受信する ..............................................................................................3-33 POSIX共有メモリ ...................................................................................................3-34 shm_openルーチンの使用 .....................................................................................3-37 shm_unlinkルーチンの使用 ..................................................................................3-39 System V共有メモリ...............................................................................................3-40 共有メモリの使用....................................................................................................3-41 shmgetシステムコール...........................................................................................3-45 shmctlシステムコール............................................................................................3-48 - vi - SUSE Linux Enterprise Real Time Linux User’s Guide 共有メモリ・セグメントのIO空間への結び付け ..........................................................3-50 shmgetの使用 .......................................................................................................3-50 shmbindの使用.....................................................................................................3-50 shmat及びshmdtシステムコール ...........................................................................3-52 共有メモリ・セグメントの取り付け .............................................................................3-53 共有メモリ・セグメントの取り外し ..............................................................................3-53 共有メモリ・ユーティリティ ........................................................................................3-53 shmdefineユーティリティ ........................................................................................3-54 shmconfigコマンド .................................................................................................3-55 4 プロセス・スケジューリング ....................................................................................... 4-1 概要.........................................................................................................................4-1 プロセス・スケジューラはどのように動作するのか.......................................................4-2 スケジューリング・ポリシー ........................................................................................4-4 先入れ先出しスケジューリング(SCHED_FIFO).......................................................4-4 ラウンド・ロビン・スケジューリング (SCHED_RR).....................................................4-4 タイムシェアリングスケジューリング (SCHED_OTHER)..........................................4-5 動作における手順 ....................................................................................................4-5 プライオリティをどのように設定するか .......................................................................4-5 割り込みルーチン .....................................................................................................4-6 SCHED_FIFOとSCHED_RR .................................................................................4-6 CPUのロック・アップを処理する固定プライオリティ.....................................................4-7 メモリ・ロッキング ......................................................................................................4-7 CPUアフィニティ及びシールドされているCPU ...........................................................4-7 プロセス・スケジューリング・インターフェイス ..............................................................4-7 POSIXスケジューリング・ルーチン ............................................................................4-8 sched_setschedulerルーチン...................................................................................4-8 sched_getschedulerルーチン ................................................................................4-10 sched_setparamルーチン ...................................................................................... 4-11 sched_getparamルーチン......................................................................................4-12 sched_yieldルーチン .............................................................................................4-13 sched_get_priority_minルーチン..........................................................................4-13 sched_get_priority_maxルーチン .........................................................................4-14 sched_rr_get_intervalルーチン.............................................................................4-15 runコマンド ............................................................................................................4-16 プロセス/スレッド_指定子......................................................................................4-17 5 プロセス間同期化.................................................................................................... 5-1 - vii - SUSE Linux Enterprise Real Time Linux User’s Guide プロセス間同期化の理解 ..........................................................................................5-1 再スケジュール制御 .................................................................................................5-3 再スケジューリング変数の理解 .................................................................................5-4 resched_cntlシステムコールの使用..........................................................................5-5 再スケジューリング制御Macrosの使用 .....................................................................5-7 resched_lock...........................................................................................................5-7 resched_unlock ......................................................................................................5-8 再スケジューリング制御ツールの適用 .......................................................................5-9 ビジー待ち相互排他 .................................................................................................5-9 spin_mutex変数の理解.........................................................................................5-10 spin_mutexインターフェイスの使用 ........................................................................5-10 spin_mutexツールの適用......................................................................................5-12 nopreemtp_spin_mutex変数の理解 .....................................................................5-13 nopreempt_spin_mutexインターフェイスの使用 ....................................................5-14 POSIXカウンティング・セマフォ ...............................................................................5-17 概要.......................................................................................................................5-17 インターフェイス ......................................................................................................5-19 sem_initルーチン ..................................................................................................5-20 sem_detroyルーチン..............................................................................................5-21 sem_waitルーチン.................................................................................................5-22 sem_openルーチン ................................................................................................5-23 sem_closeルーチン ................................................................................................5-26 sem_unlink ルーチン ...........................................................................................5-26 sem_wait ルーチン ...............................................................................................5-27 sem_timedwait ルーチン......................................................................................5-27 sem_trywaitルーチン ............................................................................................5-28 sem_postルーチン .................................................................................................5-29 sem_getvalueルーチン ..........................................................................................5-29 System Vセマフォ ..................................................................................................5-30 POSIX Mutexes の拡張 .......................................................................................5-32 ロバストな Mutexes...............................................................................................5-33 プライオリティインヘリタンス ....................................................................................5-34 ユーザーインターフェース........................................................................................5-34 pthread_mutex_consistent_np ............................................................................5-35 pthread_mutex_getunlock_np.............................................................................5-36 pthread_mutex_setconsistency_np .....................................................................5-36 - viii - SUSE Linux Enterprise Real Time Linux User’s Guide pthread_mutex_setunlock_np .............................................................................5-37 pthread_mutexattr_getfast_np ...........................................................................5-37 pthread_mutexattr_getprotocol ..........................................................................5-37 pthread_mutexattr_getrobust_np.......................................................................5-38 pthread_mutexattr_getunlock_np ......................................................................5-38 pthread_mutexattr_setfast_np ...........................................................................5-38 pthread_mutexattr_setprotocol...........................................................................5-39 pthread_mutexattr_setrobust_np .......................................................................5-39 pthread_mutexattr_setunlock_np.......................................................................5-39 Alternative glibc ..................................................................................................5-40 System Vセマフォの使用 .......................................................................................5-41 semgetシステムコール ...........................................................................................5-43 semctlシステムコール ............................................................................................5-46 semopシステムコール ............................................................................................5-48 状態同期化 ............................................................................................................5-50 postwaitシステムコール.........................................................................................5-50 サーバ・システムコール...........................................................................................5-52 server_block .........................................................................................................5-53 server_wake1 .......................................................................................................5-54 server_wakevec....................................................................................................5-55 コンディション同期化ツールの適用 ..........................................................................5-57 6 プログラム可能なクロック及びタイマー ...................................................................... 6-1 クロック及びタイマーの理解 ......................................................................................6-1 RCIMクロック及びタイマー .......................................................................................6-1 POSIXクロック及びタイマー......................................................................................6-2 POSIX時間構造の理解 ...........................................................................................6-4 POSIXクロック・ルーチンの使用 ...............................................................................6-5 clock_settimeルーチンの使用..................................................................................6-5 clock_gettimeルーチンの使用 .................................................................................6-6 clock_getresルーチンの使用....................................................................................6-7 POSIXタイマー・ルーチンの使用...............................................................................6-7 timer_createルーチンの使用...................................................................................6-8 timer_deleteルーチンの使用 .................................................................................6-10 timer_settimeルーチンの使用............................................................................... 6-11 timer_gettimeルーチンの使用 ..............................................................................6-13 timer_getoverrunルーチンの使用.........................................................................6-14 - ix - SUSE Linux Enterprise Real Time Linux User’s Guide POSIXスリープ・ルーチンの使用 ............................................................................6-15 nanospeepルーチンの使用 ....................................................................................6-15 clock_nanosleepルーチンの使用 ...........................................................................6-16 POSIXタイマーへの/procインターフェイス ...............................................................6-17 7 システム・クロック及びタイマー ................................................................................. 7-1 ローカル・タイマー .....................................................................................................7-1 機能性 .....................................................................................................................7-1 CPUアカウンティング ...............................................................................................7-2 プロセス実行時間クワンタム及び制限 .......................................................................7-2 インターバルタイマー減少 .........................................................................................7-3 システム・プロファイリング .........................................................................................7-3 CPUロード・バランス.................................................................................................7-3 CPU再スケジューリング ...........................................................................................7-4 POSIXタイマー ........................................................................................................7-4 その他 .....................................................................................................................7-4 ローカル・タイマーのディセーブリング.........................................................................7-5 グローバル・タイマー .................................................................................................7-5 8 ファイル・システム及びディスクIO ............................................................................. 8-1 ファイル・システムのジャーナル .................................................................................8-1 XFSファイル・システムの生成 ...................................................................................8-2 XFSファイル・システムのマウンティング.....................................................................8-2 データ・マネージメントAPI(DMAPI).........................................................................8-3 直接ディスクIO.........................................................................................................8-3 9 メモリ・マッピング ..................................................................................................... 9-1 ターゲット・プロセスのアドレス空間へのマッピングの確立 ...........................................9-1 mmap (2)の使用 .....................................................................................................9-1 usermap (3)の使用 .................................................................................................9-3 備考.........................................................................................................................9-4 カーネル・コンフィグレーション・パラメータ...................................................................9-5 10 Non-Uniform Memory Access (NUMA)............................................................ 10-1 メモリポリシー.........................................................................................................10-2 NUMA User Interface .........................................................................................10-3 run(1) コマンドを使用した場合のNUMA サポート .................................................10-4 shmconfig(1)を使ったシェアードメモリエリアに対する NUMA サポート..................10-6 システムコール .......................................................................................................10-8 ライブラリ関数 ........................................................................................................10-8 -x- SUSE Linux Enterprise Real Time Linux User’s Guide 情報ファイル...........................................................................................................10-8 numastat を使っている NUMA Hit/Miss 統計値................................................10-9 kdbサポート .........................................................................................................10-10 パフォーマンスガイドライン ....................................................................................10-10 タスク間のNUMAメモリポリシー ...........................................................................10-10 共有メモリセグメント.............................................................................................. 10-11 コンフィグレーション ..............................................................................................10-12 11 カーネルのコンフィグレーション及び構築..................................................................11-1 イントロダクション.................................................................................................... 11-1 ccur-configを使用してのカーネルのコンフィグレーション .......................................... 11-2 カーネルの構築 ...................................................................................................... 11-5 ドライバ・モジュールの構築 ..................................................................................... 11-7 追加情報................................................................................................................ 11-8 12 プラグ可能な認証モジュール (PAM) .................................................................... 12-1 イントロダクション....................................................................................................12-1 PAMモジュール .....................................................................................................12-1 サービス.................................................................................................................12-2 role・ベースのアクセス制御.....................................................................................12-2 例 ..........................................................................................................................12-3 ケーパビリティの定義..............................................................................................12-4 例 ..........................................................................................................................12-5 実行の詳細 ............................................................................................................12-6 13 デバイス・ドライバ.................................................................................................. 13-1 デバイス・ドライバの種類の理解..............................................................................13-1 ユーザ・レベル・デバイス・ドライバの開発 ................................................................13-1 PCIリソースへのアクセス........................................................................................13-1 PCI BARスキャン・インターフェイス ........................................................................13-3 bar_scan_open (3) ................................................................................................13-4 bar_scan_next (3).................................................................................................13-4 bar_device_count (3) ............................................................................................13-5 bar_scan_rewind (3) ............................................................................................13-5 bar_scan_close (3) ................................................................................................13-6 free_pci_device (3)................................................................................................13-6 カーネル・スケルトン・ドライバ..................................................................................13-7 サンプル・ドライバ機能性の理解 .............................................................................13-7 ドライバの評価 .....................................................................................................13-10 - xi - SUSE Linux Enterprise Real Time Linux User’s Guide カーネル・レベル・デバイス・ドライバの開発 ...........................................................13-12 ドライバ・モジュールの構築 ...................................................................................13-12 カーネル・バーチャル・アドレス空間 .......................................................................13-13 リアルタイム・パフォーマンス事項 ..........................................................................13-13 割り込みルーチン .................................................................................................13-13 遅延されている割り込み機能 (ボトムハーフ)........................................................13-14 Softirqs及びTasklets ..........................................................................................13-15 workキュー..........................................................................................................13-16 プライオリティの理解.............................................................................................13-17 マルチスレッディング事項......................................................................................13-17 ビッグ・カーネル・ロック(BKL)及びioctl ................................................................13-17 パフォーマンス分析 ..............................................................................................13-18 A プログラム例 – メッセージキュー .............................................................................A-1 POSIXメッセージキュー例 ....................................................................................... A-1 System Vメッセージキュー例................................................................................... A-3 B Real Timeカーネルチューニング................................................................................B-1 Cケーパビリティ ............................................................................................................C-1 概要........................................................................................................................ C-1 ケーパビリティ ......................................................................................................... C-1 D カーネル・トレース・イベント........................................................................................D-1 ディフォルト定義カーネル・トレース・イベント .............................................................. D-1 ユーザ定義のカーネル・トレース・イベント.................................................................. D-4 ディフォルト定義のCUSTOMトレース・イベント ......................................................... D-4 動的カーネル・トレーシング ...................................................................................... D-4 trace_create_event................................................................................................ D-5 trace_destroy_event.............................................................................................. D-5 TRACE_EVENT ................................................................................................... D-6 E 32 ビット・コードから 64 ビット・コードへの変換 .............................................................E-1 イントロダクション..................................................................................................... E-1 手順........................................................................................................................ E-3 コーディング要求 ..................................................................................................... E-3 データ・タイプ・サイズ ............................................................................................... E-3 Long....................................................................................................................... E-4 ポインタ................................................................................................................... E-4 配列........................................................................................................................ E-4 宣言........................................................................................................................ E-5 - xii - SUSE Linux Enterprise Real Time Linux User’s Guide 明確なデータ・サイズ ............................................................................................... E-5 定数........................................................................................................................ E-5 API ........................................................................................................................ E-5 呼び出し手続き ....................................................................................................... E-5 条件的コンパイル .................................................................................................... E-6 その他 .................................................................................................................... E-7 コンパイル............................................................................................................... E-7 評価/デバッグ.......................................................................................................... E-7 パフォーマンス事項 ................................................................................................. E-7 メモリ整列及び構造パディング ................................................................................. E-7 FシールドされているCPU上のカーネル・レベル・デーモン ............................................... F-1 G シールドされているCPU上のCPU間割り込み............................................................G-1 概要........................................................................................................................ G-1 メモリ・タイプ領域レジスタ(MTRR)割り込み............................................................. G-1 グラフィック割り込み................................................................................................. G-3 カーネルTLBフラッシュ割り込み .............................................................................. G-5 ユーザ・アドレス空間TLBフラッシュ割り込み ............................................................ G-7 H シリアルコンソールセットアップ ................................................................................. H-1 I ブートコマンドラインパラメータ ..................................................................................... I-1 用語解説..................................................................................................... GLOSSALY-1 結合 (affinity) ...................................................................................... GLOSSALY-1 非同期セーフ...........................................................................................GLOSSALY-1 アトミック .................................................................................................GLOSSALY-1 認証........................................................................................................GLOSSALY-1 メッセージ・オペレーションのブロッキング ..................................................GLOSSALY-1 セマフォ・オペレーションのブロッキング.....................................................GLOSSALY-1 ブレイク・ポイント .....................................................................................GLOSSALY-2 ビジー待ち ..............................................................................................GLOSSALY-2 機能........................................................................................................GLOSSALY-2 状態同期化 .............................................................................................GLOSSALY-2 コンテキスト・スイッチ ...............................................................................GLOSSALY-2 クリティカルセクション...............................................................................GLOSSALY-2 デッドロック..............................................................................................GLOSSALY-2 遅延されている割り込み扱い ...................................................................GLOSSALY-3 決定性 ....................................................................................................GLOSSALY-3 決定的システム .......................................................................................GLOSSALY-3 - xiii - SUSE Linux Enterprise Real Time Linux User’s Guide デバイス・ドライバ ....................................................................................GLOSSALY-3 直接IO ...................................................................................................GLOSSALY-3 任意のアクセス制御 ................................................................................GLOSSALY-3 実行時間.................................................................................................GLOSSALY-4 FBS........................................................................................................GLOSSALY-4 固定されているプライオリティ・スケジューリング・ポリシー..........................GLOSSALY-4 フレーバ ..................................................................................................GLOSSALY-4 Frequency-Based Scheduler (FBS) ......................................................GLOSSALY-4 GRUB ....................................................................................................GLOSSALY-5 ハイパー・スレッディング ..........................................................................GLOSSALY-5 infoページ...............................................................................................GLOSSALY-5 プロセス間通信(IPC) .............................................................................GLOSSALY-5 プロセス間同期化....................................................................................GLOSSALY-5 ジッター...................................................................................................GLOSSALY-5 ファイル・システムのジャーナル ................................................................GLOSSALY-6 カーネル..................................................................................................GLOSSALY-6 カーネル・コンフィグレーションGUI ...........................................................GLOSSALY-6 ロード・バランス .......................................................................................GLOSSALY-6 man page...............................................................................................GLOSSALY-6 メモリ・オブジェクト ...................................................................................GLOSSALY-7 メッセージキュー ......................................................................................GLOSSALY-7 モジュール...............................................................................................GLOSSALY-7 相互排他.................................................................................................GLOSSALY-7 NightProbe............................................................................................GLOSSALY-7 NightSim RT.........................................................................................GLOSSALY-7 NightStar RTツール ..............................................................................GLOSSALY-8 NightTrace RT ......................................................................................GLOSSALY-8 NightView RT .......................................................................................GLOSSALY-8 非ブロッキング・メッセージ・オペレーション ................................................GLOSSALY-8 非ブロッキング信号オペレーション............................................................GLOSSALY-8 PAM.......................................................................................................GLOSSALY-8 PCI ........................................................................................................GLOSSALY-9 パフォーマンス・モニター(PM).................................................................GLOSSALY-9 プラグ可能な認証モジュール(PAM) ........................................................GLOSSALY-9 POSIX ...................................................................................................GLOSSALY-9 プリエンプション .......................................................................................GLOSSALY-9 - xiv - SUSE Linux Enterprise Real Time Linux User’s Guide プライオリティ継承 ...................................................................................GLOSSALY-9 プライオリティ反転 ...................................................................................GLOSSALY-9 権限......................................................................................................GLOSSALY-10 プロセス ................................................................................................GLOSSALY-10 プロセスディスパッチレイテンシィ ............................................................GLOSSALY-10 RCIM ...................................................................................................GLOSSALY-10 リアルタイム ..........................................................................................GLOSSALY-10 再スケジューリング変数 .........................................................................GLOSSALY-10 RPM.....................................................................................................GLOSSALY-10 セマフォ.................................................................................................GLOSSALY-11 共有メモリ .............................................................................................GLOSSALY-11 シールドされているCPU ........................................................................GLOSSALY-11 シールドされているCPUモデル ..............................................................GLOSSALY-11 シールドされているCPU ........................................................................GLOSSALY-11 スリープ待ち..........................................................................................GLOSSALY-12 SMP.....................................................................................................GLOSSALY-12 softirq ..................................................................................................GLOSSALY-12 スピン・ロック .........................................................................................GLOSSALY-12 System V .............................................................................................GLOSSALY-12 tasklet .................................................................................................GLOSSALY-12 トレース・イベント ...................................................................................GLOSSALY-12 workキュー...........................................................................................GLOSSALY-13 - xv - SUSE Linux Enterprise Real Time Linux User’s Guide 1 概要 この章では、SUSE Linux Enterprise Real Time の紹介、及びリアルタイム機能に ついての概要を示します。 メモ この SUSE Linux Enterprise Real Time ガイドの情報は、SUSE Linux と SUSE Linux Enterprise Server 両方に当てはまります。 概要 Concurrent Computer Corporation の SUSE Linux Enterprise Real Time は、オ ープン・ソース Linux®オペレーティング・システムのリアルタイム・バージョンです。 標準的 Linux バージョン 2.6 への修正がなされ、複雑でタイム・クリティカルなアプリ ケーションが要求する機能及びパフォーマンスをサポートします。SUSE Linux Enterprise Real Time は単一カーネル・デザインを使用して、全てのシステム・オペ レーションを直接に制御する単一プログラミング環境をサポートします。このデザイ ンは決定的プログラムの実行を可能にし、また、高 IO スループット、決定的ファイル、 ネットワーキング、及びグラフィック IO オペレーションを同時に提供しながら、割り込 みへの応答も可能にします。SUSE Linux Enterprise Real Time は、シミュレーショ ン、データ収録、産業制御及び医療イメージ・システムにおける決定的アプリケーシ ョンにおいて、理想的な Linux 環境を提供します。 SUSE Linux Enterprise Real Time は人気が高い SUSE Linux Enterprise サー バー10ディストリビューションのオプションプロダクトです。 プロダクトは付加された カーネル機能にアクセスするために追加のリアルタイムカーネルとライブラリを提供 します。 オプションとして、 NightStar RT 開発ツールセットはタイムクリティカルの アプリケーションを開発することに即応できます。 SUSE Linux Enterprise Real Time カーネルはオープン・ソース・パッチ、及び Concurrent が開発した最先端のリアルタイム・カーネルを統合します。これらの機 能の多くは、Concurrent が35年間にわたってリアル・タイム・オペレーティング・シ ステムの開発の経験においてサポートしてきたリアルタイム UNIX®実行から生ま れたものです。これらの機能は、この章の後の“SUSE Linux Enterprise Real Time のリアルタイム機能”のセクションで少し触れられ、また更に詳細な情報への 参照もあります。 1-1 SUSE Linux Enterprise Real Time Linux User’s Guide SUSE Linux Enterprise Real Time は、Intel®、Xeon™及び AMD Opteron™ベー スのプラットフォーム上で使用可能です。対称並列 CPU へのサポートは、高度に最 適化されています。シールドされている CPU として知られるユニークなコンセプトは、 CPU のサブセットが最も決定的なパフォーマンスに専心することを可能にします。 個々の CPU は、割込み処理、カーネル・デーモン、ボトムハーフ割込み、及び他の Linux のタスクからシールドすることができます。CPU・シールディングは、高度な決 定的実行環境を提供し、そこでは 30 マイクロ秒以下の割込み応答が保証されてい ます。 Linux は、POSIX で定義されているインターフェイス標準の多くに適応しますが、こ れらの標準に完全には適応しません。SUSE Linux Enterprise Real Time は、2.6 シリーズのカーネルに基づいている他の Linux ディストリビューションと少なくとも同 様の POSIX 適応性を持ちます。インテル x86 アーキテクチャに関する Linux は Linux / インテル x86 プラットホーム上で走るよう設計されるシュリンクラップされ たアプリケーションが SUSE Linux Enterprise Real Time をサポートしてプラット ホームの上に変更なしで走ることを可能にするそれ自身の デファクトバイナリスタ ンダードを定義しました。 NightStarRT は、非侵入的制御、モニタ、分析、及びタイム・クリティカルな並列処 理アプリケーションにおいて、頑強なグラフィック・インターフェイスを提供する強力 なツール・セットです。SUSE Linux Enterprise Real Time カーネルは、これらのツ ールがアプリケーションの実行への最小の干渉で効率的にそれらのオペレーション を動作させることを可能にします。全てのツールは同じシステム上で、アプリケーシ ョンとして、またはリモート的にはより侵入が少ないアプリケーション制御において、 本来的に稼動されます。 NightStarRT ツールは以下のものを含みます。完全な情報については、それぞれ のユーザのガイドを参照してください。 ・ NightView™RT ソース・レベル・デバッガは――単一グラフィカル・インターフェ イスからの複数言語、マルチ CPU、複数プログラム、そして複数スレッド・モニ ターリング、及びデバッグを可能にします。NightView は、完全なアプリケーショ ン・スピードで実行を修正する、データを回収または修正するプログラム、そして 条件的ブレイク・ポイント、モニタ・ポイント、及びワッチ・ポイントをインサートす るプログラムを走らせるパッチを動作させる機能を持ちます。 1-2 SUSE Linux Enterprise Real Time Linux User’s Guide ・ NightTrace™RT ラン・タイム・アナライザは――走っているアプリケーションの 動的状態を分析するのに使用されます。ユーザ及びシステム活動は、高解像 度のタイムスタンプでログされ、そしてマークされます。これらのイベントは、アプ リケーションが走っている間に起こるシステム活動の詳細なビューを提供する ために、グラフィカルに表示されます。NightTrace は、マルチ・プロセス、マル チ・CPU 上の動作、分散されたシステム及びユーザ/カーネル相互作用上で 実行されるアプリケーション間の相互作用をビューするのに理想的です。その 強力な機能によって、特定のイベントの検索、またはカーネルまたはユーザ状 態の要約をすることが可能です。 ・ NightSim™RT 周期的スケジューラは――周期的実行を必要とするアプリケー ションをユーザが簡単にスケジュールすることを可能にします。開発者は動的 に、複数的に対応されたプロセス、それらのプライオリティ、及び CPU 割当てを 制御することができます。NightSim は、詳細な、高度に正確なパフォーマンス 統計を提供し、そして、フレーム・オーバーランが起こった時、様々なアクションを 可能にします。 ・ NightProbe™RT データ・モニタは――複数的に走っているプログラムの中で プログラム・データのサンプル、記録、または修正をするのに使用されます。プロ グラム・データはシンボル・テーブル・ブラウザで位置付けされます。アプリケー ション・ページは、アプリケーションの実行への影響を最小にするために、物理ペ ージ・レベルで共有されます。NightProbe は、デバッグ、分析、誤り検出または、 プログラム入力及び出力における GUI 制御パネルを生成するための生産環境 内で、使用されます。 ・ NightTune™ RT パフォーマンスチューナーは-CPU 利用率、コンテキストス イッチ、割り込み、バーチャルメモリ使用法、ネットワーク活動、 プロセス属性と CPU シールディング とアプリケーションパフォーマンスを分析するためのグラ フィックツールです。 NightTune RT はあなたに個人あるいはポップアップダイ アログを使っているプロセスあるいはドラッグ&ドロップでグループのプライオリ ティ、スケジューリングポリシーと CPU 割付を変えることを許します。 それは同 じくあなたに CPU シールドしている hyper-threading の特質を設定して、そし て個別の割り込みの CPU 割り当てを変えることができます。 1-3 SUSE Linux Enterprise Real Time Linux User’s Guide SUSE Linux Enterprise Real Time カーネル SUSE Linux Enterprise Real Time カーネルには3つの版があります。システム管理者は GRUB ブート・ローダ経由で SUSE Linux Enterprise Real Time カーネルのどのバージョン をロードするのかを選択することができます。 Kernel Type<=4GB Generic Trace Debug Kernel Name vmlinuz-kernelversion-SL ERT-x.x vmlinuz-kernelversion-SL ERT-x.x-trace vmlinuz-kernelversion-S LERT-x.x-debug Recommended Use Running time-critical Using NightStar RT tools Developing new applications to evaluate performance applications or drivers Description The generic kernel is the most optimized and will provide the best overall performance, however it lacks certain features required to take full advantage of the NightStar RT tools. The trace kernel is recommended for most users as it supports all of the features of the generic kernel and in addition provides support for the kernel tracing feature of the NightTrace RT performance analysis tool. This kernel is loaded at system boot by default. The debug kernel supports all of the features of the trace kernel and in addition provides support for kernel-level debugging. This kernel is recommended for users who are developing drivers or trying to debug system problems. Kernel Type > 4 GB Kernel Name * Bigmem vmlinuz-kernelversion-SL ERTx-x-bigmem Running time-critical applications The bigmem kernel is the most optimized > 4GB i386 kernel and will provide the best overall performance, however it lacks certain features required to take full advantage of the NightStar RT tools. Trace_Bigmem vmlinuz-kernelversion-SL ERTx-x-trace_bigmem Using NightStar RT tools to evaluate performance The trace_bigmem kernel is recommended for most > 4 GB kernel users as it supports all of the features of the bigmem kernel and provides support for the kernel tracing feature of the NightTrace RT performance analysis tool. Debug_Bigmem vmlinuz-kernelversion-S LERTx-x-debug_bigmem Developing new applications or drivers The debug_bigmem kernel supports all of the features of the trace_bigmem kernel and provides support for kernellevel debugging. This kernel is recommended for developing drivers or trying to debug system problems. Recommended Use Description Features Kernel Debuggers disabled disabled kdb and kgdb enabled Kernel Tracing (used disabled enabled enabled by NightTrace RT) High Resolution disabled enabled enabled Process Accounting NMI Watchdog disabled disabled enabled Frequency Based enabled when module is enabled when module is enabled when module is Scheduler (FBS) loaded loaded loaded Performance Monitor disabled enabled enabled (PM) * kernelversion is the official version of Linux kernel source code upon which the kernel is based. x-x indicates the version number. Example: vmlinuz-2.6.16.21-0.8-SLERT-10-8. 1-4 SUSE Linux Enterprise Real Time Linux User’s Guide システム・アップデート アップデートが発行されるとき、 YaST Online Update を使って SUSE の FTP サイトから ダ ウ ン ロ ー ド で き る さ れ る で し ょ う 。 こ れ を す る こ と に 対 し て の 指 示 は SUSE Linux Enterprise Real Time が含んでいる SUSE Linux Enterprise Server のドキュメンテーショ ンに見いだすことができます。 リアルタイム機能 このセクションでは、リアルタイム処理、及びパフォーマンスにおいて、オペレーティング・シス テムに含まれている機能の簡潔な説明を提供します。以下で説明されている機能性につい てのさらに詳細な情報は、このガイドの後の章で提供されます。オンラインで読まれている方 は参照されている章をクリックすれば即、情報を表示させることができます。 CPU・シールディング 割込み及びシステム・デーモンと関連する予期できないプロセスから選択された CPU をシー ルドする方法を開発してきました。決定的でプライオリティの高いタスクを特定の CPU へ連結 し、そしてほとんどの割込み及びシステム・デーモンを他の CPU へと向かわせることによって、 マルチ・CPU・システム内でのある特定の CPU 上で可能な最良のプロセスディスパッチレイ テンシィを得ることができます。2 章では CPU をシールドするモデルを提示し、そして応答時 間の向上、及び決定性を増大するテクニックについて述べます。 CPU 結合 マルチ CPU 上で複数プロセスが実行されているリアルタイム・アプリケーション内では、シス テム内の全てのプロセスの CPU 割当てを超えた明確な制御を持つことが望ましいことです。 この機能は、mpadvise (3)ライブラリ・ルーチン及び run (1)コマンドを通して、Concurrent が 提供しています。更なる情報については、2章及び man page を見てください。 ユーザ・レベル・プリエンプション制御 複数の CPU 上で走ることのできる複数プロセスをアプリケーションが持ち、そしてそれらのプ ロセスがそれらの間で共有されたデータ上に動作するなら、1 つ以上のプロセスからの同時 アクセスによる破壊を防ぐために、共有データへのアクセスはプロテクトされるべきです。共 有データをプロテクトする最も効率的なメカニズムは、スピン・ロックです。しかし、もしスピン・ ロックを保持しながらアプリケーションがプリエンプトされる可能性があるならば、スピン・ロッ クは、アプリケーションにとって効率的ではありません。効率的であるために、SUSE Linux Enterprise Real Time はアプリケーションが高速にプリエンプションを禁止することができるメ カニズムを提供します。ユーザ・レベル・プリエンプションについての更なる情報については、 5章及び resched_cntl (2)man page を見てください。 1-5 SUSE Linux Enterprise Real Time Linux User’s Guide 高速ブロック/ウェイクアップサービス 多くのリアルタイム・アプリケーションは、複数共同プロセスから構成されています。これらの アプリケーションは、内的プロセス同期化を行うことにおいて、効率的な方法を必要とします。 高速ブロック/ウェイクアップサービスによって、プロセスは高速にそれ自身を一時停止させ、 他の共同プロセスからのウェイクアップ通知を待つことができます。更なる詳細については、 2章及び、5章、そして postwait (2)及び server_block (2) の man page を見てください。 FBS FBS は、一定の周期的パターンに沿って走るスケジュール・アプリケーションのために SUSE Linux Enterprise Real Time に付加されたメカニズムです。FBS はさらに、そのプロセスが実 行される時間になればそのプロセスを呼び出す、とても速いメカニズムも提供します。さらに、 周期的アプリケーションのパフォーマンスは、デッドラインになっていなければプログラマが利 用可能な様々なオプションで、追跡することができます。FBS は、周期的アプリケーションの スケジュールにおいて、NightSim™ GUI を利用するカーネル・メカニズムです。追加的情報 については、Frequency-Based Scheduler (FBS) Use’s Guide 及び NightSim User’s Guide を見てください。 /proc 修正 特権的プロセスが他のプロセスのアドレス空間内の値をリードするまたは、ライトすることを可 能にするために、/proc の中のプロセス・アドレス空間サポートに、修正を施しました。これは、 NihgtProbe™ データ・モニター・ツール及び NightView™デバッガのサポートのためです。 カーネル・トレース機能 カーネルの活動を追跡するために、SUSE Linux Enterprise Real Time に機能が付加されて います。これは、カーネル・トレース・ポイントを挿入及び許可する、カーネルからトレース・メモ リ・バッファをリードする、そして、トレース・バッファをマネージするメカニズムを含みます。 ptrace 拡張 Linux の ptrace デバッグ・インターフェイスは、NightView デバッガの機能をサポートするため に拡張されました。付加された機能は以下のものです。 z デバッガ・プロセスが、現在停止していない状態のプロセスの中でメモリをリードし、 ライトする機能 z デバッガが、デバッグされているプロセスの中でシグナルのサブセットのみをトレー スする機能 z 1-6 デバッガが、デバッグされているプロセス内での新しいアドレスで効率的に実行を再 SUSE Linux Enterprise Real Time Linux User’s Guide 開する機能 z デバッガ・プロセスが、デバッグされているプロセスの全ての子プロセスに自動的に 付与する機能 カーネル・プリエンプション カーネル内では、高プライオリティ・プロセスが現在実行している低プライオリティ/プロセスを プリエンプトする機能が提供されています。標準的 Linux 下では、低プライオリティ・プロセス はカーネルから出るまで走りつづけ、長い最悪のケースのプロセスディスパッチレイテンシィ を生み出します。対称並列プロセスをサポートするデータ構造プロテクション・メカニズムが、 カーネルの中に構築されています。 リアルタイム・スケジューラ リアルタイム・スケジューラは、システム内でいくつのプロセスがアクティブであるかに関わら ず、時間が一定のコンテキスト・スイッチを提供します。それは対称並列 CPU 上で動作する 本当のリアルタイム・スケジュール・クラスを提供します。 低待ち時間(Low Latency)向上 カーネルが使用している共有データ構造をプロテクトするために、スピン・ロック及びセマフォ でそれらの共有されたデータ構造にアクセスするコード・パスを、カーネルはプロテクトします。 スピン・ロックのロッキングは、スピン・ロックが保持されている間に、プリエンプション、そして 時には割り込みが禁止される必要があります。最悪のケースのプリエンプションを時間から 離して識別する研究が行われました。低待ち時間向上は、最悪のプリエンプション停止のシ ナリオの中で、よりよい割り込み応答時間を提供するように、アルゴリズムを修正しました。 プライオリティ継承 スリープ待ちの相互排他メカニズムとして使用されているセマフォは、プライオリティ反転を生 み出すことがあります。プライオリティ反転は、1 つかそれ以上の低プライオリティ・プロセス実 行が、決定的なセクションで 1 つまたはそれ以上の高プライオリティ・プロセスの進行を止まら せる時に起こります。プライオリティ継承は、クリティカル・セクションでの低プライオリティ・プ ロセスの実行を一時的に、最高プライオリティ待ちプロセスへと上げることを伴います。これ は、クリティカル・セクションで実行しているプロセスが、クリティカル・セクションから離れるまで 実行を続けるのに充分なプライオリティを持つことを確実にします。 この機能はデフォルトで、それぞれの構成のカーネルの中へコンフィグされています。それ はどのシステム上でも禁止することができます。個々のシステムが非決定的タスクのみを扱 い、そしてプライオリティ継承と関連しているどのオーバーヘッドも必要でない時に、これは望 ましいものです。プライオリティ継承で使用されているチューニング可能カーネルについては、 1-7 SUSE Linux Enterprise Real Time Linux User’s Guide 付録Bを参照してください。 マルチスレッドのアプリケーションの中では、プライオリティ継承を提供する pthread mutexes に対する代わりの関数が glibc に含められます。 詳細についてはチャプター5を参照してください 高精度プロセス・アカウント 標準的 Linux カーネルでは、とても粗雑なメカニズムを使用してプロセスの実行時間をアカウ ントします。これは、ある特定のプロセスに課されている CPU の時間量がとても不正確になる ことを意味します。高精度プロセス・アカウント機能は、とても正確な CPU 実行時間アカウント のためのメカニズムを提供し、アプリケーションのよりよいパフォーマンス・モニターリングを可 能にします。この機能は、“デバッグ”及び“トレース”カーネルの中に組み込まれており、これ らのカーネル上の標準的 Linux CPU アカウント・サービス及びパフォーマンス・モニタにおい て使用されています。CPU アカウント方法に関する情報については、7章を見てください。 ケーパビリティサポート プラグ可能な認証モジュールは(PAM)、ユーザに権限を割り当てるメカニズムを提供し、そし て認証プログラムを再コンパイルする必要無く認証ポリシーを設定します。この方法では、通 常、root のみに許される権限を要求するアプリケーションを走らせることができるように、root で無いユーザがコンフィグされます。例として、メモリ内のページをロックする機能は、個々の ユーザまたはグループに割り当てられるディフォルト定義の権限が提供します。 権限は、コンフィグレーション・ファイル内で定義されている role を通して許可されます。定義さ れた role は、次に続く role の中で、新しい role が既に定義されている role の機能を継承して ビルディング・ブロックとして使用されます。role はユーザ及びグループに割り当てられ、シス テム上のそれらのケーパビリティを定義します。PAM ケーパビリティに関する詳細は、12 章 を見てください。 カーネル・デバッガ 2つのオープン・ソース・カーネル・デバッガ、kdb 及び kgdb がサポートされています。 kdb はデフォルトデバッガです。 kdb を使うことについての情報はカーネルソースディレクト リの/kdb の下に存在します。 USB キーボードでシステムで kdb を使うためには、シリア ルコンソールが構成されなくてはならないことに注意を払ってください。 シリアルコンソールを 準備する方法は付録Hに記述されています。kgdb は、まるでそれがユーザ・アプリケーション であるかのように、カーネルが gdb でデバッグすることを可能にします。gdb は別々のシステ ム上で走り、vmlinux ファイル及びマッチング・ソースのコピーを含み、そして、コンソールのシ リアル・ポートを通してデバッグされているカーネルで通信します。kgdb についての更なる情 報は、info ページ、 /kernel-source/Documentation/i386/kgdb に印字可能なマニュアルが 1-8 SUSE Linux Enterprise Real Time Linux User’s Guide あります。 これらのシステムで kdb の代わりに kgdb をアクティブなデバッガとして明示するための方 法を示します。 - ブートにおいて gdb オプションを指定します。 - kgdb シリアルポートに接続する gdb vmlinux コマンドを指定します。 - Alt+SysRq+Gのキーの組み合わせを使ってください。 若干の修正が x86_64 システムでの使用のために gdb にされていることに注意してくださ い: - スタックが一貫した方向に増大したと思うスタックバックトレースのエラーチェックを防ぐ修 正がなされました。 x86_64 カーネルは、標準的なプロセススタックのほかに、割り込みスタックを使うので、こ のオプションをセットすることは、割り込みからプロセススタックまで後方にトレースするとき、 このエラーチェックを引き起こします。 コマンドで、以下のオプションをセットしてください。 gdb> set backtrace switch-stacks on - もう1つの修正は、指定される機能のリストを許します。 「info thread」コマンドで表示するフレームを選ぶとき、スキップしてください。 コマンドで:以 下のオプションをセットしてください。 gdb> set skip-frame thread_return,schedule_timeout ユーザ・レベル・スピン・ロック SUSE Linux Enterprise Real Time のビジー待ち相互排他ツールは、低オーバーヘッドのビ ジー待ち相互排他変数(スピン・ロック)及び対応する macros のセットを含み、それはスピン・ ロックの初期化、ロック、アンロック、問合せを可能にします。効率的にするために、ユーザ・レ ベル・スピン・ロックは、ユーザ・レベル・プリエンプション制御と共に使用されなければなりま せん。詳細については、5章を見てください。 usermap 及び/proc mmap libccur_rt ライブラリ内に常駐する usermap(3)ライブラリ・ルーチンは、単純な CPU のリー ド及びライトの使用を通して現在実行しているプログラム内で効率的に位置のモニターリング 及び修正をする方法でアプリケーションを提供します。 /proc ファイル・システム mmap (2)は、usermap (3)において基になるカーネル・サポートで す。それは、他のプロセスのアドレス空間のプロセス・マップ部分をそれ自身のアドレス空間 へ入れます。よって、他の実行プログラムのモニタ-リング及び修正は、アプリケーションそ れ自身のアドレス空間内での単純な CPU のリード及びライトになり、proc ファイル・システム の read (2)及び write (2)システム・サービス呼び出しを招くことはありません。更なる情報に ついては、9章を見てください。 1-9 SUSE Linux Enterprise Real Time Linux User’s Guide ハイパー・スレッディング ハイパー・スレッディングは、Intel Pentium Xeon CPU の機能です。それは、単一の物理 CPU が2つの論理 CPU のオペレーティング・システムのように現れることを可能にします。そ れぞれの CPU チップ内で2つのプログラム・カウンタが同時に走り、結果として、それぞれの チップは、デュアル CPU の SMP に見えます。キャッシュ・ミスまたは特別インストラクションで、 2つのレジスタ間の速いハードウェア・ベースのコンテキスト・スイッチを最適化することによっ て、ハイパー・スレッディングの物理 CPU はマルチ・タスクを“並列に”走らせることができま す。SUSE Linux Enterprise Real Time は、ハイパー・スレッディングにおけるサポートを含 みます。リアルタイム環境内でこの機能をどのようにして有効的に使用するのかに関する更 なる情報については、2章を見てください。 ファイル・システムの XFS ジャーナル SGI からのファイル・システムの XFS ジャーナルは、SUSE Linux Enterprise Real Time で 実行されています。ファイル・システムのジャーナルは、ジャーナル(ログ)を使用してトランザ クションをレコードします。システム・クラッシュにおいては、バックグランド・プロセスがリブート で走り、そしてジャーナルからファイル・システムへのアップデートのコピーを終了します。これ はファイル・システム・チェックの複雑さを格段に減らし、リカバリ時間を縮小します。SGI の実 装は複数スレッドの、64ビット・ファイル・システムで、大きなファイル、ファイル・システム、拡張 された属性、変位のブロック・サイズの機能を持ち、範囲ベースで、そして2進木の多量な使 用で、パフォーマンス及びスケーラブル性を援助します。更なる情報については、8章を見てく ださい。 POSIX リアルタイム拡張 SUSE Linux Enterprise Real Time は、ISO/IEC 9945-1 で述べられているように POSIX リ アルタイム拡張で定義されているほとんどのインターフェイスをサポートします。 1-10 ・ ユーザ・プライオリティ・スケジューリング ・ プロセス・メモリ・ロッキング ・ メモリマップファイル ・ 共有メモリ ・ メッセージキュー ・ カウンティングセマフォ ・ リアルタイム・シグナル動作 ・ 非同期 IO ・ 同期 IO ・ タイマー(高精度バージョンがサポートされています。) SUSE Linux Enterprise Real Time Linux User’s Guide ユーザ・プライオリティ・スケジューリング SUSE Linux Enterprise Real Time は、ユーザ・プライオリティ・スケジューリングを適応しま す。つまり、固定プライオリティ POSIX スケジューリング・ポリシー下でスケジュールされたプ ロセスは、それらのプライオリティがオペレーティング・システムによって、それらの実行時間 動作への応答として変更することはありません。結果として、カーネル・オーバーヘッドが減 少されユーザ時間が増加します。プロセス・スケジューリング機能は、4章内で述べられてい ます。 メモリ常駐プロセス ページング及びスワッピングは、アプリケーション・プログラムに対して、予期せぬ量のシステ ム・オーバーヘッド時間を与えます。ページング及びスワッピングによるパフォーマンスのロス を無くすために、SUSE Linux Enterprise Real Time では、プロセスのバーチャル・アドレス空 間の部分を常駐にすることができます。mlockall (2)、 munlockall (2)、 mlock (2)、及び munlock (2) POSIX システムコールによって、物理メモリ内のプロセスのバーチャル・アドレ ス空間の全てまたは一部分をロックすることが可能です。詳細については、man page を見て ください。 メモリ・マッピング及びデータ共有 SUSE Linux Enterprise Real Time は、System V IPC メカニズムと同様に、IEEE 標準 1003.1b-1993 に基づいた共有メモリ及びメモリ・マッピング機能をサポートします。POSIX 機 能によって、1 つまたはそれ以上のプロセスのアドレス空間へマップすることができる記憶の 名前を付けられた領域である、メモリ・オブジェクトの使用を通してプロセスがデータを共有す ることができ、それらに結合するメモリを共有することができます。用語、 メモリ・オブジェクト は、POSIX 共有メモリ・オブジェクト、レギュラー・ファイル、及びいくつかのデバイスを含みま すが、全てのファイル・システム・オブジェクトを含むのではありません(例えば、ターミナル、ネ ットワーク・デバイス)。プロセスは、メモリ・オブジェクト内のデータに、直接にプロセスのアドレ ス空間の部分をオブジェクト上へとマップすることによって、アクセスすることができます。これ は一般的に、read (2)及び write (2)システムコールを使用するよりもより効率的です。なぜ なら、それはカーネルとアプリケーション間でのデータのコピーを無くすからです。 プロセス同期化 SUSE Linux Enterprise Real Time は、共同プロセスの共有リソースへのアクセスの同期化 において使用できる、様々なツールを提供します。 IEEE 標準 1003.1b-1993 に基づいたカウンティング・セマフォは、複数スレッド・プロセス内で マルチ・スレッドが、同じリソースのセットへのそれらのアクセスに同期化することを可能にし 1-11 SUSE Linux Enterprise Real Time Linux User’s Guide ます。カウンティング・セマフォはそれと結合する値をもっており、それはいつ利用可能なのか、 そして配分されるのかを決定します。プロセス間セマフォをサポートする System V IPC セマ フォ・セットも、SUSE Linux Enterprise Real Time 下で利用可能です。 セマフォに追加して、リアルタイム・プロセス同期化ツールは、再スケジューリングへのプロセ スの脆弱性の制御、ビジー待ち相互排他メカニズムでのクリティカル・セクションへのプロセス のアクセスの順キュー、そしてプロセス間でクライアントとサーバのインタラクションを整合す る機能を提供します。これらのツールで、結合したプライオリティ反転のスリープ待ち相互排 他の提供におけるメカニズムが構築されます。 同期化ツールの説明及びそれらの使用手続きについては、5章で述べられています。 非同期的入力/出力 IO オペレーションを非同期的に動作させることができることは、IO オペレーションにおいて設 定することができ、そして IO 完了上でブロックすることなく返ることができることを意味します。 SUSE Linux Enterprise Real Time は、IEEE 標準 1003.1b-1993 に基づいたライブラリ・ル ーチンのグループでの非同期的 IO を適応します。これらのインターフェイスによって、プロセ スが非同期的リード及びライト・オペレーションを動作させること、単一の呼び出しで複数非同 期的オペレーションを開始し、非同期的 IO オペレーションを完了待ちし、中断されている非同 期的 IO オペレーションのキャンセルし、そして、非同期的ファイルの同期化の動作を行うこと ができます。“aio”機能は、システム上の info ページ(”info libc”)の中でドキュメントされてい ます。 同期化入力/出力 SUSE Linux Enterprise Real Time はさらに、IEEE 標準 1003.1b-1993 に基づいた、同期 化 IO 機能もサポートします。POSIX 同期化 IO は、アプリケーションのデータ及びファイルの 完全性を確認する方法を提供します。同期化出力オペレーションは、出力デバイスへライトさ れたデータのレコーディングを確実にします。同期化入力オペレーションは、デバイスからリー ドされたデータが現在ディスク上に常駐しているデータに反映されていることを確実にします。 更なる情報については、man page を参照してください。 リアルタイム・シグナル動作 IEEE 標準 1003.1b-1993 で指定されているリアルタイム・シグナル動作は、同じ種類のシグ ナルの複数的生起の中で差異化のためにシグナルが生み出される時の、リアルタイム・シグ ナル・ナンバーの範囲の仕様、ある特定のシグナルの複数的生起の順キューにおけるサポ ート、そして、アプリケーション定義の値の仕様におけるサポートを含みます。POSIX シグナ ル・マネージメント機能は、sigtimedwait(2)、sigwaitinfo(2)、sigqueue(2)システムコール 1-12 SUSE Linux Enterprise Real Time Linux User’s Guide を含みます。それらによって、プロセスはシグナルの受信を待ち、シグナル及びプロセスへの アプリケーション定義の値を順キューすることができます。更なる情報については、man page を参照してください。 クロック及びタイマー 高精度 POSIX クロック及びタイマーのサポートが SUSE Linux Enterprise Real Time には 含まれています。POSIX クロックは、タイムスタンプまたはプログラムの実行速度を計るよう な目的のために使用されます。POSIX タイマーによって、アプリケーションは高精度クロック に基づいた相対的または絶対的時間を使用することができ、また、ワンショットまたは定周期 でイベントをスケジュールすることができます。アプリケーションはそれぞれのプロセスにおい て、複数のタイマーを生成することができます。さらに、高精度スリープメカニズムが提供され ており、それはプロセスをとても短いタイム・クワンタムのスリープに置くこと、そしてスリープ時 間を計るのにどのクロックが使用されるべきなのかを指定することに使用されます。更なる情 報については、6章を見てください。 メッセージキュー IEEE 標準 1003.1b-1993 に基づいた POSIX メッセージキュー機能は、SUSE Linux Enterprise Real Time に含まれており、ファイル・システムとして実行されます。POSIX メッセ ージキューライブラリ・ルーチンによって、プロセスがメッセージキューを生成、開く、問合せる、 そして破壊することができ、そして、メッセージキューからメッセージを送信し、受信し、送信さ れるメッセージにプライオリティを結合し、そしてメッセージが届いた時に非同期的通知を要 求することができます。POSIX メッセージキューは SUSE Linux Enterprise Real Time 下で も利用可能な System V IPC メッセージから独立して動作します。詳細については、3章を見 てください。 1-13 SUSE Linux Enterprise Real Time Linux User’s Guide 2 リアルタイム動作 この章では、SUSE Linux Enterprise Real Timeのリアルタイム動作に含まれるいくつかの事項に ついて論じます。この章の主要な焦点は、シールドされているCPUモデル(Shielded CPU Model)に おいてのもので、そのモデルは、最高のリアルタイム動作を得るために、プロセスと割り込みをシス テム内のCPUサブセットに割り当てるものです。 リアルタイム動作におけるキーとなる領域が論じられています。割り込み応答、プロセスディ スパッチレイテンシィ、及び決定的プログラム実行です。これらの基準における様々なシステ ムの動作の影響が論じられ、そして、最高のリアルタイム動作のための技術が提供されてい ます。 シールドされている CPU モデルの概要 シールドされている CPU モデルは、SMP・システム内で最高のリアルタイム動作を得るため の1つのアプローチです。シールドされている CPU モデルによって、リアルタイム・アプリケー ションの決定的実行、及び割り込みに対しての決定的応答が可能になります。 タスクがコード・セグメントを実行するのに要する時間が予測可能で定常である時に、タスクの 実行時間は決定的です。割り込みへ応答するのに要する時間が予測可能で定常である時に、 割り込みへの応答が決定的であるのと同様です。コード・セグメントの実行または割り込みへ の応答において計られた最悪のケースの時間が、一般的ケースのものから多大に異なって いるのならば、アプリケーションの動作はジッター(jitter)を含んでいると言われます。コンピュ ータ構造はメモリ・キャッシュや共有リソースにおける競合を機能とするので、実行時間の計 測には常にいくらかのジッターがあります。それぞれのリアルタイム・アプリケーションは、そ のアプリケーションが受け入れ可能なジッターの量を定義しなければなりません。 シールドされている CPU モデルにおいては、タスクや割り込みは、ある程度重要なリアルタイ ム機能への高位のサービスを保証する方法で、CPU に割り当てられます。特に、高プライオ リティのタスクは、1 つまたはそれ以上のシールドされている CPU に連結されており、その間、 多くの割り込み、及び低プライオリティのタスクは、他の CPU に連結されています。高プライ オリティのタスクを走らせることを担っている CPU は、割り込み、及びシステムコール経由で カーネルに入ってくる他の低プライオリティのプロセスの活動と結合している予測不可のプロ セスからシールドされていて、よって、これらの CPU はシールドされている CPU と呼ばれま す。 シールドされている CPU 上で走らされるべきタスクの種類のいくつかの例は: 2-1 SUSE Linux Enterprise Real Time Linux User’s Guide ¾ 保証された割り込み応答時間を要求するタスク ¾ 最速の割り込み応答時間を要求するタスク ¾ 高い周期で走らされなければならないタスク ¾ デッドラインに間に合うために決定的実行を要求するタスク ¾ オペレーティング・システムによる割り込みを許さないタスク 高プライオリティ割り込みに応答しなければならない、または決定的実行を要求するタスクに おいて、決定性の異なる程度を提供する、CPU シールディングにいくつかのレベルがありま す。シールドされれている CPU 上で許可できるシールディングのレベルについて論じる前に、 システムがどのように外的イベントへ反応するのか、そしてコンピュータ・システムの通常動作 のいくつかが、どのようにシステム応答時間及び決定性に影響を与えるのかを理解する必要 があります。 決定性の概要 決定性は、固定されている時間量内で、ある特定のコード・パス(順に実行される命令のセッ ト)を実行するシステムの能力を意味します。コード・パスにおける実行時間が 1 つのものか ら他のものへ変化する度合いが、そのシステム内の決定性の程度を示しています。 決定性は、ユーザアプリケーションの時間の重要な部分の実行に要求される時間量にのみ 適用されるものではなく、カーネル内でシステム・コードを実行するのに要求される時間量にも 適応されます。例として、プロセスディスパッチレイテンシィは、割り込み、ターゲット・プロセス のウェイクアップ、コンテキスト・スイッチの動作、そしてターゲット・プロセスをカーネルから出 ることを扱うのに実行されなければならないコード・パスに依存しています。(“プロセスディス パッチレイテンシィ”のセクションでは、プロセスディスパッチレイテンシィを定義し、そしてマル チ CPU・システム内のある特定の CPU 上で可能な最高のプロセスディスパッチレイテンシィ を得るためのモデルを提示しています。) プログラムの実行の決定性において最大の影響は、割り込みの受信です。これは、システム 内で割り込みは常に最高優先度の活動であり、そして割り込みの受信は予測不可能だから です(プログラムの実行中、どのポイントにおいても起こりえます)。非決定的割り込みからの シールディングは、高プライオリティ・タスクの実行の間において、よりよい決定性を生成する ことにおける最大の効果になります。 プログラムの実行の決定性を改良するための他の技術は、“決定性を増大する手順”と呼ば れるセクションで論じられています。 2-2 SUSE Linux Enterprise Real Time Linux User’s Guide プロセスディスパッチレイテンシィ リアルタイム・アプリケーションは、現実世界のイベントに応答し、そして与えられた期限内でそ の現実世界を扱うために要求されるプロセスを完了できなければなりません。与えられたデ ッドライン内で現実世界のイベントに応答するために要求される計算は、期限の前、または結 果が不正確であるとみなされる前に、完了しなければなりません。割り込みへの非定常に長 い応答の 1 つのイベントは、デッドラインに間に合わなくします。 プロセスディスパッチレイテンシィと言う用語は、割り込みによる外的イベントの生起から、外 的イベントを待っているプロセスがその最初の命令をユーザ・モードで実行するまでに経過す る時間を意味します。リアルタイム・アプリケーションにおいて、最悪のケースのプロセスディ スパッチレイテンシィは、鍵です。なぜなら、それはリアルタイム・アプリケーションがデッドライ ンに間に合うことを保証する機能を決定する、最悪のケースの応答だからです。 プロセスディスパッチレイテンシィは、以下の起こるイベントのシーケンスにかかる時間を包 含します。 割り込みコントローラは割り込みを感知し、そして CPU への割り込み実行を生成します。 割り込みルーチンが実行され、そして割り込み(ターゲット・プロセス)を待っていたプロセスが 呼び起こされます。 現在実行されているプロセスが中断され、そしてコンテキスト・スイッチが動作し、ターゲット・ プロセスが走ることができるようになります。 ブロックされていて、割り込みを待っていたカーネルから、ターゲット・プロセスは出なければ なりません。 ターゲット・プロセスが、ユーザ・モードで走ります。 イベントのこのシーケンスは、プロセスディスパッチレイテンシィにおける理想的なケースを表 しています。それは、図 2-1 で説明されています。上で述べられている 1~5のイベントが、図 2-1 でマークされていることに注意します。 2-3 SUSE Linux Enterprise Real Time Linux User’s Guide 図 2-1 通常のプロセスディスパッチレイテンシィ プロセスディスパッチレイテンシィは、イベントによって生起されるリアルタイム・アプリケーショ ンにおいてとても重要な規準です。なぜなら、アプリケーションが外部イベントに対して応答で きるスピードを表しているからです。リアルタイム・アプリケーションの多くの開発者は最悪の ケースのプロセスディスパッチレイテンシィに興味があります。なぜなら、それらのアプリケー ションはある程度の時間制約に合わなければならないからです。 プロセスディスパッチレイテンシィは、オペレーティング・システム、デバイス・ドライバ、及びコ ンピュータ・ハードウェアの通常の動作のいくつかから影響されます。次のセクションでは、プ ロセスディスパッチレイテンシィにおける、ジッターのいくつかの原因を確認します。 割り込み禁止の効果 オペレーティング・システムは共有データ構造へのアクセスを、それらのデータ構造の破壊を 防ぐためにプロテクトしなければなりません。データ構造がプログラム・レベルでアクセスされ る時、データ構造が割り込みレベルでアクセスされる時はいつでも、割り込みを禁止する必 要があります。同じ共有データ構造へのアップデート中で、それがプログラム・レベル・コード に割り込みするなら、これは、割り込みコードが共有データ構造を破壊するのを防ぎます。こ 2-4 SUSE Linux Enterprise Real Time Linux User’s Guide れは、カーネルが短時間割り込みを禁止する主な理由です。 割り込みが禁止される時、プロセスディスパッチレイテンシィは影響を受けます。なぜなら、 応答しようとしている割り込みが、割り込みが再び許可されるまでアクティブにならないからで す。この場合、割り込みを待っているタスクにおけるプロセスディスパッチレイテンシィは、割り 込みが禁止の時間量によって、変動します。これは図 2-2 の中で説明されています。この図 の中では、低プライオリティ・プロセスは、割り込みを禁止したシステムコールを生成していま す。高プライオリティ割り込みが起こる時、それは何からも影響を受けません。なぜなら、割り 込みは現在禁止されているからです。低プライオリティ・プロセスがその決定的なセクションを 完了した時、それは割り込みを許可し、割り込みはアクティブになり、そして割り込みサービ ス・ルーチンが呼び出されます。そして、割り込み応答の通常のステップが、通常の形式で完 了します。図 2-2 の中の 1~5 でマークされている番号は、先に説明された通常のプロセスディ スパッチレイテンシィのステップを表していることに注意します。 明らかに、割り込みが禁止されるオペレーティング・システム内のクリティカル・セクションは、 かなり最悪のケースのプロセスディスパッチレイテンシィに備えて、最小にされなければなり ません。 図 2-2 プロセスディスパッチレイテンシィにおける割り込みの禁止の効果 2-5 SUSE Linux Enterprise Real Time Linux User’s Guide 割り込みの効果 割り込みの受信は、割り込みを禁止するのと同じように、プロセスディスパッチレイテンシィに 影響を与えます。ハードウェア割り込みを受信する時、システムは、現在の割り込みと同じか またはより低いプライオリティの割り込みをブロックします。図 2-3 の中で、単純なケースが説 明されています。そこでは、ターゲット・プロセス前により高いプライオリティの割り込みが起こ り、より高いプライオリティ割り込みが起こるまで、ターゲット割り込みがブロックされます。図 2-3 の中の 1~5 でマークされている番号は、先に説明された通常のプロセスディスパッチレ イテンシィのステップを表していることに注意してください。 図 2-3 プロセスディスパッチレイテンシィにおける高プライオリティ割り込みの効果 割り込みの相対的プライオリティは、プロセスディスパッチレイテンシィに影響を与えません。 低プライオリティ割り込みがアクティブになる時さえ、高プライオリティ割り込みにおけるプロセ スディスパッチレイテンシィ上に割り込む影響は同じです。これは、割り込みは常にユーザ・レ ベル・コードよりもより高いプライオリティで走っているからです。よって、高プライオリティ割り 込みにおいて割り込みルーチンを提供しても、全ての割り込みがそれらの実行を完了するま で、その割り込みルーチンはユーザ・レベル・コンテキストの動作を得ません。プロセスディス 2-6 SUSE Linux Enterprise Real Time Linux User’s Guide パッチレイテンシィ上の低プライオリティ割り込み上のこのインパクトは、図 2-4 内で説明され ています。どのように事が扱われるかの順序は、図 2-3 内の高プライオリティ割り込みのケー スとは異なり、しかし、プロセスディスパッチレイテンシィ上の影響は同じであることに注意し ます。図 2-4 の中の 1~5 でマークされている番号は、先に説明されたように、通常のプロセ スディスパッチレイテンシィのステップを表していることに注意します。 図 2-4 プロセスディスパッチレイテンシィ上の低プライオリティ割り込みの効果 割り込みを禁止することの効果と、プロセスディスパッチレイテンシィ上の影響における割り 込みの受信との最も大きな違いの 1 つは、割り込みはアプリケーションの実行に非同期的に、 そして予測不可で起こるという事実です。利用可能なシールディングの様々なレベルを理解 するのに、これは重要なことです。 ある CPU 上に複数、割り込みが受信される時、最悪のケースのプロセスディスパッチレイ テンシィ上の影響は、重大なものになります。これは、割り込みがスタックに積まれ、高プライ オリティ割り込みにおけるプロセスディスパッチレイテンシィが完了する前に、1 つ以上の割り 込みサービス・ルーチンが処理されなければならないようなことになるからです。図 2-5 は、 高プライオリティ割り込みに応答しようとしながら、2 つの割り込みがアクティブになるケース 2-7 SUSE Linux Enterprise Real Time Linux User’s Guide を示しています。図 2-5 内の 1~5 でマークされている番号は、先に 2-3 ページで説明された ように通常のプロセスディスパッチレイテンシィのステップを表しています。CPU が割り込みを 受け取る時、その CPU は、より低いプライオリティの割り込みが CPU に割り込むことができ ることを禁止します。この時間内により低いプライオリティの 2 つ目の割り込みがアクティブに なれば、オリジナル割り込みがアクティブである間、それはブロックされます。第 1 の割り込み の提供が完了する時、第 2 の割り込みはアクティブになり、そして提供されます。もし第 2 の 割り込みが最初の割り込みよりも高プライオリティであるなら、それはすぐにアクティブになり ます。第 2 の割り込みがその処理を完了する時、第 1 の割り込みが再びアクティブになります。 いずれの場合も、中断されている全ての割り込みが提供されるまで、ユーザ・プロセスは行 われません。 考えられるところでは、割り込みがアクティブであり続け、システムが高プライオリティ割り 込みに応答することを決して許さない病的なケースがあり得ます。複数割り込みがある特定 の CPU に割り当てらる場合、プロセスディスパッチレイテンシィはその CPU 上でより予測で きないものになります。なぜなら、そのように割り込みはスタックされるからです。 図 2-5 プロセス複数待ち時間におけるマルチ割り込みの効果 2-8 SUSE Linux Enterprise Real Time Linux User’s Guide プリエンプションの禁止の効果 SUSE Linux Enterprise Real Time には、決定的なセクションがあり、それは割り込みレベル では決してロックされない共有リソースをプロテクトするものです。この場合、このクリティカ ル・セクションの間、割り込みをブロックする理由はありません。しかし、このクリティカル・セク ションの間に起こるプリエンプションは、もしも新しいプロセスが同じクリティカル・セクションに 入ってくれば、共有リソースを破壊します。よって、この種類のクリティカル・セクションにおけ るプロセスの実行の間、プリエンプションは禁止されます。プリエンプションのブロックは、割り 込みの受け取りを遅らせません。しかし、その割り込みが高プライオリティ・プロセスを呼び起 こせば、プリエンプションが再び許可されるまで、そのプロセスに切り換わることはできません。 同じ CPU が要求することとして、最悪のケースのプロセスディスパッチレイテンシィ上の実際 的な効果は、あたかも割り込みが禁止されたものと同じです。プロセスディスパッチレイテン シィ上のプリエンプションの禁止の効果は、図 2-6 内で説明されています。図 2-6 内で 1~5 でマークされている番号は、先に説明された通常のプロセス・ディスパッチ待ち時間のステッ プを表していることに注意します。 図 2-6 プロセスディスパッチレイテンシィ上のプリエンプションの禁止の効果 2-9 SUSE Linux Enterprise Real Time Linux User’s Guide オープン・ソース・デバイス・ドライバの効果 デバイス・ドライバは、Linux カーネルの一部です。なぜなら、それらはスーパバイザ・モードで 走るからです。これはデバイス・ドライバは自由に、割り込みを禁止する、またはプリエンプシ ョンを禁止する Linux 関数を呼び出すことができることを意味します。デバイス・ドライバはさ らに割り込みも扱います。よって、割り込みレベルで使用される時間量を制御することができ ます。この章の先のセクションで示されたように、これらのアクションには、最悪のケースの割 り込み応答、及びプロセスディスパッチレイテンシィにインパクトを与える可能性があります。 SUSE Linux Enterprise Real Time に含まれているデバイス・ドライバは、リアルタイム動作 に有害な影響を与えないことが検証されています。オープン・ソース・デバイス・ドライバは、割 り込みレベルで使用される時間、割り込みが禁止される時間を最小にするよう様々なレベル の注意で書かれています。もしオープン・ソース・デバイス・ドライバを追加されれば、それら は SUSE Linux Enterprise Real Time が提供する、保証された最悪のケースのプロセスディ スパッチレイテンシィにネガティブな影響を与えるかもしれません。 デバイス・ドライバのリアルタイム事項に関する更なる情報については、“デバイス・ドライバ” の章を参照してください。 シールディングはどのようにしてリアルタイム動作を向上させるのか このセクションでは、CPU シールディングの異なる属性がどのようにして、ユーザ・プロセスが 割り込み(プロセスディスパッチレイテンシィ)に応答する、及びユーザ・プロセスの実行にお ける決定性においての機能を向上させるのかを調べます。 シールディングを許可する時、全てのシールディング属性はデフォルトで許可されます。これ は、シールドされている CPU 上で最も決定性の大きな実行環境を提供します。これらのシー ルディング属性のそれぞれは、以下でさらに詳細に述べられます。これらの属性のいくつか は通常のシステム機能に副作用をもたらすので、ユーザは、あり得るシールディング属性の それぞれの影響を完全に理解しているべきです。現在サポートされているシールディング属 性に 3 つのカテゴリがあります。 ¾ バックグランド・プロセスからのシールディング ¾ 割り込みからのシールディング ¾ ローカルな割り込みからのシールディング これらの属性のそれぞれは、CPU 個々に選択可能です。シールディング属性は、下記に述 2-10 SUSE Linux Enterprise Real Time Linux User’s Guide べられています。 バックグランド・プロセスのシールディング このシールディング属性によって、システム内のプロセスのサブセットのために CPU を確保 することができます。このシールディング属性は CPU に、割り込みに対して最速の、最も予 想可能な応答を持たせたい時に、許可されるべきです。プロセスディスパッチレイテンシィに おける最良の保証は、割り込みに応答するタスクのみが、その割り込みが指向されている CPU 上で実行を許されている際に得られます。 CPU がバックグランド・プロセスを走らせることを許される時、それは高プライオリティ・タスク のプロセスディスパッチレイテンシィに影響を与え、そのタスクは、その CPU に指向された割 り込みに対してとても決定性のある応答を要求するものです。これは、割り込みまたはプリエ ンプションを禁止するシステムコールを、バックグランド・プロセスが潜在的に生成するからで す。これらの動作は、“割り込みの禁止の効果”及び“プリエンプションの禁止の効果”のセク ションで説明されたように、プロセスディスパッチレイテンシィに影響を与えます。 CPU がバックグランド・プロセスを走らせることを許される時、高プライオリティ・プロセスの実 行での決定性には影響を与えません。これは、バックグランド・プロセスは、高プライオリティ よりも低プライオリティを持っていることを前提とします。バックグランド・プロセスは、シグナル、 または server_wake1 (3)インターフェイスのような他のカーネル・メカニズム経由でプロセス を呼び起こすのに要する時間に影響を与えることに注意します。 システム内のそれぞれのプロセスまたはスレッドは CPU バインドマスクを持ちます。CPU バ インドマスクは、どの CPU 上でプロセスまたはスレッドが実行するのを許されるのかを決定し ます。CPU バインドマスクは親から継承され、mpadvise (3)ライブラリ・ルーチン、または sched_setaffinity (2)システムコール経由で設定されます。CPU がプロセスからシールドさ れている時、シールドされている CPU を含むだけの CPU のセットへそれらの CPU バインド が明確に設定されているプロセス及びスレッドを、その CPU は走らせるだけです。換言すれ ば、もしプロセスがその CPU バインドマスクの中にシールドされていない CPU を持つなら、 プロセスは、シールドされていない CPU 上を走るだけです。バックグランド・プロセスからシー ルドされている CPU 上でプロセスまたはスレッドを走らせるためには、それは、シールドされ た CPU のみを指定する CPU バインドマスクを持たなければなりません。 Linux が生成したある程度のカーネル・デーモンは、システム内のどの CPU 上にも複製され ています。プロセスから CPU をシールドすることは、これらの“CPU ごとの”デーモンをシール ドされている CPU から取り除きません。これらのデーモンの影響は、カーネル・コンフィグレー 2-11 SUSE Linux Enterprise Real Time Linux User’s Guide ション、またはアプリケーション動作の考慮された制御によって回避することができます。 CPU ごとのカーネル・デーモンからのジッタ-を回避するカーネル・デーモン、それらの機能、 及び方法は、付録 F で述べられています。 割り込みのシールディング このシールディング属性によって、システムによって受け取られる割り込みのサブセットのみ を処理するために CPU を確保することができます。最速の、最も予測可能なプロセスディス パッチレイテンシィを持つことが望まれる時、またはアプリケーションの実行時間の中で決定 性を持つことが望まれる時に、このシールディング属性は許可されるべきです。 CPU 上では、割り込みは常に最高のプライオリティの動作であるため、割り込みの扱いは、 プロセスディスパッチレイテンシィ、及び高プライオリティ・タスクの中で通常のコード・パスを 実行するのにそれが要する時間双方に影響を与えます。これは、“割り込みの効果”のセク ションで述べられています。 それぞれのデバイス割り込みは、IRQ と結合しています。これらの IRQ は結合している CPU バインドを持ち、それは、どの CPU が割り込みを受け取ることを許されるかを決定します。割 り込みが特定の CPU に経路を持たなければ、割り込みコントローラは、IRQ バインドマスク 内の CPU のセットから割り込みが生成される時の割り込みの扱いにおいて、CPU を選択し ます。IRQ バインドは、shield (1)コマンドによって、または/proc/irq/N/smp_affinity を通し て、修正されます。 i386 アーキテクチャ上では、kirqd デーモンは、CPU における割り込み負荷のバランスをとる ために、周期的に IRQ バインドを調整します。このデーモンは割り込みシールディングと競合 し、そして IRQBALANCE カーネル・コンフィグレーション・オプションを通して、全ての SUSE Linux Enterprise Real Time カーネル・コンフィグレーションの中でデフォルトで禁止されてい ます。それは、カーネル・ブート・パラメータ“noirqbalance”で、または IRQBALANCE カーネ ル・パラメータを許可することによって、許可することができます。 もしも全ての CPU 上で全ての割り込みを禁止することが望まれるのならば、推奨される手順 は、全ての CPU を 1 つを除く割り込みからシールドし、そしてシールドされていない CPU 上 で local_irq_disable (2)を呼び出すことに注意します。詳細については、man page を見てく ださい。 ある程度の動作はシールドされている CPU へ割り込みが送られることを引き起こします。こ れらの・CPU 間割り込みは、他の CPU にいくつかの CPU ごとの特定のタスクを扱わせる方 2-12 SUSE Linux Enterprise Real Time Linux User’s Guide 法として使用されます。CPU 間割り込みは潜在的にシールドされている CPU において、目立 つジッターを引き起こします。完全な説明については、付録 G を参照してください。 ローカル割り込みからのシールディング ローカル割り込みは、それぞれの CPU と結合しているプライベート・タイマーにおける特別な 割り込みです。SUSE Linux Enterprise Real Time 下では、このタイマーは、カーネル内、及 びユーザ・レベルで様々なタイムアウト・メカニズムにおいて使用されています。この機能は、 7 章で述べられています。デフォルトでは、この割り込みはシステム内の全ての CPU 上で許 可されています。 この割り込みは 10 ミリ秒ごとに発生し、ローカル割り込みを、システム内で最も頻繁に実行さ れる割り込みルーチンになります。よって、ローカル割り込みは、リアルタイム・アプリケーショ ンへのジッターの大きな要因です。 CPU がローカル・タイマーからシールドされている時、ローカル・タイマーは有効的に禁止さ れており、そしてその CPU とバインドしているローカル・タイマーが供給する機能はもはや動 作しません。しかし、それらは、ローカル・タイマーがシールドされていない他の CPU 上で走り 続けます。他の方法経由で他のものが供給されている間に、これらの機能のいくつかは失わ れます。 ある特定の CPU 上でローカル割り込みが禁止される時に失われる機能の 1 つは、CPU 実 行時間アカウンティングにおける、低精度メカニズムです。これは、この CPU 上で実行されて いるそれぞれのプロセスによって、どれほどの CPU 時間が使用されているかを計るメカニズ ムです。ローカル割り込みが発生するたびに、時間の最後のクロック間隔は、割り込みされ たプロセスにチャージされます。もしも高精度プロセス・アカウントがコンフィグされれば、CPU 時間はローカル割り込みが許可されているかいないかに関わり無く正確にアカウントされま す。高精度プロセス・アカウントは、7 章、“システムのクロック及びタイマー”で論じられていま す。 CPU がローカル・タイマーからシールドされている時、ローカル割り込みは POSIX タイマーに おいて使用され続け、そしてプロセスによるナノスリープ機能性は、シールドされている CPU にバイアスされます。この理由のため、特定のシールドされている CPU 上の最良の動作の ためにローカル・タイマー割り込みを完全に消すことがクリティカルなら、POSIX タイマーまた はナノスリープ機能性を利用しているアプリケーションは、その CPU にバイアスされるべきで はありません。もしもそのシールドされている CPU 上でプロセスが走ることが許されないのな ら、そのタイマーはプロセスが走ることが許される CPU へ移動されます。 2-13 SUSE Linux Enterprise Real Time Linux User’s Guide ローカル・タイマーの禁止、及びいくつかの機能によって利用可能な他の方法の効果に関す る完全な説明については、7 章、“システム・クロック及びタイマー”を参照してください。 CPU シールディングへのインターフェイス このセクションは、コマンド・レベル及びシールドされている CPU のセット・アップに使用される プログラミング・インターフェイス双方について述べます。シールドされている CPU のセット・ア ップにおける共通のケースを述べている例もあります。 シールド・コマンド shield (1)コマンドは、選択された CPU における、指定されているシールドされた属性を設定 します。シールド・コマンドは CPU をシールドされている CPU としてマークするのに使用され ます。アプリケーション・コードを実行するのに要する時間内でよりよい決定性を提供するた めに、シールドされている CPU は、システム動作のいくつかのセットからプロテクトされてい ます。 shield コマンドの呼び出しによって影響される論理 CPU のリストは、カンマで区切られた CPU 数または範囲のリストとして、与えられています。 shield コマンドを実行するフォーマットは: shield [オプション] オプションは表 2-1 の中で説明されています。 下にリストされているオプションの中で、CPULIST は、カンマで区切られた値、または値の範 囲で、論理 CPU を表しています。例として、CPUs“0-4,7”のリストは次の論理 CPU を指定し ています:0,1,2,3,4,7。 2-14 SUSE Linux Enterprise Real Time Linux User’s Guide 表 2-1 shield(1)コマンドへのオプション オプション 説明 --irq=CPULIST -i CPULIST 割り込みから CPULIST の中の全ての CPU をシールドします。指定された CPU 上で実 行する割り込みのみは、それらをその他のどの CPU 上でも実行させない CPU バインド を割り当てられたものです。 --loc=CPULIST -l CPULIST CPU の指定されたリストは、ローカル・タイマーからシールドされています。ローカル・タイ マーは、CPU へ時間ベースのサービスを提供します。ローカル・タイマーの禁止は、ユー ザ/システム時間アカウント及びラウンド・ロビン・クワンタム満了の禁止のような、いくつ かのシステム機能性を引き起こします。更に完全な説明は、7 章を参照してください。 --proc=CPULIST,-p CPU の指定されたリストは、外部からのプロセスからシールドされています。シールドさ CPULIST れていない CPU 上を走ることを許されたバインドマスクを持つプロセスは、シールドされ ていない CPU 上を走るだけです。シールドされている CPU 以外のどの CPU 上でも実 行することから除外されたプロセスは、そのシールドされている CPU 上で実行することを 許されます。 --all=CPULIST -a CPULIST CPU の指定されたリストは、全ての利用可能なシールディング属性セットを持ちます。上 の個々のシールディング・オプションを見て、それぞれのシールディング属性が示唆する ことを理解します。 --help -h 利用可能なオプション及び使用法を説明します。 --version -V コマンドの現在のバージョンをプリント・アウトします。 --reset 全ての CPU において、シールディング属性を再設定します。CPU はシールドされていま -r せん。 全てのアクティブな CPU において、現在の設定を表示します。 --current -c シールド・コマンドの例 以下のコマンドはまず、全てのシールディング属性を再設定し、そして割り込みから CPU 0、 1、2 をシールドし、そしてローカル・タイマーから CPU 1をシールドし、外部プロセスから CPU 2 をシールドし、そして最後に変更後の全ての新しい設定を表示します。 shield –r –I 0-2 –l 1 –p 2 –c 以下のコマンドは、割り込み、ローカル・タイマー、そして外部プロセスから CPU 1、2、そして 3 をシールドします。CPU 0 は、“GENERIC”CPU として残され、シールドされている CPU に ターゲットすることなく、全ての割り込み及びプロセスを提供します。全てのシールディング属 2-15 SUSE Linux Enterprise Real Time Linux User’s Guide 性は、CPU のリストにおいて設定されています。 shield --all=1 – 3 終了ステータス 通常、終了ステータスはゼロです。しかし、もしシールドされている CPU 属性を修正しようとし ている間にエラーが生じれば、診断メッセージが発信され、そして終了ステータス 1 が返され ます。 シールド・コマンドの進歩した機能 下で説明されている進歩した機能は経験豊富なユーザに使用されるのみであることが薦め られます。 CPULIST の中で指定されている CPU は、’+’または’-‘記号を前につけることができ、その場 合、既にシールドされている CPU のリストから、リストの中の CPU は加えられる(’+’)、また は取り除かれます(’-‘)。 オプションは多様な回数で使用されます。例として、“shield –i 0 –c –i +1 –c”は、割り込みか ら CPU 0がシールドされた後の現在の設定を示し、そして割り込みからシールドされた CPU のリストへ CPU 1 が加えられた後の現在の設定を表示します。 CPU シールディングへの/proc インターフェイス CPU シールディングへのカーネル・インターフェイスは、以下のファイルを使用して/proc ファ イル・システムを通されます。 /proc/shield/procs プロセス・シールディング /proc/shield/irqs irq シールディング /proc/shield/ltmrs ローカル・タイマー・シールディング 全てのユーザはこれらのファイルをリードすることができます。しかし、ルートまたは CAP_SYS_NICE 認証及びファイル許可のユーザのみが、それらにライトすることができま す。 リードされる時、8 桁の16進文字キューが返されます。この値は、シールドされている CPU のビットマスクです。シールドされている CPU のセットを識別するようにビットを設定します。 それぞれのセット・ビットの基ポジションは、そのビットによってシールドされている論理 CPU の数です。 2-16 SUSE Linux Enterprise Real Time Linux User’s Guide 例: 00000001 - ビット 0 が設定されているので CPU#0がシールドされています 00000002 - ビット 1 が設定されているので CPU#1がシールドされています 00000004 - ビット 2 が設定されているので CPU#2がシールドされています 00000006 - ビット 1 及びビット2が設定されているので CPU#1 及び 2#がシールドされて います ライトされる時、8 桁の 16 進文字キューが予期されます。この値は、上にリストされているも のに類似した形式でのシールドされている CPU のビットマスクです。値はシールドされた CPU の新しいセットになります。 更なる情報については、shield (5)man page を見てください。 CPU へのプロセスの割り当て このセクションでは、CPU のセットへのプロセスまたはスレッドの割り当てにおいて利用可能 な方法を説明します。プロセスが走ることを許されている CPU のセットは、その CPU バインド として知られています。 デフォルトでは、システム内のどの CPU 上でもプロセスまたはスレッドは実行できます。どの プロセスまたはスレッドもビットマスクまたは CPU アフィニティを持ち、それは、その上でスケ ジュールされる単一の CPU または複数の CPU を決定します。プロセスまたはスレッドは、 fork (2)または clone (2)の間にその CPU バインドをそのクリエータから継承しますが、その 後変化します。 mpadvise (3)への呼び出し上の MIPA_PRC_SETBIAS コマンドを、または run (1)コマンド への-b バイアスオプションを指定することによって、1つまたはそれ以上のプロセスまたはス レッドにおいて、CPU アフィニティを設定することができます。sched_setaffinity (2)も CPU バインドを設定するのに使用されます。 CPU バインドを設定するには、以下の状態が満たされなければなりません。 ¾ 呼び出しプロセスの本当のまたは有効的なユーザ ID が、それにおいて CPU バイン ドが設定されるプロセスの本当のまたは保存されているユーザ ID に一致しなけれ ばなりません。または、 ¾ 2-17 呼び出しプロセスは CAP_SYS_NICE 認証を持つかまたはルートでなければなりま SUSE Linux Enterprise Real Time Linux User’s Guide せん。 プロセスまたはスレッドの CPU バインドへ CPU を加えるには、呼び出しプロセスは CAP_SYS_NICE 機能を持つかまたはルートでなければなりません。 CPU バインドは、init (8)プロセスへと割り当てられます。全ての一般的プロセスは、init から 来ています。結果として、多くの一般的プロセスは、init または initCPU バインド内の CPU の サブセットと同じ CPU バインドを持ちます。特権化されたプロセス(上で述べられたように)の みが、それらの CPU アフィニティに CPU を加えることができます。init に制約された CPU バ インドを割り当てることは、init としての CPU の同じサブセットへの全ての一般的プロセスを 制約します。例外は選択されたプロセスで、それは明確にそれらの CPU バインドを修正する 適切なケーパビリティを持ちます。init の CPU バインドを変更したければ、“init への CPU バ インドの割り当て”のセクションの下のインストラクションを見てください。 mpadvise ライブラリ・ルーチンは、下の“mpadvise を使用してのマルチ CPU・コント role”の セクション及び mpadvise (3) man page の中にドキュメントされています。run コマンドは、4 章の“run コマンド”のセクション及び run (1) man page の中にドキュメントされています。 sched_setaffinity (2) 及 び sched_getaffinity (2) に つ い て の 情 報 に つ い て は 、 sched_affinity (2) man page を見てください。 2-18 SUSE Linux Enterprise Real Time Linux User’s Guide mpadvise を使用してのマルチ CPU・コント role mpadvise (3)は、様々なマルチ CPU 機能を動作します。CPU は、1つまたはそれ以上の CPU を指定する CPUset_t オブジェクトへポインタを指定することによって、識別されます。 CPU セットに関する更なる情報については、CPUset (3) man page を見てください。 概要 #include <mpadvise.h> int mpadvise (int cmd, int which, int who, CPUset_t *setp) gcc [オプション] ファイル –lccur_rt … 情報コマンド 以下のコマンドは、システム内の CPU に関する情報を収得するかまたは設定します。which 及び who パラメータは無視されます。 MPA_CPU_PRESENT どの CPU がシステム内に物理に存在するのかを示すマスクを返します。CPU (1) コマンドでダウンされた CPU はまだ含まれています。 MPA_CPU_ACTIVE どの CPU がアクティブであるかを示すマスクを返します。もしも CPU が CPU (1)を 使用してダウンさせられれば、それは含まれません。 MPA_CPU_BOOT CPU がシステムをブートした CPU を示すマスクを返します。ブート CPU は、他の CPU と共有しない動作を持ちます。 MPA_CPU_LMEM MPA_CPU_LMEM はどの CPU が NUMA サポートでシステムでローカルなメモリを 持っているかを示しているマスクを返します。CPU (1)コマンドでダウンさせられた CPU はまだ含まれています。 制御コマンド 以下のコマンドは CPU の使用における制御を、プロセス、スレッド、プロセス・グループ、また はユーザによって提供します。 2-19 SUSE Linux Enterprise Real Time Linux User’s Guide MPA_PRC_GETBIAS 指定されているプロセス(MPA_PID)内の全てのスレッドの CPU バインドにおける CPU セットを、または指定されているスレッド(MPA_TID)における正確でユニーク なバイアスを返します。 MPA_PRC_SETBIAS 指定されているプロセス(MPA_PID)内の全てのスレッドの CPU バインドを、また は指定さている CPUset へ指定されたスレッド(MPA_TID)におけるユニークな CPU バインドを設定します。プロセスの CPU バインドを変更するには、本当のまた は有効的なユーザ ID が、プロセスの本当のまたは保存されている(exe (2)から)ユ ーザ ID に一致するか現在のユーザーが CAP_SYS_NICE を持ってなければなり ません。 MPA_PRC_GETRUN 指定されているスレッドが現在走っている(または走るのを待っている)(MPA_TID) CPU に対応する、その中にある正確に1つの CPU で CPU セットを返します。 MPA_PID が指定される際、スレッドされていないプログラムにおける1つの CPU を、 及びマルチ・スレッドされているプログラムの全てのスレッドで使用されている CPU セットを返します。値が返された時には CPU 割り当てが既に変化していることがあ り得ることに注意します。 which 及び who の使用 which 選択基準を指定するのに使用されます。以下の中の1つです。 MPA_PID 特定のプロセス及び全てのそのスレッド MPA_TID 特定のスレッド MPA_PGID プロセス・グループ MPA_UID ユーザ MPA_LWPID MPA_TID と同様(PowerMAX と互換性があります) who which と関連していると解釈されたもの プロセス識別子 スレッド識別子 プロセス・グループ識別子 ユーザ識別子 0の値の who は、呼び出しのプロセス識別子、プロセス・グループ識別子、またはユーザ識 別子の使用を引き起こします。 2-20 SUSE Linux Enterprise Real Time Linux User’s Guide 一つの子スレッドが MPA_PID を使うと、その親スレッドが生成したすべてのスレッドへ適用さ れます。 2-21 SUSE Linux Enterprise Real Time Linux User’s Guide init への CPU バインドの割り当て 全ての一般的プロセスは init (8)から来ています。デフォルトでは、init は、システム内の全て の CPU を含むマスクを持ち、そして、選別された適切なケーパビリティのあるプロセスのみが それらの CPU バインドを修正することができます。もしもデフォルトで全てのプロセスが CPU のサブセットに制約することが望まれるのなら、CPU バインドは、特権的ユーザにより、init プロセスへと割り当てられます。この目的を達成するために、run(1)コマンドは、システム初 期化プロセスの間に起動されます。 例として、init 及びその全ての子を CPU 1、2、そして3にバイアスさせるには、以下のコマン ドが、システムの/etc/rc.sysinit スクリプトの最後に付加されます。そのスクリプトは、システ ム初期化の早期に呼ばれるものです(inittab (5)を見てください)。init プロセスは、このコマ ンドの中で常に1であるそのプロセス ID で指定されます。 /usr/bin/run –b 1-3 –p 1 同じ効果は、shield (1)コマンドを使用することによっても得られます。このコマンドを使用す ることの利点は、どのラン・レベルでもコマンド・ラインからそれが行われることです。shield コ マンドは、既に CPU 内を走っているプロセスがシールドされる動作を手助けします。さらに、 shield コマンドでシールディングの異なるレベルを指定することができます。このコマンドに 関する更なる情報については、“シールド・コマンド”のセクション、または shield (1) man page を見てください。 例として、CPU 0を走っているプロセスからシールドするためには、次のコマンドを発信しま す。 $ shield –p 0 CPU をシールドした後、run コマンドを使用して、いつでも選択されたプロセスをシールドされ ている CPU 内で走らせるように指定することができます。 例として、プロセスから既にシールドされていた CPU 0上で mycommand を走らせるため には、次のコマンドを発信します。 $ run –b 0 ./mycommand 2-22 SUSE Linux Enterprise Real Time Linux User’s Guide シールドされている CPU のセット・アップの例 以下の例は、シールドされている CPU をどのように使用して、RCIM からのエッジ・トリガの割 り込みに対して最良の割り込み応答を保証するのかを表しています。換言すれば、意図は、 RCIM 上でエッジ・トリガの割り込みが起こった際にユーザ・レベル・プロセスを呼び起こすの にかかる時間を最適化すること、及び、それが呼び起こされた際にそのプロセスにおいて決 定的実行環境を提供することです。この場合、シールドされたている CPU は、ただ RCIM 割 り込み及びその割り込みに応答しているプログラムを扱うためにセット・アップされます。 第1のステップは、割り込みをシールドされている CPU から shield (1)コマンドを通して離れ させることです。ローカル・タイマー割り込みも禁止され、そしてバックグランド・プロセスは最 良の割り込み応答を得るために排除されます。CPU 1 においてこれらの結果を達成するシ ールド・コマンドは: $ shield –a 1 この時点で、シールドされている CPU1上に割り込みは無く、また実行することを許されたプ ロセスもありません。CPU のシールディング・ステータスは、以下の方法を使用してチェックす ることができます。 shield (1)コマンド経由で: $ shield -c CPUID irqs ltmrs procs --------------------------------------0 no no no 1 no no no CPU(1)コマンド経由で(i386 システム上): $ CPU log id(phys id) state shielding ----------- ------ 0 (0) up none 1 (0) up none 2 (1) up none 3 (1) up none 2-23 ------------------- SUSE Linux Enterprise Real Time Linux User’s Guide または、/proc ファイル・システム経由で: $ cat/proc/shield/irqs 00000002 これは、全ての割り込みの CPU1 上での実行が排除されていることを示しています。この例 では、目的はシールドされている CPU 上でのある特定の割り込みに対して応答することなの で、よって、RCIM 割り込みを CPU1 へ向けさせること、及びこの割り込みに応答するプログ ラムが CPU 1上で走るようにすることが必要です。 第 1 のステップは、それに対して RCIM 割り込みが割り当てられている IRQ を決定すること です。割り込みと IRQ の間の割り当ては、マザーボード上のデバイス及び特定の PCI スロッ ト内の PCI デバイスにおいて、定常です。もしも PCI ボードが新しいスロットへ移動された場 合、その IRQ 割り当ては変化します。デバイスの IRQ を確かめるためには、以下のコマンド を動作させます。 $ cat /proc/interrupts CPU0 CPU1 0: 665386907 0 4: 2720 0 8: 1 0 9: 0 0 14: 9649783 1 15: 31 0 16: 384130515 0 17: 0 0 18: 11152391 0 19: 0 0 23: 0 0 NMI: 102723410 116948412 LOC: 665262103 665259524 RES: 36855410 86489991 CAL: 2072 2074 TLB: 32804 28195 TRM: 0 0 SPU: 0 0 ERR: 0 0 MIS: 0 0 CPU2 0 0 0 0 2 0 0 0 0 0 0 0 665264914 94417799 2186 21833 0 0 0 0 CPU3 0 0 0 0 3 0 0 0 0 0 0 0 665262848 80848546 2119 37493 0 0 0 0 IO-APIC-edge timer IO-APIC-edge serial IO-APIC-edge rtc IO-APIC-level acpi IO-APIC-edge ide0 IO-APIC-edge ide1 IO-APIC-level eth0 IO-APIC-level rcim,Intel.. IO-APIC-level aic7xxx,... IO-APIC-level uhci_hcd IO-APIC-level uhci_hcd Non-maskable interrupts Local interrupts Rescheduling interrupts function call interrupts TLB shootdowns Thermal event interrupts Spurious interrupts Error interrupts APIC errata fixups 上にリストされているように、RCIM は IRQ28 に割り当てられています。そしてその IRQ 番号 が知られ、IRQ28 におけるバインドマスクを/proc ファイル経由で、RCIM における割り込み はシールドされている CPU へと割り当てられます。IRQ における相性マスクは 8 桁の 16 進 文字キューです。その値は CPU のビット・マスクです。マスク内のそれぞれのビット・セットは、 この割り込みにおける割り込みルーチンが扱われる CPU を表しています。それぞれのビッ ト・セットの基位置は、割り込みを扱う論理 CPU の番号です。以下のコマンドは、IRQ におけ る CPU バインドマスクを CPU1へとセットします。 2-24 SUSE Linux Enterprise Real Time Linux User’s Guide $ echo 2 > /proc/irq/28/smp_affinity IRQ における“smp_affinity”ファイルは、デフォルトで、ルート・ユーザのみが IRQ の割り込 み割り当てを変更することができる許可と共にインストールされていることに注意します。IRQ バインドにおける/proc ファイルは、変更が効果を発したことを確認するためにリードされま す。 $ cat /proc/irq/28/smp_affinity 00000002 user 00000002 actual “user”に返された値は、IRQ の CPU バインドにおいてユーザが指定したビット・マスクである ことに注意します。“actual”に返された値は、存在していない CPU 及びマスクからシールドさ れている CPU 取り除かれた後の結果としての結果になることに注意します。もしもユーザが シールドされている及びシールドされていない CPU 両方を含むバインドマスクをセットすれば、 シールドされている CPU は IRQ のバインドマスクから切り取られるだけだということに注意し ます。これは、もしも IRQ の相性マスク内に割り込みを扱うことができるシールドされていない CPU がなければ、割り込みからシールドされている CPU は割り込みを扱うだけだからです。 この例では、CPU 1 は割り込みからシールドされていますが、しかし、CPU 1 は IRQ28 を扱 います。なぜなら、そのバインドマスクは CPU 1 のみが割り込みを扱うことを許されていると 指定しているからです。 次のステップは、RCIM のエッジ・トリガ割り込みに応答しているプログラムがシールドされて いる CPU 上で走ることを確認することです。システム内のそれぞれのプロセスは割り当てら れた CPU アフィニティマスクを持ちます。バックグランド・プロセスからシールドされている CPU においては、シールドされた CPU のみを指定している CPU バインドマスクを持つプロ セスのみが、シールドされている CPU 上で走ることを許されます。もしもプロセスのバインド マスク内にシールドされていない CPU があれば、プロセスはシールドされていない CPU 上で 実行するのみであることに注意します。 以下のコマンドはリアルタイム・プライオリティでユーザ・プログラム“エッジ・ハンドラ”を実行し、 そして CPU 1 上で走ることを強制します。 $ run –s fifo –P 50 –b 1 edge-handler プログラムはさらに、“mpadvise を使用するマルチ CPU 制御”のセクションで述べられたよう に、ライブラリ・ルーチン mpadvise (3)を呼び出すことによって、それ独自の CPU バインドを セットすることができることに注意します。 2-25 SUSE Linux Enterprise Real Time Linux User’s Guide run (1)コマンドは、プログラムの結合をチェックするために使用することができます。 $ run –i –n edge-handler Pid Tid Bias Actual Policy Pri Nice Name 9326 9326 0x2 0x2 fifo 50 0 edge-handler “bias”へ返された値は、プロセスの CPU バインドにおいてユーザが指定したビット・マスクで あることに注意します。“actual”へ返された値は、存在しない CPU 及びシールドされている CPU がマスクから取り除かれた後の結果としての結合になります。もしもユーザがシールドさ れている及びシールドされていない CPU 両方を含むバインドマスクをセットすれば、シールド されている CPU はプロセスのバインドマスクから離されるだけだということに注意します。こ れは、プログラムを走らせるプロセスのバインドマスク内にシールドされていない CPU が無 ければ、バックグランド・プロセスからシールドされている CPU はプロセスを扱うだけだからで す。この例では、CPU 1はバックグランド・プロセスからシールドされていますが、CPU 1は、 “edge-handler”プログラムを走らせます。なぜなら、そのバインドマスクは CPU 1のみがこ のプログラムを走らせることを許されていると指定しているからです。 決定性を向上させる手順 以下のセクションでは、次のテクニックを使用してパフォーマンスを向上させる様々な方法に ついて説明します。 z メモリ内でプロセスのページのロッキング z 望ましい静的プライオリティ割り当ての使用 z 割り込みレベルから決定的でないプロセスを取り除きます。 z プロセスの高速なウェイクアップ z キャッシュアクセスの制御 z 物理メモリの予約 z NUMA システム上でのローカルメモリへのプログラム割付 z ハイパー・スレッドの使用の可否 z 空きメモリが少ない状態を避ける メモリ内のページのロッキング mlockall (2)、munlockall (2)、mlock (2)、及び munlock (2)を使用してページング及びス ワッピングと結合しているオーバーヘッドを回避することができます。これらのシステムコール によって、物理メモリ内のプロセスのバーチャル・アドレス空間の全てまたは一部をロックしそ して、アンロックすることができます。これらのインターフェイスは IEEE 標準 1003.1b-1993 に 基づいています。 2-26 SUSE Linux Enterprise Real Time Linux User’s Guide これらの呼び出しそれぞれで、呼び出し時に常駐していないページはメモリ・フォルトされ、そ してロックされます。mlcokall (2)、munlockall (2)、mlcok (2)及び munlock (2)システムコ ールを使用するためには、CAP_IPC_LOCK 及び CPS_SYS_RAWIO ケーパビリティがな ければなりません(ケーパビリティに関する追加的情報については、12 章、及び pam_capability (8) man page を参照してください)。 これらのシステムコールの使用における手順は、対応する man page で完全に説明されてい ます。 プログラム・プライオリティの設定 SUSE Linux Enterprise Real Time カーネルは、静的プライオリティ・スケジューリングを許 容しています。つまり、ある程度の POSIX スケジュール・ポリシー下でスケジュールされたプ ロセスのプライオリティは、それらのラン時間動作への応答におけるオペレーティング・システ ムによって変更されません。 POSIX リアルタイム・スケジューリング・ポリシーの1つの元でスケジュールされているプロセ スは、常に静的プライオリティを持ちます。(リアルタイム・スケジューリング・ポリシーは、 SCHED_RR 及び SCHED_FIFO です。それらは4章で説明されています。)プロセスのスケ ジ ュ ー リ ン グ ・ プ ラ イ オ リ テ ィ を 変 更 す る に は 、 sched_setscheduler (2) 及 び sched_setparam (2)システムコールを使用します。プロセスののプライオリティをさらに高 い(より好ましい)値へと変更するためにこれらのシステムコールを使用するには、 CAP_SYS_NICE ケーパビリティがなければなりません(これらのルーチンの使用における 必要ケーパビリティに関する完全な情報については、対応する man page を参照してくださ い)。 ある特定の CPU 上を走る最高プライオリティ・プロセスは、最良のプロセスディスパッチレイ テンシィを持ちます。CPU 上を走っている他のプロセスよりも高いプライオリティをプロセスが 割り当てられていなければ、そのプロセスディスパッチレイテンシィは、より高いプロセスが動 作する時に影響されます。結果として、よいプロセスディスパッチレイテンシィを要する1つ以 上のプロセスがあるなら、これらのプロセスをいくつかの CPU 間に分散することが薦められ ます。 特定の CPU へ割り当てることにおける手順については、“CPU へのプロセスの付与”のセク ションを参照してください。 2-27 SUSE Linux Enterprise Real Time Linux User’s Guide プロセス・スケジュールについては、4章で完全に説明されています。sched_setscheduler 及び sched_setparam システムコールを使用してプロセスのプライオリティを変更する手順 についても説明されています。 遅延されている割込みプロセスのプライオリティの設定 Linux は、そうしなければ割り込みレベルで行われるプロセスを遅延するために、割り込みル ーチンが使用するいくつかのメカニズムをサポートしています。デバイス割り込みを扱うのに 要されるプロセスは、2 つの部分に分けられます。最初の部分は割り込みレベルで実行し、 割り込み完了プロセスの最もクリティカルな局面のみを扱います。第 2 の部分は、プログラ ム・レベルで走らせるために遅延されます。割り込みレベルから非クリティカル・プロセスを取 り除くことによって、この章の“割り込みの効果”で先に説明されたように、システムはよりよい 割り込み応答を得ることができます。 どの遅延されている割り込みテクニックがデバイス・ドライバによって使用されているのかに 依拠して、カーネル・デーモンが割り込みルーチンの第 2 の部分を扱います。遅延されている 割り込みプロセスを扱うカーネル・デーモンのプライオリティをシステム管理者が設定すること を可能にする、チューニング可能なカーネルがあります。遅延されている割り込みを扱ってい る CPU 上でリアルタイム・タスクが実行する時、遅延されている割り込みカーネル・デーモン のプライオリティを設定することが可能であり、よって高プライオリティ・ユーザ・プロセスは、 遅延されている割り込みカーネル・デーモンに比し、より好ましいプライオリティを持ちます。こ れによって、このリアルタイム・プロセスにおいてより決定的な応答時間を可能にします。 使用されているデーモン及びそれらのプライオリティの設定においてチューニング可能なカー ネルを含む遅延されている割り込みプロセスに関する更なる情報については、“デバイス・ド ライバ”の章を見てください。 他のプロセスのウェイクアップ 複数プロセス・アプリケーションの中では、しばしばプロセスをウェイクアップてある特定のタ スクを動作させる必要があります。システムの応答性の1つの計測の方法は、1つのプロセ スが他のプロセスを呼び起こすスピードです。このスイッチから他のタスクへと動作させるの に使用する最速の方法は、postwait (2)システムコールを使用することです。継承コードとの 互換性のために、server_block (2)及び server_wakel (2)関数が SUSE Linux Enterprise Real Time では提供されています。 これらのケーパビリティの使用における手順は、このガイドの5章で説明されています。 2-28 SUSE Linux Enterprise Real Time Linux User’s Guide キャッシュアクセスの制御 アプリケーションのライターが「不変のランタイム決定論」をアプローチしようとしているなら、 プログラムの変数が CPU のキャッシュにマップされる方法に注意を払わなくてはなりません。 例えば、もしプログラムが変数iと変数jを持ってい、そして両方ともが頻繁に使われ、そしてそ れらに割り当てられたメモリの場所がiとjの両方が同じキャッシュラインにあるという結果にな るなら、iに対するすべての参照がjをキャッシュから排出するでしょう、そして逆もまた同様で す。 これはキャッシュスラッシング状態と呼ばれます、そしてその発生はパフォーマンスに致 命的です。 これを避けるために、お互いに近いすべての頻繁にアクセスされたデータをメモリに置いてく ださい。 もしその範囲がキャッシュの大きさより小さいなら、すべてのデータは保証された異 なったキャッシュラインにあるでしょう。 CPU のキャッシュが大きいかどうかを見るために 「grep キャッシュ / proc / CPUinfo」を実行する方法があります。 あなたのシステムが頻繁にアクセスされた変数のデータセットより大きいキャッシュを持って いることを確認してください。 例えば、もしあなたが600,000バイトの変数を持ってい、そし てあなたがたった.5MBのキャッシュでシステムを受けるなら、キャッシュがスラッシング状態 になっていることは避けられないでしょう。 もしあなたが重大な変数が1ページ以下(4096バイト)をであるなら、あなたはそれらに、す べてのデータに1つの物理的なページにあることを強いることによって:別個のキャッシュライ ンにあることを強いることができます; struct mydata{ int i; int j; float fp[200]; floag fq[200]; } __attribute__((__aligned__(4096))); struct mydata mydata; 物理メモリの予約 /etc/grub.conf ファイルでコマンドライン引数を使用する事で、物理的なメモリを予約すること ができます。 現在、これは EM64T システムでは利用できません。 このタイプの割付は PCI-VME アダプターのような、 iHawk メモリにマップされる外部のホス ト装置の DMA バッファのために使われます。 また、ダイナミックな仮想メモリアロケーター の影響を排除して連続的なページのデータ空間を提供するために使うことができます。 これ は、それで実行時に大きいデータ・アレイのプロセスの連続的なアクセスからキャッシュ衝突 減らしてアプリケーションパフォーマンスを改善することが出来ます。 マッピングメモリと /etc/grub.conf ファイルで、 RAM の”reserved”セクションを得ることが できます。 システムV shmop (2)機能は物理的なメモリのこの領域にアクセスするために 2-29 SUSE Linux Enterprise Real Time Linux User’s Guide 使うことができます。 shmconfig (1)あるいは shmbind (2)と shmop (2)機能がこのメ モリパーティションを作って、そしてそれにアタッチするために使うことができます。 こ こ で 下 記 i386 シ ス テ ム に 示 さ れ る よ う に 、 利 用 可 能 な 物 理 的 な RAM の 量 は /proc/iomem の中身を調べることによって、見ることができます。 $ cat /proc/iomem 00000000-0009ffff : System RAM 000a0000-000bffff : Video RAM area 000c0000-000cefff : Video ROM 000d0800-000d3fff : Adapter ROM 000f0000-000fffff : System ROM 00100000-7fe8abff : System RAM 00100000-0055c7dd : Kernel code 0055c7de-006ffbff : Kernel data 7fe8ac00-7fe8cbff : ACPI Non-volatile Storage 7fe8cc00-7fe8ebff : ACPI Tables 7fe8ec00-7fffffff : reserved . . (I/O entries removed from example) “System RAM”で表わされた領域はアロケーションのために利用可能な物理的なメモリを表 します。 どのように物理的な RAM を予約するべきか例示する /etc/grub.conf の例が16進数(10 進数での例が続きます)で下に示されます。 grub.conf に置かれたコマンドはメモリのマッピ ングを引き起こすブート時に処理されます。 「memmap = exactmap」エントリは正確な BIOS マップが使われることを明示します。 残っているエントリは定義される領域を指定します。コマンドフォーマットは以下のようになり ます: memmap=size<デリミタ>address ‘@’ である場合 System RAM, <デリミタ>が ‘$’ である場合 予約メモリ、 “#” である場合 ACPI を示します。 次の例は 1G のアドレスのすぐ下に32MBを予約します。 default=0 timeout=10 splashimage=(hd0,0)/grub/ccur.xpm.gz title SUSE Linux Enterprise Real Time 2.3 (Trace=Yes, Debug=No) root (hd0,0) kernel /vmlinuz-2.6.9-SUSE root=/dev/sda2 vmalloc=256M ¥ memmap=exactmap ¥ memmap=0xa0000@0x0 ¥ 2-30 Linux Enterprise Real Time-2.3-trace ro SUSE Linux Enterprise Real Time Linux User’s Guide memmap=0x3df00000@0x100000 ¥ memmap=0x2000000$0x3e000000 ¥ memmap=0x3fe8ac00@0x40000000 エントリー“memmap=0x3df00000@0x100000”は、カーネルコードとカーネルデータを含むシス テム RAM 全体をカバーしてメモリを予約します。 3 2 M B の 予 約 は エ ン ト リ ー ”memmap=0x2000000$0x3e000000” ( 0x3e000000 0x2000000 + = 0x40000000)によって物理的なメモリの1GB(0x40000000)の終わりに宣言さ れます。 メモリの場所が /proc/iomem リストで「System Ram」と認知されて、そしてカーネルアドレスを含 まない限り、この予約されている領域は独断的に選択することができます。 領域「アダプター ROM」、「システム ROM」、「ACP」と「reserved」はこれらのコマンドを使って map を作り直されて はなりません。 エントリー“memmap=0x3fe8ac00@0x40000000”は /proc/iomem で見た「ACPI Non-volatile Storage」領域からの予約されている場所の終わりを引くことから生じます(0x7fe8ac00 0x40000000 - = 0x3fe8ac00)。 注意 これらの項目が予約されている領域(例えばシステム ROM など)で重なり合っていることで引き 起こされたエラーはカーネルをブートしている時に致命的エラーを発生します。 それは上の16進数例とまったく同じであって、そして同一の結果を作り出します。 次の例は10進のアドレスを使います。: default=0 timeout=10 splashimage=(hd0,0)/grub/ccur.xpm.gz title SUSE Linux Enterprise Real Time 2.3(Trace=Yes, Debug=No) root (hd0,0) kernel /vmlinuz-2.6.9-SUSE Linux Enterprise Real Time-2.32-trace ro root=/dev/sda2 vmalloc=256M ¥ memmap=exactmap ¥ memmap=640K@0 ¥ memmap=991M@1M ¥ memmap=32M$992M ¥ memmap=1047083K@1G 表わされた領域“System RAM”はアロケーションのために利用可能な物理的なメモリを表しま す。 どのように物理的な RAM を予約するべきか例示する /etc/grub.conf の例が16進数(10進数 での例が続きます)で下に示されます。 grub.conf に置かれたコマンドはメモリのマッピングを引 2-31 SUSE Linux Enterprise Real Time Linux User’s Guide き起こすブート時に処理されます。 下 は 上 記 の 例 で さ れ る 予 約 の 前 と 後 の メ モ リ の 比 較 で す 。 “after reservation” marked “reserved” 0x3e000000 においての領域が newly reserved な32MBの領域です。 /proc/iomem before reservation /proc/iomem after reservation 00000000-0009ffff : System RAM 00000000-0009ffff : System RAM 000a0000-000bffff : Video RAM area 000a0000-000bffff : Video RAM area 000c0000-000cefff : Video ROM 000c0000-000cefff : Video ROM 000d0800-000d3fff : Adapter ROM 000d0800-000d3fff : Adapter ROM 000f0000-000fffff : System ROM 000f0000-000fffff : System ROM 00100000-7fe8abff : System RAM 00100000-3dffffff : System RAM 00100000-0055c7dd : Kernel code 00100000-00558a49 : Kernel code 0055c7de-006ffbff : Kernel data 00558a4a-006fbbff : Kernel data 7fe8ac00-7fe8cbff : ACPI Non-volatile Storage 3e000000-3fffffff : reserved 7fe8cc00-7fe8ebff : ACPI Tables 40000000-7fe8abff : System RAM 7fe8ec00-7fffffff : reserved . . . . . 次の例は Opteron システムで4GBで向こうの2つのシステム RAM 領域の間にメモリ領域を予 約する grub.conf に置かれたコマンドを例証します。 この予約の前に出力された /proc/iomem は次のページに対して示されます。 注意:Opteron システムでは、”mm”が”memmap”のエイリアスで、”ex”が”exactmap”のためのエ イリアスです。 これらのより短いエイリアス名はgrubコマンドライン毎に256の文字の限界がある ので、予約されているエリアを準備するために必要とされる文字数を減らすために使われます。 mm=ex ¥ mm=0x9fc00@0x0 ¥ mm=0x400@0x9fc00 ¥ mm=0x20000$0xe0000 ¥ mm=0xcfef0000@0x100000 ¥ mm=0x10000#0xcfff0000 ¥ mm=0x840000$0xff7c0000 ¥ mm=512M@0x100000000 ¥ mm=512M$4608M ¥ 2-32 SUSE Linux Enterprise Real Time Linux User’s Guide mm=1G@5G 2-33 SUSE Linux Enterprise Real Time Linux User’s Guide 下記は上記の例の”reserved”前と後のメモリの比較です。“after reservation”の 0x0000000120000000 の”reserved”とマークを付けた領域が新たに予約された領域です。 /proc/iomem before reservation /proc/iomem after reservation 0000000000000000-000000000009fbff : System RAM 0000000000000000-000000000009fbff : System RAM 000000000009fc00-000000000009ffff : reserved 000000000009fc00-000000000009ffff : System RAM 00000000000a0000-00000000000bffff : Video RAM area 00000000000a0000-00000000000bffff : Video RAM area 00000000000c0000-00000000000c7fff : Video ROM 00000000000c0000-00000000000c7fff : Video ROM 00000000000c8000-00000000000cbfff : Adapter ROM 00000000000c8000-00000000000cbfff : Adapter ROM 00000000000f0000-00000000000fffff : System ROM 00000000000f0000-00000000000fffff : System ROM 0000000000100000-00000000d7feffff : System RAM 0000000000100000-00000000cffeffff : System RAM 0000000000100000-00000000005c9521 : Kernel code 0000000000100000-00000000005c9521 : Kernel code 00000000005c9522-0000000000954137 : Kernel data 00000000005c9522-0000000000954137 : Kernel data 00000000d7ff0000-00000000d7ffefff : ACPI Tables 00000000cfff0000-00000000cfffffff : ACPI Tables 00000000d7fff000-00000000d7ffffff : ACPI Non-volatile Storage 00000000ff7c0000-00000000ffffffff : reserved 00000000ff7c0000-00000000ffffffff : reserved 0000000100000000-000000011fffffff : System RAM 0000000100000000-000000017fffffff : System RAM 0000000120000000-000000013fffffff : reserved . 0000000140000000-000000017fffffff : System RAM . . . . (I/O entries removed from example) shmconfig (1)あるいは shmbind (2)が予約されている物理アドレスにおいて仕切りを作る ために使われることができます。 shmop (2)、共有されたメモリオペレーション、はアプリケ ーションによって領域へのアクセスを増すために使われることができます。 次の例は i386 システムでこのセクションで与えられた最初の例に基づいています: /usr/bin/shmconfig -s 33554432 -p 0x3e000000 -m 0777 6602 が無制限のアクセスと6602のキーで物理アドレス 0x3e000000 において32MBのシステ ムVメモリパーティションを作ります。 あるいは 2-34 SUSE Linux Enterprise Real Time Linux User’s Guide paddr = 0x3e000000 ; shmkey = 6602 ; . . shmid = shmget ( shmkey, sizeof ( <shared_region > ) , SHM_R | SHM_W | IPC_CREAT) ; shmstat = shmbind ( shmid , paddr ) ; . . pstart = shmat ( shmid , NULL , SHM_RND ) ; もっと多くのこれらの機能を使うことについての情報は man page あるいは3章を参照してく ださい。 NUMA システム上での、ローカルメモリへのプログラム割付 iHawk Opteron システムでの非ユニフォームメモリアクセス(NUMA)システムでは、他のも のよりメモリ領域にアクセス時間はもっと長くかかります。 NUMA システムのメモリはノード に分けられます、そしてそこでノードがメモリと NUMA ノードのメモリ領域と同じ物理的なバ スで位置するすべての CPU の領域であるために定義されます。もしこのタイプのシステム上 で走っているプログラムが NUMA-aware なら、それは不完全に実行することができます。 デフォルトで、ページが(そこからプログラムが実行されます)ローカルな CPU が位置するノ ードから割り当てられます、しかしタスクの中のタスクあるいは仮想領域は、特定のノードか らもっと良い決定論とコント role にページを割り当てるために指定することができます。 NUMA についての詳細な情報は、10章を参照してください。 2-35 SUSE Linux Enterprise Real Time Linux User’s Guide Quad Opteron システムの入出力スループット 4つの Opteron SMP システムでは、すべてのプロセッサが直接プロセッサに取り付けられ た固有のバンクメモリを持っています。 システムでのすべてのメモリが HyperTransport によってどんなプロセッサからでもアクセスすることができます、しかし直接プロセッサに付け られたメモリが最も速いアクセス出来るメモリです。 このレイアウトは図2-7で示されます。 Opteron システムでの I/O デバイスへのアクセスはメモリとは同じではなく対称です。 I/O ハブと PCI トンネルはシステムで直接特定のノードに付けられます。 図2-7で、 I/O ハブはノード0に付けられます、そして PCI トンネルはノード1とつながって います。 テストの結果、プログラム I/O を行なっているプログラムが装置が位置する I/O バスに取り 付けられたノード上で走っているとき、I/O 時間が、共により速くて、そしていっそう決定論的 であることを示しました。 HyperTransport 相互接続のために論争があるとき、 I/O パフォーマンスに対する効果は、 他のプログラムが I/O あるいはローカルでないメモリオペレーションを行なっているから特に 目立ちます。 これはもしアプリケーションが高速の決定論的なプログラムされた I/O を要求するなら、この ような I/O を行なっているプログラムが装置が居住する I/O バスに最も近いプロセッサ上 で走ることに疑いがないべきであることを意味します。 I/O ブリッジに結び付けられるノードは、システム概略図を見ることによって、あるいは、テス トをすることによって、決定し得ます。 テストプログラム、 histogram.c 、がディレクトリ /usr/share/doc/ccur/examples/numa. で供給されます。 このプログラムは並列にシステム ですべての CPU 上で走らせるべきです。 プログラム I/O をすることに対して、最少の量の 時間に達成された読み取りの最大の数を持っているノードは最適なノードです。 2-36 SUSE Linux Enterprise Real Time Linux User’s Guide ハイパー・スレッディングの理解 ハイパー・スレッディングは、iHawk 860 システムの Intel Pentium XeonCPU の機能です。 それは、単一の物理 CPU がソフトウェア・アプリケーションのマルチスレッディングを同時に 走らせることを可能にします。CPU 実行リソースの1つのセットを共有している間、それぞれ の CPU 上で 2 つの構造的状態をもつことによって、これは達成されます。構造的状態はプロ グラムまたはスレッドの流れを追跡し、そして実行リソースは、加える、多重するなどの動作 を行う CPU 上のユニットです。ハイパー・スレッディング物理 CPU 内の構造的状態の 2 つの セットのそれぞれは、“論理的”CPU であるとみなされます。 用語“sibling CPU”は、同じ物理 CPU に常駐する論理 CPU のペアの中の他の CPU を意味 します。 スレッドをスケジュールする際、オペレーティング・システムは物理 CPU 上の 2 つの論理 CPU をあたかも別々の CPU であるかのように扱います。ps (1)または shield (1)のようなコ マンドは、それぞれの論理 CPU を識別します。これにより、マルチ CPU 可能ソフトウェアが、 2 倍の論理的 CPU 上で修正されずに走ることを可能になります。ハイパー・スレッド技術は、 第 2 の物理 CPU を加えることによって得られるパフォーマンス能力提供しませんが、いくつ かのベンチマーク試験は、並列アプリケーションはパフォーマンスにおいて30 パーセントの 増加の収穫を得ていることを示しています。リアルタイム・アプリケーションにおいて、どのよう にして最良にハイパー・スレッドを使用するのかにおける示唆については、“推奨される CPU コンフィグレーション”のセクションを見てください。 ハイパー・スレッドによるパフォーマンスの向上が起こるのは、2 つの論理 CPU の1つの CPU が、より効率的に実行リソースを使用するからです。非ハイパー・スレッドの CPU 上の 通常のプログラム・オペレーションの間、チップ上の実行リソースは入力待ちをしてアイドリン グしています。2 つの論理 CPU が実行リソースの1つのセットを共有できるので、第 2 の論理 CPU 上で実行しているスレッドは、そうでなければ1つだけのスレッドの実行でアイドリングさ れていたリソースを使用できます。例として、1つの論理 CPU が完了するためにメモリからの フェッチを待って往生している間に、その sibling CPU は自分の命令ストリームを処理しつづ けることができます。CPU のスピードとメモリ・バスは、とても非均等なので、CPU はデータが メモリから来るのを待つのにかなりの時間を費やすします。よって、ある程度の並列アプリケ ーションにおいては、ハイパー・スレッドはかなりのパフォーマンス向上を提供します。並列性 のその他の例は、他の CPU が加算及びロード・オペレーションを実行している間に、1つの 論理的 CPU が浮動小数点オペレーションを実行することです。これらのオペレーションは並 列的に実行します。なぜなら、それらはチップ上の異なる CPU 実行ユニットを利用するから です。 2-37 SUSE Linux Enterprise Real Time Linux User’s Guide 複数スレッド作業負荷において、ハイパー・スレッディングは一般的により速い実行を提供し ますが、それはリアルタイム・アプリケーションにおいては問題があることです。これは、スレッ ド実行の決定性上の影響によるものです。ハイパー・スレッドされている CPU は他のスレッド と CPU の実行ユニットを共有しますが、ハイパー・スレッドされている CPU 上でスレッドが実 行する際、実行ユニットそのものはリソース争いの他のレベルになるからです。ハイパー・ス レッドされている CPU 上の高プライオリティ・プロセスが命令を実行しようとする際、実行ユニ ットは常に利用可能ではないため、ハイパー・スレッドされている CPU 上のコード・セグメント を実行するのにかかる時間量は、ハイパー・スレッドされていない CPU ほどには予測可能で はないからです。 並列リアルタイム・アプリケーションの設計者は、そのアプリケーションにおいて、ハイパー・ス レッドが理にかなうかどうかを決断しなければなりません。逐次的に走る場合に比して、ハイ パー・スレッドされている CPU 上で並列にタスクを走らせる事からアプリケーションが恩恵を 得るか、もしそうなら、開発者はそれらをハイパー・スレッドされている CPU 上で走らせること によって、重要な高プライオリティ・スレッドの実行スピードの中へどれほどのジッタ-が入る かを確認するための計測を行うことができます。 受容可能なジッタ-のレベルは、アプリケーションに大きく依存しています。ハイパー・スレッ ドによってもしリアルタイム・アプリケーションの中へ受容不可な量のジッタ-が入れられれば、 影響されたタスクは CPU (1)コマンド経由でダウンされたその sibling CPU と共にシールドさ れた CPU 上を走ります。CPU がダウンされたシステムの例は、この章の後で述べられます。 ある程度の CPU 間割り込みが、ダウンされた CPU 上でも扱われることに注意します(更なる 情報については、CPU (1) man page を見てください)。もし望まれれば、ハイパー・スレッドは システムで禁止されます。詳細については、下の“システム・コンフィグレーション”を見てくだ さい。 ハイパー・スレッディング技術は、システム内のそれぞれの CPU 内でより大きな並列性を提 供することによる、複数プロセスへの補足的なものです。しかし、二重または複数プロセスへ の置き換えではありません。システムが利用可能な 2 倍の論理的 CPU がありますが、しかし、 それらは依然として実行リソースの同じ量を共有しています。よって、それ独自の専心された 実行リソースでの他の物理 CPU のパフォーマンスは、より高いパフォーマンス・レベルを提供 します。これは、決定的実行環境においてシールドされている CPU を使用するアプリケーシ ョンにおいて、特に当てはまります。 上で述べられたように、それぞれの論理 CPU は、アーキテクチャ状態の完全なセットを維持 2-38 SUSE Linux Enterprise Real Time Linux User’s Guide しています。アーキテクチャ状態(それは sibling CPU によって共有されていません)は、一般 目的レジスタ、制御レジスタ、進歩したプログラム可能な割り込みコントローラ(APIC)、及び いくつかのマシーン状態レジスタから構成されます。論理的 CPU は物理 CPU 上に、キャッシ ュ、実行ユニット、ブランチ予測値、制御ロジック、及びバスのようなほとんど全ての他のリソ ースを共有しています。それぞれの論理 CPU はそれ独自の割り込みコントローラまたは APIC を持っています。特定の論理 CPU へ送られた割り込みは、ハイパー・スレッディングが 許可であるか禁止であるかに関係無く、その論理 CPU によってのみ扱われます。 システム・コンフィグレーション 以下の項目は、システムのハイパー・スレッドの利用する場合に影響を与えます。 ・ システムは、Intel Pentium Xeon CPU を含まなければなりません。 ・ カーネルは、カーネル・コンフィグレーション GUI 上の Processor Type and Features 下 で X86_HT チューニングパラメータでハイパー・スレッドを許可し、コンフィグされていなけ ればなりません。ハイパー・スレッディングは全ての SUSE Linux Enterprise Real Time i386 ディフォルト定義のカーネル上でデフォルトとして許可されています。 ・ ハイパー・スレッドは、BIOS 内で利用可能に許可されていなければなりません。もし必要 ならば、どの BIOS 設定が成されているのかを決定するために、ハードウェア・ドキュメン トを参照してください。 ハイパー・スレッディングは、CPU 単位で CPU (1)コマンドを使用して sibling CPU の1つをダ ウンさせて、禁止することができます。更なる詳細については、CPU (1)の man page を参照 してください。 ハイパー・スレッディングが許可されていれば、top (1)及び run (1)のようなコマンドは、ハイ パー・スレッディングのサポートを持っていなかったリリース 1.3 以前の SUSE Linux Enterprise Real Time のバージョンを走らせているシステム上で存在していた 2 倍の数の CPU をレポートすることに注意してください。ハイパー・スレッディングがシステム・ワイド・ベー スで禁止されている時、論理 CPU の数は物理 CPU の数と同じです。 推奨 CPU コンフィグレーション ハイパー・スレッディング技術は、並列アプリケーションにおいて、よりよいパフォーマンスの 可能性を提供します。しかし、単一の物理 CPU 上の論理 CPU 間で CPU リソースが共有さ れるため、異なるアプリケーションの組合せが、異なるパフォーマンス結果を生みます。これ は、アプリケーションがクリティカル実行時間を要するリアルタイム要求をする時に、特にそう です。よって、最適のパフォーマンスを決定するために様々な CPU コンフィグレーション下で アプリケーションのパフォーマンスを評価することが重要です。例として、sibling CPU のペア 2-39 SUSE Linux Enterprise Real Time Linux User’s Guide 上で並列に走っている 2 つのタスクがあれば、両方の sibling CPU を使用して並列にこれら のタスクを実行するのに要する時間と、sibling CPU の1つをダウンして順次にこれらのタス クを実行するのに要する時間とを比較しなければなりません。これは、これら 2 つのタスクが ハイパー・スレッディングが提供するユニークな並列性の利点を得ることができるか否かを決 定します。 以下は、リアルタイム・アプリケーションにおける、ハイパー・スレッドされている CPU を含む SMP システムをコンフィグレーションする示唆的方法です。これらの例は、様々なパフォーマ ンス特性を持つアプリケーションが最良に動作するコンフィグレーションについての示唆を含 みます。 標準的なシールドされている CPU モデル このモデルは、プログラム実行における決定性において厳密な要求を持つアプリケーション に使用されます。シールドされている CPU は、これらのような種類のタスクにおいて最も決定 的な環境を提供します(シールドされている CPU に関する更なる情報については、“シール ディングはどのようにしてリアルタイム動作を向上させるのか”のセクションを見てください)。 シールドされている CPU の決定性を最大化するためにその物理 CPU のハイパー・スレッド は禁止されます。これは、CPU (1)コマンドを使用して、シールドされている CPU の論理 sibling CPU をダウンさせることによって達成されます。 標準的なシールドされている CPU モデルの中では、シールドされていない CPU は、ハイパ ー・スレッディングが許可されています。一般的に、ハイパー・スレッディングは更なる CPU リ ソースの適用を可能にするため、これらの CPU は、非クリティカル作業負荷に使用されま す。 図 2-7 は、2 つの物理 CPU(4つの論理 CPU)を持つシステム上の標準的なシールドされて いる CPU のモデルを示しています。この例では、CPU3はダウンされ、CPU2 は割り込み、プ ロセス、及びハイパー・スレッディングからシールドされています。高プライオリティ割り込み及 びその割り込みに応答するプログラムは、その割り込みに対して最も決定的な応答のために、 CPU2 に割り当てられます。 2-40 SUSE Linux Enterprise Real Time Linux User’s Guide 図 2-7 標準的なシールドされた CPU モデル このコンフィグレーションをセット・アップするコマンドは: $ shield –a 2 $ CPU –d 3 割り込みアイソレーションでのシールディング このモデルは、標準的なシールドされている CPU モデルにとても似ています。しかし、このケ ースでは全ての論理 CPU が使用され、ダウンされていません。標準的なシールドされている CPU モデルのように、論理 CPU のサブセットはシールドされています。しかし、シールドされ ている sibling CPU をダウンさせるのではなく、これらの CPU はシールドされ、そして決定的 割り込み応答を要する高プライオリティ割り込みの扱いに専心されます。これは、sibling CPU をプロセス及び割り込みからシールドし、そしてその sibling CPU への特定の割り込み の CPU バインドを設定することで達成されます。 割り込みアイソレーションでのシールディングは、図 2-8 で説明されています。 2-41 SUSE Linux Enterprise Real Time Linux User’s Guide 図 2-8 割り込みアイソレーションでのシールディング このアプローチの利点は、それが割り込みルーチン(CPU3 上を走っています)と、sibling CPU(CPU2 上での割り込み動作を待っているプログラム)上での高プライオリティ・タスクの 実行との間に小さな量の並列性を提供することです。割り込みルーチンは、CPU3 上で実行 している 1 つのコードのみであるため、この割り込みルーチンは一般的に、その全体におい て L1 キャッシュ内に保持され、そしてコードはキャッシュ内にとどまり、割り込みルーチンにお いて最適実行時間を提供します。しかし、支払わなければならない少しのペナルティがありま す。なぜなら、割り込みルーチンは、sibling CPU 上のこの割り込みを待っているタスクを呼 び起こすために CPU 間割り込みを送らなければならないからです。この追加的オーバーヘッ ドは、2 マイクロ秒以下であると計測されています。 割り込みアイソレーションでのシールディングを使用する、他の潜在的使用は、デバイスにお ける IO スループットを向上させることです。デバイス割り込みの扱いに CPU を専心させてい るため、IO オペレーションが完了するとともに、この割り込みは常に完了します。これによっ て割り込みルーチンは高速に次の IO オペレーションを開始し、よりよい IO スループットを提 供します。 ハイパー・スレッドされているシールディング このコンフィグレーションは、標準的なシールドされている CPU モデルの別種です。このケー スでは、他の sibling CPU が一般的タスクを走らせることを許されている間、1 つの sibling CPU はシールドされています。シールドされている CPU は、その sibling CPU 上の動作に影 響されたその決定性を持ちます。しかし利点は、この物理 CPU の CPU パワーの更なるもの が、アプリケーションによって利用することです。図 2-9 は、ハイパー・スレッド・シールディン グ・コンフィグレーションを説明しています。 2-42 SUSE Linux Enterprise Real Time Linux User’s Guide 図 2-9 ハイパー・スレッドされているシールディング この例では、CPU 3 はシールドされており、そして高プライオリティ割り込み及びその割り込 みに応答するプログラムのみを走らせることが許されています。CPU 2 はシールドされておら ず、よって一般的使用に利用可能か、または特定のタスクのセットを走らせるように設定され ています。CPU 2 上を走るタスクは直接的には割り込み応答時間に影響を与えません、なぜ なら、それらがプリエンプションの禁止または割り込みのブロックをする時、高プライオリティ 割り込みまたは CPU3 上を走っているタスクに影響を与えないからです。しかし、チップ・リソ ース・レベルでは、CPU 3 上の実行の決定性に影響を与える競合があります。影響の大きさ は、とてもアプリケーションに依存します。 浮動少数点/整数共有 このコンフィグレーションは、主に浮動小数点オペレーションを行うプログラム、及び主に整数 算術オペレーションを行うプログラムをアプリケーションが持つ時に使用されます。ハイパー・ スレッドされている CPU の両方の sibling が特定のタスクを走らせるのに使用されます。浮動 小数に集中的なプログラムは、1 つの sibling CPU に割り当てられ、そして主に整数オペレー ションを行うプログラムは、他の sibling CPU に割り当てられます。このコンフィグレーション の利点は、浮動小数点オペレーション及び整数オペレーションが異なるチップ・ソースを使用 することです。これによって、アプリケーションはハイパー・スレッド・スタイルの並列性を有効 利用することができます。なぜならチップ・レベルでは、利用できる更なる並列性があるからで す。整数オペレーションを動作しているだけの CPU 上のアプリケーションには、コンテキスト・ スイッチの間浮動小数点レジスタの保存/復活が無いため、より速いコンテキスト・スイッチ があることにも注意します。 共有データ・キャッシュ このコンフィグレーションは、アプリケーションがアプリケーションの生産/消費スタイルであ る時に使用されます。換言すれば、1つのプロセス(消費者)が、他のプロセス(生産者)から 2-43 SUSE Linux Enterprise Real Time Linux User’s Guide 渡されたデータを動作しています。この場合、生産及び消費スレッドは、ハイパー・スレッドさ れている sibling CPU へ割り当てられます。2 つの sibling CPU がデータ・キャッシュを共有し ているため、消費プロセスが生産タスクから渡されたデータにアクセスしている際、生産プロ セスによって生産されたデータがまだデータ・キャッシュの中にあることが多いのです。この方 法で 2 つの sibling CPU を使用することによって、生産及び消費タスクが並列的に動作する ことができ、そして、それらの間で渡されたデータは、本質的には高スピードのキャッシュ・メ モリ経由で渡されます。これは、ハイパー・スレッド・スタイルの並列性を利用することにおい て、重要な機会を提供します。 このモデルの他の潜在的使用は、1つの sibling CPU 上のプロセスが、ハイパー・スレッドさ れている CPU 上の他の sibling CPU 上を走るプロセスにおいて、データ・キャッシュの中へ データをあらかじめフェッチすることです。 シールドされた単一 CPU このコンフィグレーションは、ハイパー・スレッドされているシールディング・コンフィグレーショ ンの変異です。唯一の違いは、このテクニックを、SMP システム内の1つの物理 CPU にでは なく単一 CPU に適用していることです。今、物理 CPU は 2 つの論理 CPU を含んでいるため、 今、単一 CPU はシールドされている CPU を生成するために使用されます。この場合、他の CPU がバックグランド活動を走らせるのに使用されている際に、CPU の1つはシールドされ ているとマークされます。この種類のシールドされている CPU の決定性は、個別の物理 CPU 上で CPU シールディングを使用するほどには堅固ではありませんが、しかしそれはシ ールディングが全くないものに比し、はるかに優れています。 空きメモリが少ない状態を避ける あなたのシステムが適切な物理メモリを持っていることを保証してください。 リアルタイム保 証はリアルタイムアプリケーション使用法のために適切な RAM で適切に構成を設定された システムを想定しています。 空きメモリが少ない状態で、リアルタイムのデッドラインがもっと良くシステム完全性を保証し て、そして適切なシステム行動を維持するために犠牲にされるかもしれません。 Linux がメ モリを使い果たすとき、他のプロセスが進むことができるように、それはランダムな試みで殺 すプロセスをメモリを開放するよう選びます。 メモリ用法が自由な /proc/meminfo (1)と vmstat (8)を含めて多くのツールを使ってモニ ターすることができます。 Linux の決定性の知られた事項 以下は、標準的 Linux において、リアルタイム動作にネガティブな影響を与えると知られてい 2-44 SUSE Linux Enterprise Real Time Linux User’s Guide るものです。これらのアクションは、その性質から一般的に管理的で、システムがリアルタイ ム・アプリケーションを実行している際は動作されるべきではありません。 ・ hdparm (1)ユーティリティは、IDE 及び SCSI ディスクにおいて特別のパラメータを許可 するためのコマンド・ラインです。このユーティリティは、とても長い時間にわたって割り込 みを禁止するものとして知られています。 ・ blkdev_close (2)インターフェイスは、生の(raw)ブロック・デバイスにライトするのにブ ート・ローダによって使用されます。これは、とても長い時間にわたって割り込みを禁止す るものとして知られています。 ・ フレーム・バッファ(fb)・コンソールをスク role することを避けます。これは、とても長い時 間にわたって割り込みを禁止するものとして知られています。 ・ バーチャル・コンソールを使用する際、コンソールをスイッチしません。これは、とても長い 時間にわたって割り込みを禁止するものとして知られています。 ・ CD のマウント及びアンマウント、そしてファイル・システムのアンマウントを避けます。こ れらのアクションは長い待ち時間を生みます。 ・ CD の自動マウントをオフにします。これはポーリング・インターフェイスで、定期的ポール は長い待ち時間を生み出します。 ・ デフォルトでは、Linux カーネルは、デバイス・ドライバの ioctl ( )ルーチンを呼び出す前 にビッグ・カーネル・ロック(BKL)をロックします。これは、ioctl ( )ルーチンがリアルタイ ム・プロセスに呼び出される時、またはシールドされている CPU 上で呼び出される時に、 遅れを引き起こします。この問題をどのようにして解決するかに関する更なる情報につい ては、“デバイス・ドライバ”の章を見てください。 ・ カーネル・モジュールのアンロードを避けます。このアクションは、不必要なジッタ-を CPU に加える多くの CPU あたりの kmodule デーモンを生み出し、そして破壊します。 ・ ksoftirqd カーネルデーモンによって周期的にクリアされる IP ルートキャッシュテーブル は使用可能メモリ;例えば、4GBのメモリを持っているシステムの 128K エントリの量に 基づいて動的にサイズを定められます。 もしネットワーク決定論が、特にシングルCPU システムで、問題となっているなら、フラッシュのために必要とされる時間は問題です。 過度の ksoftirqd 実行を減らすために、 IP ルートキャッシュテーブルは grub コマンド rhash_entries = nを使って固定サイズにセットすることができます、nは 4K 項目の テーブルエントリ;すなわち、 rhash_entries ・ = 4096の数です。 タイムクリティカルのアプリケーションをシールド CPU 上で走らせる間に、Xサーバーを始 動させて、そして止めるとき可能なリアルタイム問題があるかもしれません。あなたのシ ステムが使うグラフィックス・カードのタイプによって、これはパフォーマンスを遅くする多 数のクロスプロセッサ割り込みをもたらすかもしれません。 もしあなたがこれを経験して いるなら、これらの割り込みを減らす方法のために付録Gに言及してください。 ・ 2-45 DETECT_SOFTLOCKUP がカーネルでコンフィグされないことを保証してください。 SUSE Linux Enterprise Real Time Linux User’s Guide rescheduling variable が誤って softlockup メカニズムによってソフトロックアップと解釈 されると考えられますので、このオプションはすべての CPU の上に、そして rescheduling variable でアンロックによって過度の per-CPU デーモンをかばっている CPU を妨げま す。 2-46 SUSE Linux Enterprise Real Time Linux User’s Guide 3 リアルタイム・プロセス間通信 この章では、POSIX 及び System V メッセージキュー、また共有メモリ機能を通してのリアル タイム・プロセス間通信における、SUSE Linux Enterprise Real Time サポートについて説明 します。 付録 A は、POSIX 及び System V メッセージキュー機能の使用について説明する、プログラ ム例を含みます。 概要 SUSE Linux Enterprise Real Time は、プロセスがデータをやり取りすることを可能にするい くつかのメカニズムを提供します。これらのメカニズムは、System V プロセス間通信(IPC)パ ッケージに含まれているものと同じように、メッセージキュー、共有メモリ、そして IEEE 標準 1003.1b-1993 に基づくセマフォを含みます。メッセージキュー及び共有メモリは、この章で論 じられ、セマフォは、5章、プロセス間同期化で論じられます。 メッセージキューによって、1つまたはそれ以上のプロセスが、1つまたはそれ以上のリーディ ング・プロセスによってリードされるメッセージを送信することができます。提供されている機 能は、メッセージキューの生成(ceate)、オープン(open)、問い合わせ(query)、破壊(destroy)、 メッセージキューの優先度付き送信(send)、受信(receive)、メッセージ受信時の非同期的通 知(asynchronous notification)の要求です。 POSIX 及び System V メッセージ機能は、それぞれ独立して動作します。推奨されるメッセー ジキューメカニズムは、その効率性及び移植性により、POSIX メッセージキュー機能です。 “POSIX メッセージキュー”及びこの章での“System V メッセージ”は、これらの機能を説明し ます。 共有メモリによって、共同プロセスがメモリの共同エリアを通してデータを共有することができ ます。1つまたはそれ以上のプロセスがメモリのセグメントをくっ付け、そして結果としてそこに 置かれているデータなら何でも共有することができます。 メッセージに関しては、POSIX 及び System V の共有メモリ機能は、それぞれ独立して動作し ます。アプリケーションの中では、System V 共有メモリ・エリアを使用することが推奨されます。 そのアプリケーション内では、共有メモリ内に置かれたデータは一時的で、そしてシステムの リブートを追って存在する必要がありません。System V 共有メモリ内のデータは、メモリ内に 3-1 SUSE Linux Enterprise Real Time Linux User’s Guide のみ保存されます。そのメモリと結合しているディスク・ファイルは無く、よって sync (2)システ ムコールによるディスク渋滞は生まれません。さらに、System V 共有メモリによって、共有メ モリ・セグメントを物理 IO メモリのセクションへと連結することができます。この機能に関する 更なる情報については、“System V 共有メモリ”のセクションを参照してください。 System V 共有メモリを使用するのに代わる方法は、mmap (2)システムコールを使用して、 /dev/mem ファイルの部分をマップすることです。mmap システムコールに関する情報につ いては、9 章、“メモリ・マッピング”を参照してください。/dev/mem ファイルに関する情報につ いては、mem (4)man page を参照してください。 POSIX 共有メモリ・インターフェイスは、/var/tmp ディレクトリ内のディスク・ファイルにマップさ れています。もしこのディレクトリが memfs ファイル・システム上にマウントされていれば、 sync システムコール間に共有データをフラッシュするための追加的なディスク待ちが発生す ることはありません。もしこのディレクトリが一般的ディスク・パーティション上にマウントされて いれば、sync システムコールがマップされたディスク・ファイル内でアップデートされた共有さ れたデータを保持するために、ディスク渋滞が生まれます。 POSIX 共有メモリに書かれたデータがファイル内で保存されているか否かに関わらず、これ らのデータはシステムのリブートを追って存在しません。POSIX 共有メモリ機能性について は、この章の“POSIX 共有メモリ”のセクションで説明されています。 POSIX メッセージキュー アプリケーションは、多様な共同プロセス、時には別々の CPU 上での動作から構成されます。 これらのプロセスはシステム・ワイド POSIX メッセージキューを使用して、それらの活動を効 率的に通信し、対応させます。 POSIX メッセージキューの主要な使用は、プロセス間でデータを渡すことです。対照的に、同 じプロセス内のスレッドは既に全体のアドレス空間を共有しているので、同じプロセス内の共 同スレッド間でデータを渡す機能はあまり必要ではありません。しかし、1つまたはそれ以上 のプロセス内のスレッド間で、アプリケーションがメッセージキューを使用してデータを渡すこ とを妨げるものは何もありません。 基本的概念 POSIX メッセージキューは、mqueue ファイル・システム内でファイルとして実行されます。 SUSE Linux Enterprise Real Time は、どのマウント・ポイント上にもマウントが可能ですが、 3-2 SUSE Linux Enterprise Real Time Linux User’s Guide /dev/mqueue 上に mqueue ファイル・システムをマウントします。もしもシステム管理者が /dev/mqueue におけるエントリを/etc/fstab に加えれば、それは、ブート時にエントリごとに マウントされます。そうでなければ、/etc/init.d/ccur スクリプトがマウントを行います。 /dev/mqueue 上に mqueue ファイル・システムを手動でマウントするには、次のコマンドを発 信します。 # mkdir –p /dev/mqueue (もしマウント・ポイントが存在しなければ) # mount –t mqueue none /dev/mqueue ‘none’引数は、これはマウント・ポイントであって、デバイス・ファイルではないことを反映して います。メジャー・ナンバー0(ヌル・デバイス・ナンバーとして保管されています)が、名前の無 いデバイス(例: デバイスが無いマウント)のためにカーネルによって使用されます。 マウントされる時、/dev/mqueue ディレクトリ内にファイルとして、メッセージキューが現れま す。例として: /dev/mqueue/my_queue 現在の実行は mqueue ファイル・システムがマウントされていることを必要としません。プロ グラムはそれがマウントされいるいないに関係なく走ります。しかしマウントされていない時、 mqueue は見えず、コマンド・ラインから操作することはできません。 mqueue ファイル・システムはディレクトリをサポートしていないため、/dev/mqueue 下にディ レクトリを生成することはできません。ソース・コード内での POSIX メッセージキュー上の操作 において、システムコール close (2)、open (2)、及び unlink (2)を使用します。しかし、 POSIX メッセージキューへの完全なアクセスは、SUSE Linux Enterprise Real Time リアル タイム・ライブラリ・インターフェイスが提供するライブラリ・ルーチンを通してのみ達成されます。 このインターフェイスの使用に関する更なる論説については、“メッセージキューライブラリ・ル ーチン”を見てください。 多様なマウント・ポイントを同時にアクティブにすることは可能です。ミラー・イメージがあり、1 つのパスの下で起こることは、全てのパスの下で見ることができます。これは、異なるパスの 下で見える同じ名前の mqueue は、同じ mqueue を指すことを意味します。例として: /dev/mqueue/my_queue 及び/mnt/mqueue/my_queue は、同じ mqueue を指します。こ れは意図されたオペレーションの方法ではありませんが、しかし、それは mqueue がシステ ム・ワイドのグローバル・データ構造であることを明白にしています。 cat (1)、stat (1)、ls (1)、chmod (1)、chown (1)、rm (1)、touch (1)、及び umask (2)は全 て、他のファイル上で mqueue ファイルを動作させます。ファイル許可、及びモードも他のファ イルの時と同様に動作します。 3-3 SUSE Linux Enterprise Real Time Linux User’s Guide mqueue ファイルは、VFS によっては一般的ファイルであると報告されているため、copy の ような他の共通のファイル操作コマンドが、ある程度まで動作します。しかし、この方法で使 用されるようには設計されていません。しかし、いくつかのコマンド特に、cat 及び touch では、 有用でしょう。。 z touch は、‘0’のキューを生成します。 z cat は、下記 4 つのフィールドの情報を出力します。 QSIZE キュー全体で占められるメモリ内のバイト数 NOTIFY 通知マーカー(mq_notify(2)を見てください) SIGNO 通知の時に生み出されるシグナル NOTIFY_PID どのプロセスが通知させられるべきか 以下のシステム制限が、POSIX メッセージキューに適用されます。 DFLT_QUEUESMAX 64 メッセージキューの最大数 DFLT_MSGMAX 40 それぞれのキュー内のメッセージの最大数 DFLT_MSGSIZEMAX 16384 最大メッセージサイズ HARD_MSGMAX (131072/sizeof(void*)) 全てのキューが共に持てる最大サイズ MQ_PRIO_MAX 32768 最大メッセージ・プライオリティ メッセージキューはメッセージ・スロットから構成されます。メッセージ送信及び受信を最適化 するために、1つのメッセージキュー内の全てのメッセージ・スロットは、同じサイズです。1つ のメッセージ・スロットは1つのメッセージを保持することができます。メッセージ・サイズは、メ ッセージ・スロット・サイズとは異なりますが、それはメッセージ・スロット・サイズより大きくなる べきではありません。メッセージはパッドされず、ヌル終端されません。メッセージの長さは、 バイト・カウントで決定されます。メッセージキューは、それらのメッセージ・スロット・サイズ及 びそれらが保持するメッセージの最大数によって異なります。図 3-1 は、これらの事実のいく つかを説明しています。 3-4 SUSE Linux Enterprise Real Time Linux User’s Guide 図 3-1 2 つのメッセージキュー及びそれらのメッセージ POSIX メッセージキューライブラリ・ルーチンは、以下のプロセスを可能にします。 z メッセージキューの生成、開く、問い合わせる、閉じる、そして破壊 z メッセージキューにメッセージを送り、メッセージキューからメッセージを受け取る (時間が計られます) z 送られるメッセージでプライオリティを結合する z メッセージが特定の空のメッセージキューに着いた時に、ユーザ指定のシグナル経 由で非同期通知を要求する プロセスはメッセージキューとメッセージキュー記述子経由で通信します。fork (2)システムコ ールが生成した子プロセスは、親プロセスのオープン・メッセージキュー記述子の全てを継承 します。exec (2)及び exit (2)システムコールは、全てのオープン・メッセージキュー記述子を 閉じます。 プロセス内で1つのスレッドがメッセージキューを開いた場合、そのプロセス内の全てのスレ ッドは、もしもそれらがメッセージキュー記述子へのアクセスを持っていれば、メッセージキュ ーを使用することができます。 メッセージキューにメッセージを送ろうとしている、またはメッセージキューからメッセージを受 けようとしているプロセスは、待たなければなりません。待つことは、ブロックされている状態 としても知られています。 3-5 SUSE Linux Enterprise Real Time Linux User’s Guide 2 つの異なるプライオリティが、メッセージ送信及び受信において役割を担っています。メッセ ージ・プライオリティとプロセス・スケジューリング・プライオリティです。どのメッセージもメッセ ージ・プライオリティを持っています。 最も古く、最高プライオリティのメッセージがプロセスによって最初に受け取られます。 どのプロセスもスケジューリング・プライオリティを持っています。完全なメッセージキューにメ ッセージを送るために、複数プロセスがブロックされているものとします。そのメッセージキュ ー内で空間がフリーになった時、システムは最高プライオリティ・プロセスをウェイクアップま す。このプロセスは次のメッセージを送ります。最高プライオリティを持つ複数プロセスがある 場合、最も長くブロックされていたものが呼び起こされます。空のメッセージキューからメッセ ージを受けるために複数プロセスがブロックされているものとします。メッセージがそのメッセ ージキューに着く時、そのメッセージを受けるプロセスを決定するのに同じ基準が使用されま す。 高度な概念 スピン・ロックは、メッセージキューへのアクセスを同期化し、メッセージキュー構造をプロテク トします。スピン・ロックがロックされている間、アプリケーションが中断するのを防ぐために多 くのシグナルがブロックされます。しかし、ある程度のシグナルはブロックされません。 アプリケーションがメッセージキューを使用し、そしてロックを持っているものとします。もしも シグナルがこのアプリケーションを中断すれば、どのプロセスもメッセージキューを使用でき なくなります。メッセージキューにアクセスしようとしている全てのプロセスが、ロックへのアク セスを得ようとしてハングします。再びアクセスを可能にするために、プロセスは mq_unlink (2)経由でメッセージを破壊し、そして mq_open (2)経由でメッセージキューを再生成しなけ ればなりません。これらのルーチンに関する更なる情報については、“mq_unlink ルーチン” 及び“mq_open ルーチン”それぞれを見てください。 メッセージキューライブラリ・ルーチン メッセージキューをサポートする POSIX ライブラリ・ルーチンは、メッセージキュー属性構造に 依拠しています。“メッセージキュー属性構造”は、この構造を説明しています。“ライブラリ・ ルーチンの使用”は、ライブラリ・ルーチンを提示しています。 メッセージキューライブラリ・ルーチンを呼び出す全てのアプリケーションは、以下に示すライ ブラリをリンクしなければなりません。このライブラリは静的にまたは動的にリンクできます。 以下の例は、典型的なコマンド・ライン・フォーマットを示しています。 3-6 SUSE Linux Enterprise Real Time Linux User’s Guide gcc [options…] file –lrt … メッセージキュー属性構造 メッセージキュー属性構造 mq_attr は、ステータス及び特定のメッセージキューについての属 性情報を保持します。プロセスがメッセージキューを生成する時、それは自動的にこの構造 を生成、そして初期化します。このメッセージキューへメッセージを送るどの試み、及びこのメ ッセージキューからメッセージを受けるどの試みも、この構造内で情報をアップデートします。 プロセスはこの構造内で値を問合わせます。 mq_getattr (2)を起動する時、そしてオプション的に mq_open (2)を起動する時、mq_attr 構造へポインタを供給します。これらのルーチンに関する情報については、“mq_getattr ルー チン”及び“mq_open ルーチン”それぞれを参照してください。 mq_attr 構造は、<mqueue.h>の中で以下のように定義されています。 struct mq_attr { long mq_flags ; long mq_maxmsg ; long mq_msgsize ; long mq_curmsgs ; }; 構造の中でのフィールドは以下のように説明されます。 mq_flags このメッセージキューと結合しているオペレーションが、ノンブロッキン グ・モードであるかないかを示すフラッグ mq_maxmsg このメッセージキューが保持できるメッセージの最大数 mq_msgsize このメッセージキュー内のメッセージのバイトでの最大数 mq_curmsgs 現在このメッセージ内にあるメッセージ数 ライブラリ・ルーチンの使用 メッセージキューをサポートする POSIX ライブラリ・ルーチンは、以下のように手短に説明さ れます。 3-7 SUSE Linux Enterprise Real Time Linux User’s Guide mq_open 新しいメッセージキューを生成する及び開く、または存在するメッセージキューを開 きます mq_close オープン・メッセージキューを閉じます mq_unlink メッセージキュー及びその中のどのメッセージも取り除きます。 mq_timedsend オープン・メッセージキューに、タイムアウト値付でメッセージをライトします mq_receive オープン・メッセージキューから最も古く、最高プライオリティのメッセージをリードし ます mq_timedreceive オープン・メッセージキューから、タイムアウト値付で最も古く、最高プライオリティの メッセージをリードします mq_notify メッセージが着く時、呼び出しプロセスがユーザ指定のシグナルへ送られる時のよ うに空のメッセージキューへのメッセージの到着の通知を登録します mq_setattr メッセージキューと結合している属性を設定します mq_getattr オープン・メッセージキューについてのステータス及び属性情報を収得します それぞれのルーチンの使用における手順は、以下に続くセクションで述べられます。 mq_open ルーチン mq_open (2)ライブラリ・ルーチンは、呼び出しプロセスとメッセージキューとの接続を確立し ます。フラグ設定に依拠して、mq_open はメッセージキューを生成します。mq_open は常 に新しいメッセージキュー記述子を生成し、開きます。メッセージキューをサポートするほとん どの他のライブラリ・ルーチンは、このメッセージキュー記述子を使用してメッセージキューを 参照してください。 概要 #include <mqueue.h> mqd_t mq_open (const char name, int oflag, /* mode_t mode, struct mq_attr *attr*/…); 3-8 SUSE Linux Enterprise Real Time Linux User’s Guide 引数は以下のように定義されます。 Name は、マウントポイント/dev/mqueue と連結して、mqueue ファイルに名前を付ける 絶 対 的 パ ス を 作 り ま す 。 例 と し て 、 も し 名 前 が /my_queue な ら 、 パ ス は /dev/mqueue/my_queue になります。このパスは、PATH_MAX の限度内でな ければなりません。 name と同様の値で mq_open を呼び出すプロセスは、同じメッセージキューを 指します。もし name 引数が存在しているメッセージキューではなく、また生成を 要求しなければ、mq_open は失敗し、エラーを返します。 Oflag 呼び出しプロセスがメッセージキューへの送信及び受信アクセスを持っているか どうかを示す整数値です。このフラグはさらに、呼び出しプロセスがメッセージキ ューを生成しているのか、または既存しているものへの接続を確立しているのか どうかを示します。 mode プロセスは、それがメッセージキューを生成する時、同じメッセージキュー において oflag 設定を限定するなら、供給します。例として、生成の時、メッセージ キューmode が、同じ有効的グループ ID と共にメッセージキューをリードはする がライトしないプロセスを許すものとします。もしもこのグループ内のプロセスが oflag セットでメッセージキューを開き、(O_WRONLY)へライト・アクセスしようとす るなら、mq_open はエラーを返します。 メッセージキューにおける oflag 設定を変えるただ1つの方法は、mq_close 及 び mq_open を呼び出し、mq_open が返すメッセージキュー記述子を、それぞ れ閉じそして再開きすることです。 送る、受ける、または両方のために、プロセスはメッセージキューを複数時間で 開きます。oflag の値は、正確に以下の3つのうちの1つのアクセス・モードを含ま なければなりません。 O_RDONLY メッセージを受信するためにメッセージキューを開きます。呼び出 しプロセスは、mq_send ではなく mq_receive と共に返されたメ 3-9 SUSE Linux Enterprise Real Time Linux User’s Guide ッセージキュー記述子を使用できます。 O_WRONLY メッセージを送信するためにメッセージキューを開きます。呼び出 しプロセスは、mq_receive ではなく mq_send と共に返されたメ ッセージキュー記述子を使用できます。 O_RDWR メッセージの送信及び受信のためにメッセージキューを開きます。 呼び出しプロセスは、mq_send 及び mq_receive と共に返され たメッセージキュー記述子を使用できます。 oflag の値はさらに残りのフラッグのどの組合せも含みます。 O_CREAT もしもまだ存在しないなら、空のメッセージキューを生成し、開きま す。もしメッセージキューname が現在開かれていなければ、この フラグは mq_open に空のメッセージキューを生成させます。もし もメッセージキューname がシステム上で既に開かれていれば、こ の フ ラ ッ グ の 効 果 は 、O_EXCL 下で 示 さ れてい る も の です 。 O_CREAT フラッグを設定するなら、さらに mode 及び attr 引数も 指定しなければなりません。 新しく生成されたメッセージキューはそのユーザ ID が呼び出しプ ロセスの有効的ユーザ ID に設定されており、またそのグループ ID は、呼び出しプロセスの有効的グループ ID に設定されています。 O_EXCL もしも呼び出しプロセスが既に存在しているメッセージキューを生成 しようとすれば、エラーを返します。もし O_EXCL 及び O_CREAT が 設定されておりメッセージキューname が既に存在しているなら、 mq_open ルーチンは失敗します。もし O_EXCL 及び O_CREAT が設定されておりメッセージキューname が未だ存在しないならば、 mq_open ルーチンは成功します。もしも O_EXCL が設定されてお り O_CREAT が設定されていなければ、mq_oepn ルーチンは O_EXCEL の設定を無視します。 O_NONBLOCK mq_send は、空間が完全なメッセージキューでフリーになるのを待 つよりもエラーを返します。mq_receive は、メッセージが空のメッセ ージキューに着く前にエラーを返します。 3-10 SUSE Linux Enterprise Real Time Linux User’s Guide mode もしもこれがメッセージキューを生成する mq_open コールなら、リー ドし、ライトし、そしてメッセージキューにおいて実行/検索許可を設 定する、整数値。mq_open ルーチンは、他の全てのモード・ビット ( 例 と し て 、 setuid ) を 無 視 し ま す 。 フ ァ イ ル 生 成 モ ー ド ・ マ ス ク 、 umask の設定は、mode の値を修正します。モード設定に関する更 なる情報については、chmod (1)及び unmask (2) man page を見 てください。 attr メッセージキュー属性を設定する、ヌル・ポインタ定数または構造へ のポインタ。例として、メッセージキュー内でのメッセージの最大数及 び最大メッセージ・サイズ。mq_attr 構造に関する更なる情報につい ては、“メッセージキュー属性構造”を見てください。 もしも attr が NULL なら、システムはシステム限度付でメッ セージキューを生成します。もしも attr が NULL でなければ、フィール ド内で指定されている属性付でシステムはメッセージキューを生成し ます。もしも attr が指定されていれば、メッセージキューが実際的に 生成される時にのみ、それは効果を発揮します。 もし attr が NULL でなければ、以下の属性がゼロよりも大きな値に設 定されなければなりません。 attr.mq_maxmsg attr.mq_msgsize メッセージキュー記述子の返り値は、メッセージキューが成功して開かれたことを示します。 ((mqd_t) –1)の返り値は、エラーが発生したことを示します。errno は、エラーを示すように設 定されます。起こり得るエラーの種類のリストについては、mq_open (2) man page を参照し てください。 mq_close ルーチン mq_close (2)ライブラリ・ルーチンは、呼び出しプロセスとメッセージキューとの間の接続を 切ります。 mq_close ルーチンは、呼び出しプロセスがメッセージキューへアクセスするのに使用するメ 3-11 SUSE Linux Enterprise Real Time Linux User’s Guide ッセージキュー記述子を取り除くことによって、これを行います。mq_close ルーチンは、メッ セージキューそのもの、またはメッセージキュー内のメッセージには影響を与えません。 注 もしもプロセスがメッセージキューについての通知を要求し、そして後にメッセー ジキューへのその接続を切る場合、その要求は取り除かれます。メッセージキュ ーは、他のプロセスが通知を要求するために利用されます。 mq_notify 経由での通知要求に関する情報については、“mq_notify ルーチン” を見てください。 概要 #include <mqueue.h> int mq_close (mqd_t mqdes) ; 引数は以下のように定義されます。 mqdes mq_open から得られたメッセージキュー記述子 0 の返り値は、メッセージキューが成功して閉じられたことを示します。-1 の返り値は、エラー が起こったことを示します。errno は、エラーを示すために設定されます。起こり得るエラーの 種類のリストについては、mq_close (2) man page を参照してください。 3-12 SUSE Linux Enterprise Real Time Linux User’s Guide mq_unlink ルーチン mq_unlink (2)ライブラリ・ルーチンは、メッセージキューへもはや mq_open 呼び出しをさせ ないようにします。 このメッセージキューへ他の接続が無い場合、mq_unlink は、メッセージキュー及びその中 のメッセージを取り除きます。 概要 #include <mqueue.h> int mq_unlink(const chr *name) ; 引数は以下のように定義されます。 name は、マウントポイント/dev/mqueue と連結して、mqueue ファイルに名前を付 ける絶対的パスを形成します。例として、もし名前が/my_queue なら、パスは /dev/mqueue/my_queue になります。このパスは PATH_MAX の限度内で なければなりません。 mq_unlink が呼ばれた時に、もしもプロセスがメッセージキューname を開いていれば、 mq_unlink はすぐに返ります。メッセージキューname の破壊は、メッセージ キューへの全ての参照が閉じるまで延期されます。このメッセージキューを生 成した mq_open が、リード及びライト双方のプロセス許可を許容する mode 引数を持っていた場合にのみ、プロセスは成功してメッセージキューname を 取り除くことができます。 0 の返り値は、メッセージキューが成功して取り除かれたことを示します。1の返り値は、エラ ーが発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラ ーの種類のリストについては、mq_unlink (2)を参照してください。 mq_send 及び mq_timedsend ルーチン mq_send (2)ライブラリ・ルーチンは、指定されたメッセージキューへメッセージを加えます。 m_send ルーチンは、async-safe オペレーションです。つまり、セマフォを扱うルーチン内で 呼び出せます。 空のメッセージキューへの成功した mq_send は、システムに、そのメッセージキューから受 け取ることをブロックされている最高プライオリティ・プロセスを呼び起こさせます。もしもメッセ 3-13 SUSE Linux Enterprise Real Time Linux User’s Guide ージキューが通知要求を付けられており、受信することをブロックされているプロセスでなけ れば、そのメッセージキューへの成功した mq_send はシステムに、通知要求が付けられた プ ロ セ ス に シ グ ナ ル を 送 信 さ せ ま す 。 更 な る 情 報 に つ い て は 、 “ mq_receive 及 び mq_timedreceive ル ー チ ン ” の 中 の mq_receive 及 び “ mq_notify ル ー チ ン ” の 中 の mq_notify を読みます。 mq_timedsend ライブラリ・ルーチンは、タイムアウト値を指定するのに使用され、よって、も しも指定されているメッセージキューが満杯なら、キュー中の充分な空き容量の待ちはタイム アウトになる時終了します。 概要 #include <mqueue.h> #include <time.h> int mq_send (mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio) ; int mq_timedsend (mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prIio, const struct timespec *abs_timeout); 引数は、以下のように定義されます。 mqdes mq_open から得られるメッセージキュー記述子。もしも指定されているメッセー ジキューが満杯で、そして O_NONBLOCKS が mqdes 内で設定されているなら、 メッセージはキューにされず、mq_send はエラーを返します。もしも指定されて いるメッセージキューが満杯で、そして O_NONBLOCK が mqdes 内に設定され ていなければ、メッセージをキューにできる空間が利用可能になるまで、または mq_send がシグナルによって割り込みされるまで、mq_send はブロックします。 複数プロセスが、満杯のメッセージキューへメッセージを送信することをブロック されているものとします。そのメッセージキュー内で空間がフリーになる時 (mq_receive によって)、最も長くブロックされていた最高プライオリティ・プロセ スをシステムはウェイクアップます。このプロセスは次のメッセージを送信します。 mq_send を成功させるために、このメッセージキュー記述子への mq_open 呼 び出しは、oflag 内で O_WRONLY または O_RDWR が設定されていなければ 3-14 SUSE Linux Enterprise Real Time Linux User’s Guide なりません。mq_open に関する情報については、“mq_open ルーチン”を見てく ださい。 msg_ptr mqdes によって表されるメッセージキューに送信されるメッセージを指定するスト リング。 msg_len msg_ptr によってポイントするメッセージのバイトでのサイズを示す整数値。 mq_open の生成上に設定されているメッセージキューのメッセージ・サイズ属性、 mq_msgsize を msg_len が超える時、mq_send ルーチンは失敗します。そうで なければ、メッセージキューへの msg_ptr 引数がポイントするメッセージを mq_send ルーチンはコピーします。 msg_prIio メッセージ・プライオリティを示す符号なし整数値。システムはメッセージ・プライオ リティ順でメッセージキューの中にメッセージを保存します。より新しいメッセージ は、もしそれがより高いメッセージ・プライオリティを持っているなら、より古いメッ セ ー ジ よ り も 前 の キ ュ ー に な り ま す 。 msg_prIio に お け る 値 は 0 か ら MQ_PRIO_MAX にわたり、0 は最も低いプライオリティを表しています。正確な 使用のために、緊急メッセージのメッセージ・プライオリティは、普通のメッセージ のそれを超えるべきです。メッセージ・プライオリティによって、定義することがあ る程度可能なものはメッセージ受信順であって、メッセージ受信者のものではな いことに注意します。 abs_timeout ナノ秒でのタイムアウト値です。範囲は、0 から 10 億までです。もし指定されてい るメッセージキューが満杯で、そして O_NONBLOCK が mqdes と結合している メッセージキュー記述子の中で設定されていなければ、キュー中での充分な空き 容量の待ちは、タイムアウトが満了する時、終了します。 図 3-2 は、メッセージキュー及び、プロセスがブロックされているかまたはフリーでメッセージ キューにメッセージを送信する状況内でのメッセージ・プライオリティを説明しています。 特に、以下の事実が述べられています。 z オペレーティング・システムは、それぞれのメッセージキューの中でメッセー ジ・プライオリティ順でメッセージを保持します。 3-15 SUSE Linux Enterprise Real Time Linux User’s Guide z いくつかのメッセージは、同じメッセージキュー内で同じメッセージ・プライオ リティを持ちます。 z デフォルトでは、満杯のメッセージキューへメッセージを送信しようとするプ ロセスはブロックされます。 図 3-2 2 つの mq_sends の結果 0 の返り値は、メッセージが成功して指定されたメッセージキューへと送信されたことを示しま す。-1 の返り値は、エラーが発生したことを示します。errno がエラーを示すために設定され ています。起こり得るエラーの種類のリストについては、mq_send (2) man page を参照して ください。 mq_receive 及び mq_timedreceive ルーチン mq_receive (2)ライブラリ・ルーチンは、特定のメッセージキューから最高プライオリティ・メッ セージの最も古いものをリードし、よって、メッセージキュー内の空間をフリーにします。 mq_receive ルーチンは、async-safe オペレーションで、つまり、シグナル扱いルーチン内で それを呼び出すことができます。 満杯のメッセージキューからの成功した mq_receive は、システムに、そのメッセージキュー へ送ることをブロックされている最高プライオリティ・プロセスを呼び起こさせます。更なる情報 については、“mq_send 及び mq_timedsend ルーチン”の中の mq_send を読みます。 mq_timedreceive ライブラリ・ルーチンは、タイムアウト値を指定するのに使用され、よって、 3-16 SUSE Linux Enterprise Real Time Linux User’s Guide 受信を満足させるメッセージがキュー上に存在しなければ、このようなメッセージにおける待 ちはタイムアウトになる時、終了されます。 概要 #include <mqueue.h> #include <time.h> ssize_t mq_receive (mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int msg_prio) ; ssize_t mq_timedreceive (mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout) ; 引数は以下のように定義されます。 mqdes mq_open から得られたメッセージキュー記述子。もし O_NONBLOCK が mqdes 内に設定されており、そして参照されているメッセージキューが空な ら、何もリードされず、そして mq_receive はエラーを返します。もしも O_NONBLOCK が mqdes 内に設定されておらず、そして指定されているメ ッセージキューが空なら、メッセージが利用可能になるか、または mq_receive がシグナルによって割り込みされるまで、mq_receive はブロ ックします。 空のメッセージキューからマルチ・プロセスがメッセージを受信することをブ ロックされているものとします。メッセージがそのメッセージキューに届いた 時(mq_send によって)、最も長くブロックされていた最高プライオリティの プロセスをシステムはウェイクアップます。このプロセスはメッセージを受信 します。 mq_receive を成功させるために、このメッセージキューにおける、プロセス の mq_open 呼び出しには、oflag の中で O_RDONLY または O_RDWR が設定されていなければなりません。mq_open に関する情報については、 “mq_open ルーチン”を見てください。 図 3-3 は、mqdes 内で O_NONBLOCK が設定されていない 2 つのプロセスを示しています。 両方のプロセスがメッセージを受信しようとしていますが、1つのプロセスは、それが空のメッ 3-17 SUSE Linux Enterprise Real Time Linux User’s Guide セージキューにアクセスしているために、ブロックされています。図の中では、矢印はデータ の流れを示しています。 図 3-3 2 つの mq_receive の結果 msg_ptr mqdes によって表されるメッセージキューからメッセージを受信するキャラクタ配 列(メッセージ・バッファ)へのポインタ。成功した mq_receive の返り値は、バイ ト・カウントです。 msg_len msg_ptr によってポイントされるアレイのバイトでのサイズを示す整数値。もしも mq_open の生成上に設定されているメッセージキューの mq_msgsize メッセー ジ・サイズ属性よりも msg_len が小さければ、mq_receive ルーチンは失敗しま す。そうでなければ、mq_receive ルーチンは、メッセージキューからメッセージ を取り除き、msg_ptr 引数がポイントする配列へとそれをコピーします。 msg_prio 受け取られたメッセージのプライオリティを受け取る符号無し整数変数へのヌル・ ポインタ定数またはポインタ。もし msg_prio が NULL なら、mq_receive ルーチ ンは、メッセージ・プライオリティを捨てます。もし msg_prio が NULL でなければ、 mq_receive ルーチンは、msg_prio が参照する位置の中で受信されたメッセー ジのプライオリティを記憶します。受信されたメッセージは、メッセージキューの中 で最も古く、最高プライオリティのメッセージです。 3-18 SUSE Linux Enterprise Real Time Linux User’s Guide abs_timeout ナノ秒でのタイムアウト値です。範囲は、0 から 10 億までです。mq_open (2) 経由でメッセージキューが開かれた時に O_NONBLOCK が指定されておらず、 そしてキュー上に受け取りを満足させるメッセージが存在しなければ、タイムア ウトになる時に、このようなメッセージへの待ちは終了します。 -1 の返り値は、エラーが発生したことを示します。errno は、エラーを示すため に設定されており、そしてメッセージキューの内容は変化されません。マイナス でない返り値は、成功して受信されたメッセージの長さを示しており、受信され たメッセージは、メッセージキューから取り除かれます。起こり得るエラーの種 類のリストについては、mq_receive (2) man page を参照してください。 mq_notify ルーチン mq_notify (2)ライブラリ・ルーチンによって、空のメッセージキューでのメッセージの到着の 通知を、呼び出しプロセスが登録することができます。この機能性によって、メッセージキュー からメッセージを受信するための mq_receive (2)への呼び出し上でブロックせずに処理を進 め る 処 理 が 可 能 で す ( こ の ル ー チ ン の 説 明 に つ い て は 、 “ mq_receive 及 び mq_timedreceive ルーチン”を見てください)。複数スレッドされているプログラムにおいては、 この機能性を得るためのさらに効率的な方法は、mq_receive 呼び出しを発信する別々のス レッドを生み出す必要があることに注意してください。 何時でも、1つのプロセスだけが通知のために、メッセージキューの登録を行えます。しかし、 プロセスは通知のために、それがオープンしたそれぞれの mqdes によって登録することがで きます。しかし、それまたは他のプロセスが既に登録している mqdes は例外です。特定のメ ッセージキューでのメッセージの到着の通知において、プロセスが既に登録しているものとし ます。そのメッセージキューによる通知を登録する全ての後の試みは、通知が登録されてい るプロセスへ送信されるまで、または登録されているプロセスがその登録を取り除くまで、失 敗します。通知が送信される時、そのプロセスにおける登録は取り除かれます。メッセージキ ューは再びどのプロセスの登録でも利用可能です。 1 つのプロセスが mq_receive 上でブロックし、そして他のプロセスが同じメッセージキュー上 でのメッセージ到着の通知において、登録するものとします。メッセージがメッセージキューに 到着する時、ブロックされているプロセスはメッセージを受信し、そして他のプロセスの登録は 中断されたままになります。 概要 3-19 SUSE Linux Enterprise Real Time Linux User’s Guide #include <mqueue.h> int mq_notify (mqd_t mqdes, const struct sigevent *notification) ; 引数は以下のように定義されます。 mqdes mq_open から得られるメッセージキュー記述子 notification 指定されているメッセージキューでメッセージの到着が知らされる呼び 出しプロセスの方法を指定するヌル・ポインタ定数または構造へのポイ ンタ。通知が NULL ではなく、また呼び出しプロセスまたは、指定されて いるメッセージキューでの通知において既に登録している他のどのプロ セスでもなければ、mq_notify は、メッセージキューでのメッセージの 到着を通知する呼び出しプロセスを登録します。メッセージが空メッセ ージキューに着く時(mq_send によって)、notification 引数が指定す るシグナルを、通知において登録したプロセスへとシステムは送信しま す。通常、呼び出しプロセスはこのシグナルに対して、メッセージキュー 上で mq_receive を発信することによって応答します。 通知が登録されているプロセスへ送信される時、その登録は取り除か れます。そしてメッセージキューは、どのプロセスによっても登録におい て利用可能になります。 notification が NULL で、また指定されているメッセージキューによって、 呼び出しプロセスが、通知において以前に登録しているなら、既存する 登録は取り除かれます。 も し notification の 値 が NULL で な け れ ば 、 notification->sigevent.sigev_notify が指定しているただ1つの意味の ある値は、SIGEV_SIGNAL です。この値が設定されていることで、空 のメッセージキューでのメッセージの到着にデリバーされるシグナルを プロセスは指定することができます。 3-20 SUSE Linux Enterprise Real Time Linux User’s Guide SIGEV_SIGNAL を指定すると、notification->sigevent.sigev_signal は、生成されるシグナルの数を指定しなければなりません。そして、 notification->sigevent.sigev_value は、受信プロセスによって定義さ れているシグナル扱いルーチンへと渡されるアプリケーション定義の値 を、指定しなければなりません。記号的定数のセットは、シグナル・ナン バーを指定することにおいて手助けするように定義されています。これ らの定数は、<signal.h>ファイルの中で定義されています。アプリケー ション定義の値は、ポインタまたは整数値です。シグナルをキャッチし ているプロセスが、シグナルが生成される前に SA_SIGINFO フラグ・ セットと共に sigaction (2)システムコールを呼び起こせば、メッセージ キューにメッセージが到着する時に、シグナル及びアプリケーション定 義値は、プロセスでキューにされます。siginfo_t 構造は、ルーチンが入 る時にシグナル・ハンドラの中で調べられます。以下の値が予期されま す(siginfo.h を見てください)。 si_value 通知において送信される、指定されている sigevent.sigev_value si_code SI_MESGQ(リアルタイム・メッセージキュー状態変 化値: 3) si_signo 生成される、指定されている sigevent.sigev_signal si_errno このシグナルと関連している errno 値 0 の返り値は、指定されているメッセージキューでのメッセージの到着の通知において、呼び 出しプロセスが成功して登録したことを示します。-1 の返り値は、エラーが発生したことを示し ます。errno はエラーを示すために設定されています。起こり得るエラーの種類のリストにお いては、mq_notigy (2) man page を参照してください。 3-21 SUSE Linux Enterprise Real Time Linux User’s Guide mq_setattr ルーチン mq_setattr (2)ライブラリ・ルーチンによって、呼び出しプロセスが特定のメッセージキューと 結合している属性を設定することが可能です。 概要 #include <mqueue.h> int mq_setattr (mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat) ; 引数は以下のように定義されます。 mqdes mq_open から得られるメッセージキュー記述子。mq_setattr ルーチン は mqdes と結合しているメッセージキューにおいて、メッセージキュー属 性を設定します。 mqstat mqdes が参照するメッセージキューのフラッグ属性を指定する構造への ポ イ ン タ 。 こ の フ ラ ッ グ の 値 は ゼ ロ 、 ま た は O_NONBLOCK.O_NONBLOCK で、メッセージキューと結合している mq_send 及び mq_receive オペレーションにノンブロッキング・モードで 動作させます。 mq_maxmsg、mq_msgsize、及び mq_curmsgs の値を mq_setattr は 無視します。 mq_attr 構造に関する情報については、“メッセージキュー属性構造”を 見てください。mq_send 及び mq_receive ルーチンに関する情報につい ては、“mq_receive 及び mq_timedsemd ルーチン”及び“mq_receive 及 び mq_timedreceive ルーチン”をそれぞれ見てください。 omqstat 以前の属性についての情報及び mqdes が参照するメッセージキューの 現在のステータスが返される、ヌル・ポインタ定数または構造へのポイン タ。mq_attr 構造に関する情報については、“メッセージキュー属性構造” を見てください。 0 の返り値は、メッセージキュー属性が指定通りに成功して設定されたことを示します。-1 の 3-22 SUSE Linux Enterprise Real Time Linux User’s Guide 返り値は、エラーが発生したことを示します。errno は、エラーを示すために設定されていま す。起こり得るエラーの種類のリストについては、mq_setattr (2) man page を参照してくだ さい。 mq_getattr ルーチン mq_getattr (2)ライブラリ・ルーチンは、ステータス及び特定のメッセージキューと結合してい る属性情報を得ます。 概要 #include <mqueue.h> int mq_getattr (mqd_t mqdes, struct mq_attr *mqstat) ; 引数は以下のように定義されます。 mqdes mq_open から得られるメッセージキュー記述子。mq_getattr ルーチン は、ステータス及び mqdes と結合しているメッセージキューの属性につい ての情報を提供します。 mqstat ステータス及び mqdes が参照するメッセージキューの属性についての現 在の情報を受信する構造へのポインタ。mq_attr 構造に関する情報につ いては、“メッセージキュー属性構造”を見てください。 0 の返り値は、メッセージキュー属性が成功して得られたことを示します。-1 の返り値は、エラ ーが発生したことを示します。errno は、エラーを示すために設定されています。起こり得るエ ラーの種類のリストについては、mq_getattr (2) man page を参照してください。 Ststem V メッセージ プロセス間通信(IPC)の System V メッセージ・タイプによって、プロセス(実行プログラム)が、 バッファ内に記憶されているデータのやり取りを通して通信することができます。このデータ は、メッセージと呼ばれる不連続の部分内のプロセスの間で伝達されます。このタイプの IPC を使用するプロセスはメッセージを送信し、そして受信することができます。 プロセスがメッセージを送信するまたは受信することができる前に、それは、これらのオペレ ーションを扱うのに必要なソフトウェア・メカニズムを生成するオペレーティング・システムを持 3-23 SUSE Linux Enterprise Real Time Linux User’s Guide たなければなりません。プロセスは、msgget(2)システムコールを使用してこれを行います。 これを行う間に、プロセスはメッセージキューの所有者/生成者になり、そして自身も含む全 てのプロセスにおいて、最初のオペレーション許可を指定します。 その後、所有者/生成者はオーナーシップを破棄するか、または msgctl(2)システムコール を使用してオペレーション許可を変更します。しかし、生成者は機能が存在している限り、生 成者のままです。許可付の他のプロセスは、msgctl を使用して他の様々な制御機能を動作 することができます。 許可を持ち、そしてメッセージを送信するか受信することを試みるプロセスは、もしもそれらが オペレーション動作において問題がある時、実行を中止することができます。つまり、メッセー ジを送信しようと試みているプロセスは、それが指定されているメッセージキューへメッセージ を送ることが可能になるまで、待つことができます。受信プロセスは含まれません(間接的な ものは例外です。例として、消費者が消費していなければ、キュー空間は絶えてしまいます)。 その逆もそうです。実行が中止されるように指定しているプロセスは、ブロッキング・メッセー ジ・オペレーションを動作しています。その実行が中止されるのを許さないプロセスは、ノンブ ロッキング・メッセージ・オペレーションを動作しています。 ブロッキング・メッセージ・オペレーション動作しているプロセスは、以下の3つの状態が起こる まで中止されます。 ・ オペレーションが成功している ・ プロセスがシグナルを受信する ・ メッセージキューがシステムから取り除かれる システムコールは、これらのメッセージ機能をプロセスが利用できるようにします。呼び出しプ ロセスは、システムコールに引数を渡し、そしてシステムコールは、成功してまたは不成功に その機能を動作します。システムコールが成功すれば、それはその機能を動作し、そして適 応可能な情報を返します。そうでなければ、-1 がプロセスに返され、そして外部エラー・ナン バー変数、errno が相応に設定されます。 メッセージの使用 メッセージが送信されるまたは受信される前に、ユニークに識別されたメッセージキュー及び データ構造が生成されなければなりません。ユニークな識別子は、メッセージキュー識別子と 呼ばれ(msqid)、それは結合しているメッセージキュー及びデータ構造を識別するかまたは 参照するのに使用されます。この識別子は、システム内のどのプロセスによってもアクセス可 3-24 SUSE Linux Enterprise Real Time Linux User’s Guide 能で、通常アクセス制約に準じます。 メッセージキューの対応するカーネル・データ構造は、送信されるか受信されるそれぞれのメ ッセージについての情報を維持します。この情報は、システムに内的に使用されますが、そ れぞれのメッセージにおいて以下のものを含みます。 ・ メッセージの種類 ・ メッセージのテキスト・サイズ ・ メッセージのテキスト・アドレス ユニークに識別されたメッセージキュー、msqid_ds において、1つの結合しているデータ構造 があります。このデータ構造は、メッセージキューに関連している以下の情報を含みます。 ・ オペレーション許可データ(オペレーション許可構造) ・ キュー上の現在のバイト数 ・ キュー上のメッセージ数 ・ キュー上の最大バイト数 ・ 最後のメッセージ送りのプロセス ID(PID) ・ 最後のメッセージ受け取りの PID ・ 最後のメッセージ送り時間 ・ 最後のメッセージ受け取り時間 ・ 最後の変更時間 注 この章の中で述べられている全ての C ヘッダ・ファイルは、/usr/include サブディレクトリ内に 位置します。 結合しているメッセージキューデータ構造 msqid_ds は、図 3-4 で示されているメンバを含み ます。 図 3-4 msqid_ds 構造の定義 struct ipc_perm msg_perm;/* structure describing operation permission */ __time_t msg_stime; /* time of last msgsnd command */ __time_t msg_rtime; /* time of last msgrcv command */ __time_t msg_ctime; /* time of last change */ unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes;/* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ 3-25 SUSE Linux Enterprise Real Time Linux User’s Guide msqid_ds における C プログラミング言語データ構造の定義は、この構造は実際的には <bits/msq.h>内で定義されていますが、<sys/msg.h>ヘッダ・ファイルをインクルードするこ とによって得ることができます。 プロセス間許可データ構造、ipc_perm の定義は、図 3-5 で示されているメンバを含みます。 図 3-5 ipc_perm 構造の定義 __key_t __key; /* Key. */ __uid_t uid; /* Owner’s user ID. */ __gid_t gid; /* Owner’s group ID. */ __uid_t cuid; /* Creator’s user ID. */ __gid_t cgid; /* Creator’s group ID. */ unsigned short int mode; /* Read/write permission. */ unsigned short int __seq; /* Sequence number. */ ipc_perm の C プログラミング言語データ構造の定義は、この構造における実際的な定義は <bits/ipc.h>内に位置しますが、<sys/ipc.h>ヘッダ・ファイルをインクルードすることによっ て、得ることができます。<sys/ipc.h>は、全ての IPC 機能において共通して使用することに 注意します。 msgget (2)システムコールは、2 つのタスクのうち1つを動作します。 ・ 新しいメッセージキュー識別子を生成し、そしてそれにおける、結合するメッセージキ ュー及びデータ構造を生成します。 ・ 既に関連するメッセージキュー及びデータ構造を持つ、存在するメッセージキュー識 別子の位置を見つけます。 両方のタスクは、key 引数が msgget システムコールに渡されている必要があります。もし key が存在するメッセージキュー識別子において、未だ使用できなければ、結合するメッセー ジキュー及び key のために生成されたデータ構造と共に新しい識別子が返ります。チューニ ング可能なシステム・パラメータは超過されないものとします。 さらに、プライベート・キー(IPC_PRIVATE)として知られる、ゼロ(0)値の key を指定するた めの準備もあります。このキーが指定される時、メッセージキューの最大数(MSGMNI)にお けるシステム限定が超えられない限り、結合するメッセージキュー及びそのために生成され たデータ構造と共に、新しい識別子が常に返ります。ipcs(8)コマンドは、msqid においては 全てはゼロとして、key フィールドを示します。 3-26 SUSE Linux Enterprise Real Time Linux User’s Guide 指定されているキーにおいて、メッセージキュー識別子が存在すれば、存在する識別子の値 が返ります。存在するメッセージキュー識別子が返らないようにしたければ、制御コマンド (IPC_EXCL)を msgflg 引数の中で指定して(設定して)、システムコールに渡すことができま す(このシステムコールの詳細については、“msgget システムコール”を見てください)。 メッセージキューが生成される時、msgget を呼ぶプロセスは所有者/生成者になり、そして 結合するデータ構造が相応に初期化されます。ただし、オーナーシップは変更できても、生成 プロセスは常に生成者であることは覚えておかなければなりません。メッセージキュー生成 者はさらに、それにおける初期オペレーション許可も決定します。 ユニークに識別されたメッセージキューが生成されるか、または存在しているものが見つかる と、msgop (2)(メッセージ・オペレーション)及び msgctl (2)(メッセージ制御)を使用すること ができます。 前述されているように、メッセージ・オペレーションは、メッセージを送信する及び受信すること から構成されます。msgsnd 及び msgrcv システムコールは、これらのオペレーションのそ れぞれにおいて、提供されています(これらの呼び出しの詳細については、“msgsnd 及び msgrcv システムコール”を見てください)。 msgctl システムコールによって、以下の方法でメッセージ機能を制御することができます。 ・ メッセージキュー識別子と関連するデータ構造を取り戻します(IPC_STAT) ・ メッセージキューにおいて、オペレーション許可を変更します(IPC_SET) ・ 特定のメッセージキュー識別子における、メッセージキューのサイズ(msg_qbytes) を変更します(IPC_SET) ・ 結合するメッセージキュー及びデータ構造と共に SUSE Linux Enterprise Real Time オペレーティング・システムから、特定のメッセージキュー識別子を取り除きま す(IPC_RMID) msgctl システムコールの詳細については、“msgctl システムコール”のセクションを見てくだ さい。 System V メッセージキューを使用するサンプル・プログラムについては、付録 A を参照してく ださい。オンラインで見つかる追加的サンプル・プログラムは、System V システムコールでの それぞれの使用を奥深く説明しています。これらは、この章のセクション内で参照された、シ ステムコールを説明するものです。 3-27 SUSE Linux Enterprise Real Time Linux User’s Guide msgget システムコール msgget (2)は、新しいメッセージキューを生成するか、または既存するものを識別します。 このセクションでは、msgget システムコールについて説明します。更に詳細な情報について は、msgget (2)man page を見てください。この呼び出しの使用を説明するプログラムは、 /usr/share/doc/ccur/examples/msgget.c に あ り 、 詳 細 な コ メ ン ト は 、 README.msgget.txt 内で提供されています。 概要 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgget (key_t key, int msgflg) ; 全ての#include ファイルは、SUSE Linux Enterprise Real Time オペレーティング・システム のサブディレクトリ/usr/include 内に位置します。 key_t は、typedef により、ヘッダファイル<bits/types.h>の中で整数タイプになるように定義 されています(このヘッダファイルは、<sys/types.h>によって内的にインクルードされていま す)。完了が成功してこの関数から返る整数は、ユニークなメッセージキュー識別子、msqid です。(msqid はこの章で先に“メッセージの使用”のセクションの中で論じられています。)失 敗すれば、失敗の理由を示し、-1 が返されるための外部変数 errno が設定されています。 以下の状態の1つが真なら、結合するメッセージキュー及びデータ構造で新しい msqid が生 成されます。 ・ key は IPC_PRIVATE に等しい ・ key は ま だ そ れ と 結 合 す る msqid を 持 っ て お ら ず 、 そ し て ( msgflg 及 び IPC_CREAT)“真”である msgflg の値は以下の組合せです。 3-28 ・ 制御コマンド(flags) ・ オペレーション許可 SUSE Linux Enterprise Real Time Linux User’s Guide 制御コマンドはディフォルト定義の定数です。以下の制御コマンドは msgget システムコール に適用でき、ヘッダファイル<bits/ipc.h>の中で定義されており、それはヘッダファイル <sys/ipc.h>で内的にインクルードされています。 IPC_CREAT 新しいセグメントを生成するのに使用されます。もし使用されていなければ、 msgget は key と関連するメッセージキューを見つけ、アクセス許可を確証し、そし てセグメントが破壊としてマークされていないことを確認します。 IPC_EXCL もし指定されている key においてメッセージキュー識別子が既に存在するなら、 IPC_CREAT と共に使用してシステムコールにエラーを返させます。これは、そうで ないのにプロセスが新しい(ユニークな)識別子を受信したと認識することを防ぐた めに必要です。 オペレーション許可は、結合するメッセージキュー上でプロセスが動作することをオペレーショ ンが許すかを決定します。“Read”許可は、メッセージを受け取るため、または msgctl IPC_STAT オペレーションによって、キューステータスを決定するために必要です。“Write” 許可はメッセージを送るために必要です。 表 3-1 は、有効なオペレーション許可コードにおける数値(8進表記で表されています)を示し ています。 表 3-1 メッセージキューオペレーション許可コード 3-29 Operation Permissions Octal Value Read by User 00400 Write by User 00200 Read by Group 00040 Write by Group 00020 Read by Others 00004 Write by Others 00002 SUSE Linux Enterprise Real Time Linux User’s Guide 特定の値が、望まれるオペレーション許可において、8進値を加算するまたはビットごとに OR することから生成されます。つまり、もし“ユーザによるリード”と“他によるリード/ライト” が望まれるなら、コード値は、00406(00400 プラス 00006)です。 8進オペレーション許可値との連携でフラッグ名を使用することによって、msgflg 値は、簡単 に設定することができます。例として: msqid = msgget (key, (IPC_CREAT | 0400)) ; msqid = msgget (key, (IPC_CREAT | IPC_EXCL | 0400)) ; システムコールは常に試みられます。MSGMNI 限度を超えると、常に失敗を引き起こします。 MSGMNI 限度値は、いつでも使用できるユニークなメッセージキューのシステム・ワイドの数 を決定します。この限度値は、<linux/msg.h>内に位置する固定された定義値です。 メッセージキュー限度値のリストは、以下のオプションを使用して ipcs (8)コマンドで得ること ができます。更なる詳細については、man page を見てください。 ipcs –q –1 特定のエラー状態と同様に、特定の結合するデータ構造初期化については、msgget (2) man page を参照してください。 msgctl システムコール msgctl (2)は、メッセージキュー上で制御オペレーションを動作させるのに使用されます。 このセクションでは、msgctl (2)システムコールについて説明します。更に詳細な情報につい ては、msgctl (2) man page を見てください。この呼び出しの使用を説明しているプログラム は 、 /usr/shre/doc/ccur/examples/msgctl.c に あ り 、 詳 細 な コ メ ン ト が README.msgctl.txt 内で提供されています。 概要 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl 3-30 (int msqidi, int cmd, struct msqid_ds *buf) ; SUSE Linux Enterprise Real Time Linux User’s Guide 全ての#include ファイルは、SUSE Linux Enterprise Real Time オペレーティング・システム のサブディレクトリ/usr/include の中に位置します。 msgctl システムコールは、整数値を返します。それは、成功した完了なら 0 で、その他の場 合は、-1 です。 msqid 変数は、msgget システムコールを使用して既に生成された、有効な、マイナスでない 整数値でなければなりません。 cmd 引数は、以下の値のいくつかの1つです。 IPC_STAT 指定されているメッセージキュー識別子において、結合するデータ構造内 に含まれるステータス情報を返し、そしてそれを、ユーザ・メモリ内で buf ポインタがポイントしているデータ構造内に置きます。 IPC_SET ユーザ・メモリ内で buf ポインタがポイントしているデータ構造内に含まれ る値へのメッセージキューにおいて、有効的ユーザ、グループ ID、オペレ ーション許可、そしてバイト数をライトします。 IPC_RMID 結合しているデータ構造と共に指定しているメッセージキューを取り除き ます。 注 msgctl (2)サービスはさらに、IPC_INFO、MSG_STAT、及び MSG_INFO コマンドもサポー トします。しかし、これらのコマンドは、ipcs (8)ユーティリティによる使用のためのみなので、 これらのコマンドについては述べません。 IPC_SET または IPC_RMID 制御コマンドを動作するには、プロセスは以下の状態の1また はそれ以上を満たさなければなりません。 ・ OWNER の有効的ユーザ ID を持つこと ・ CREATOR の有効的ユーザ ID を持つこと ・ スーパー・ユーザであること ・ CAP_SYS_ADMIN ケーパビリティを持つこと さらに、MSGMNB(<linux/msg.h>の中で定義されています)の値を超えて、msg_qbytes の サ イ ズ を 増 大 す る IPC_SET 制 御 コ マ ン ド を 動 作 す る 際 、 プ ロ セ ス に は 3-31 SUSE Linux Enterprise Real Time Linux User’s Guide CAP_SYS_ADMIN ケーパビリティがなければなりません。 メッセージキューは、ipcrm (8)コマンドを使用して-qmsgid または-Qmsgkey オプションを指 定することによっても、メッセージキューを取り除くことができることに注意します。そこでは、 msgid はメッセージキューにおける識別子を指定し、msgkey はメッセージキューと結合する キーを指定します。このコマンドを使用するには、IPC_RMID 制御コマンドを動作するに要求 されるものと同じ有効的ユーザ ID、またはケーパビリティを、ユーザは持たなければなりませ ん。このコマンドの使用に関する追加的情報については、ipcrm (8) man page を見てくださ い。 msgsnd 及び msgrcv システムコール メッセージ・オペレーション・システムコール、msgsnd 及び msgrcv は、メッセージを送信す る及び受信するのに使用されます。 このセクションでは、msgsnd 及び msgrcv システムコールについて説明します。更に詳細 な情報については、msgop (2) man page を見てください。これらの呼び出しの使用を説明 す る プ ロ グ ラ ム は 、 README.msgop.txt 内 で 提 供 さ れ てい る 詳 細 な コ メ ン ト と 共 に 、 /usr/share/doc/ccur/examples/msgop.c にあります。 概要 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgsnd (int msqid, void *msgp, size_t msgsz, int msgflg) ; int msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg) ; 全ての#include ファイルは、SUSE Linux Enterprise Real Time オペレーティング・システム のサブディレクトリ/usr/include 内に位置します。 メッセージを送信する msgsnd システムコールは、整数値を返します。それは、成功した完了ではゼロを、その他 の場合は-1 を返します。 3-32 SUSE Linux Enterprise Real Time Linux User’s Guide msgqid 引数は、msgget システムコールの使用によって既に生成された、有効的な、非マイ ナス整数です。 msgp 引数は、メッセージの種類及び送信されるメッセージを含むユーザ・メモリ・エリア内の 構造へのポインタです。 msgsz 引数は msgp 引数がポイントするデータ構造内で文字配列の長さを指定します。これ は メ ッ セ ー ジ の 長 さ で す 。 こ の 配 列 の 最 大 の サ イ ズ は 、 <linux/msg.h>内 に 位 置 す る MSDMAX 定義によって、決定されます。 msgflg 引数によって、もし IPC_NOWAIT フラグが設定されていなければ((msgflg & IPC_NOWAIT)==0)、動作されるメッセージ・オペレーションをブロックすることができます。も しも指定されているメッセージキュー上で許されている全体のバイト数が使用されていれば (msg_qbytes)、オペレーションはブロックします。もし IPC_NOWAIT フラッグが設定されて いれば、システムコールは失敗し、-1 を返します。 メッセージを受信する msgrcv システムコールが成功すれば、受信したバイト数を返します。成功しないなら、それ は-1 を返します。 msqid 引数は、有効的な非マイナス整数値でなければなりません。換言すれば、それは、 msgget システムコールを使用して既に生成されていなければなりません。 msgp 引数は、メッセージの種類及びメッセージのテキストを受信する、ユーザ・メモリ・エリア 内の構造へのポインタです。 msgaz 引数は、受信されるメッセージの長さを指定します。もしその値が、アレイ内のメッセ ージよりも小さければ、もし望まれればエラーを返します(下の msgflg 引数を見てください)。 msgtyp 引数は、指定されている特定の種類のメッセージキュー上の最初のメッセージをピッ クするのに使用されます。 ・ msgtyp がゼロに等しければ、キュー上の最初のメッセージが受信されます。 ・ msgtyp がゼロよりも大きく、そして MSG_EXCEPTmsgflg が設定されていなければ、 同じ種類の最初のメッセージが受信されます。 ・ 3-33 msgtyp がゼロよりも大きく、そして MSG_EXCEPTmsgflg が設定されていれば、 SUSE Linux Enterprise Real Time Linux User’s Guide msgtyp に等しくないメッセージキュー上の最初のメッセージが受信されます。 ・ msgtyp がゼロよりも小さく、msgtyp の絶対値よりも小さいかまたは等しい、最も低い メッセージ種類が受信されます。 msgflg 引数によって、もし IPC_NOWAIT フラッグが設定されていなければ((msflg & IPC_NOWAIT) == 0)、メッセージ・オペレーションのブロックを動作することができ、指定され ているメッセージキュー上で許されているバイトの全体数が使用されていれば (msg_qbytes)、オペレーションはブロックします。IPC_NOWAIT フラッグが設定されていれ ば、システムコールは失敗し、a-1 を返します。そして、先のパラグラフで述べられているよう に、msgflg 引数内に MSG_EXCEPT フラグが設定されており、msgtyp 引数が 0 よりも大き ければ、msgtyp 引数とは異なるメッセージ種類を持つキュー中の最初のメッセージが受信さ れます。 IPC_NOWAIT フラッグが設定されており、キュー上に望まれる種類のメッセージが無ければ、 システムコールはたちまち失敗します。メッセージが受信されるサイズよりも長い場合、 msgflg も シ ス テ ム が 失 敗 す る と 指 定 す る こ と が で き ま す 。 こ れ は 、 msgflg 引 数 内 で MSG_NOERROR フ ラ ッ グ を 設 定 し な い こ と に よ っ て 成 さ れ ま す ( (msgflg & MSG_NOERROR) ==0)。MSG_NOERROR フラッグが設定されていれば、msgrcv の msgsz が指定している長さにメッセージを短縮できます。 POSIX 共有メモリ POSIX 共有メモリ・インターフェイスによって、共同プロセスがデータを共有することができ、 そして共有メモリ・オブジェクトの使用を通してさらに効率的に通信することができます。共有 メモリ・オブジェクトは、ファイル・システムから独立している名前を付けられた記憶領域である と定義され、そして1つまたはそれ以上のプロセスのアドレス空間にマップされて、結合するメ モリを共有することができます。 インターフェイスは、手短に以下のように説明されます。 shm_open 共有メモリ・オブジェクトを生成し、そして共有メモリ・オブジェクトとファイル記述 子との間の接続を確立します。 shm_unlink 共有メモリ・オブジェクトの名前を取り除きます。 shm_open ルーチンの使用における手順は、“shum_open ルーチンの使用”の中で述べら れています。shm_unlink ルーチンの使用における手順は、“shum_unlink ルーチンの使 用”の中で述べられています。 3-34 SUSE Linux Enterprise Real Time Linux User’s Guide 共同プロセスがこれらのインターフェイスを使用してデータを共有するために、1つのプロセス は以下のステップを完了します。提示されているステップの順序は典型的なもので、使用でき る唯一の順序ではないことに注意します。 ステップ1: 共有メモリ・オブジェクトを生成し、そして shm_open ライブラリ・ルーチン を起動し、ユニークな名前を指定し、リーディング及びライティングにおい て共有メモリ・オブジェクトを開く O_CREAT 及び ORDWR ビットを設定す ることによって、オブジェクトとファイル記述子との接続を確立します。 ステップ2: ftruncate (2)システムコールを起動し、ステップ1で得たファイル記述子 を指定することによって共有メモリ・オブジェクトのサイズを設定します。こ のシステムコールは、メモリ・オブジェクトがライティングにおいてオープン になっていることを必要とします。ftruncate (2)に関する追加的情報につ いては、対応する man page を参照してください。 ステップ3: mmap (2)システムコールを起動し、そしてステップ1で得られたファイル 記述子を指定することによって、プロセスのバーチャル・アドレス空間の部 分を共有メモリ・オブジェクトへマップします(このシステムコールの説明に ついては、“メモリ・マッピング”の章を見てください)。 共有メモリ・オブジェクトを使用するには、他のどの共同プロセスも以下のステップを完了しま す。提示されているステップの順序は典型的なもので、使用できる唯一の順序ではないこと に注意します。 ステップ1: shm_open ライブラリ・ルーチン及びオブジェクトの生成のために使用さ れた同じ名前を指定することによって、最初のプロセスが生成した共有メ モリ・オブジェクトとファイル記述子との間の接続を確立します。 ステップ 2: 共有メモリ・オブジェクトのサイズが知られてなければ、fstat (2)システム コールを起動し、そしてステップ1で得られたファイル記述子及び stat 構 3-35 SUSE Linux Enterprise Real Time Linux User’s Guide 造への(この構造は、<sys/stat.h>内で定義されています) ポインタを指定することによって、共有メモリ・オブジェクトのサイズを取得 します。オブジェクトのサイズは stat 構造の st_size フィールド内で返され ます。オブジェクトと関連するアクセス許可は、st_modes フィールド内で 返されます。fstat(2)に関する更なる情報については、対応するシステム・ man page を参照してください。 ステップ3: mmap を起動し、ステップ1で得られたファイル記述子を指定することに よって、プロセスのバーチャル・アドレス空間の部分を共有メモリ・オブジェ クトへマップします(このシステムコールの説明については、“メモリ・マッ ピング”の章を見てください)。 3-36 SUSE Linux Enterprise Real Time Linux User’s Guide shm_open ルーチンの使用 shm_open (3)ルーチンによって、呼び出しプロセスが POSIX 共有メモリ・オブジェクトを生 成し、そしてオブジェクトとファイル記述子の間の接続を確立することができます。プロセスは 次に shm_open が返すファイル記述子を使用して、ftruncate (2)、fstat (2)、及び mmap (2)への呼び出しの共有メモリ・オブジェクトを参照してください。プロセスが共有メモリ・オブジ ェクト生成した後、他のプロセスは、shm_open を起動し、そして同じ名前を指定することに よって、共有メモリ・オブジェクトとファイル記述子との間の接続を確立することができます。 munmap (2)、exec (2)、または exit (2)を起動することによって、どのプロセスもそのアドレ ス空間と共有メモリ・オブジェクトとの間のマッピングを取り除くまで、また shm_unlink (3)を 起動することによって1つのプロセスが共有メモリ・オブジェクトの名前を取り除くまで、共有メ モリ・オブジェクトが生成された後、共有メモリ・オブジェクト内の全てのデータは残ります。 概要 #include <sys/types.h> #include <sys/mman.h> int shm_open (const chr *name, int oflag, mode_t mode) ; 引数は以下のように定義されます。 name 共有メモリ・オブジェクトの名前を指定するヌル終端ストリングへのポイン タです。このストリングは最大 255 文字を含むことが注意されます。それ はリーディング・スラッシュ(/)文字を含みますが、しかしそれは embedded スラッシュ文字を含みません。この名前はファイル・システム の一部ではないことに注意します。 リーディング・スラッシュ文字も現在のワーキング・ディレクトリも、その解 釈には影響を与えないことに注意します(/shared_obj と shared_obj は 同じ名前であると解釈されます)。しかし、POSIX インターフェイスをサポ ートするどのシステムにも移植可能なコードをライトしないならば、name はスラッシュ文字で始めることが薦められます。 oflag 3-37 SUSE Linux Enterprise Real Time Linux User’s Guide 以下のビットの1つまたはそれ以上を設定する整数値 O_RDONLY と O_RDWR は、互いに排他的なビットであることが注意さ れます。どちらか一方だけが設定されなければなりません。 O_RDONLY 共有メモリ・オブジェクトがリーディングに対してのみ開かれるよ うにします。 O_RDWR 共有メモリ・オブジェクトがリーディング及びライティングに対して 開かれるようにします。共有メモリ・オブジェクトを生成するプロ セスは、ftruncate (2)を起動してそのサイズを設定するために、 ライティングに対してそれを開かなければならないことに注意し ます。 O_CREAT もしもそれが存在しないならば、name が指定する共有メモリ・ オブジェクトが生成されるようにします。メモリ・オブジェクトのユ ーザ ID は、呼び出しプロセスの有効的ユーザ ID に設定されて います。そしてその許可ビットは、mode 引数が指定するように 設定されます。 もしも name が指定する共有メモリ・オブジェクトが存在するなら、 O_CREAT の設定は、O_EXCL で触れられているものを除け ば、影響力を持ちません。 O_EXCL もしも O_CREAT が設定されており、name が指定する共有メモ リ・オブジェクトが存在するなら、shm_open を失敗させます。も し O_CREAT が設定されていないなら、このビットは無視されま す。 O_TRUNC もしもオブジェクトが存在し、リーディング及びライティングに対し て開かれているなら、name が指定する共有メモリ・オブジェクト の長さをゼロへと短縮させます。オーナー及び指定されている 共有メモリ・オブジェクトのモードは交換できません。 mode name が指定する共有メモリ・オブジェクトの許可ビットを、以下の例外で 設定する整数値: プロセスのファイル・モード生成マスクで設定されてい るビットは、共有メモリ・オブジェクトのモードでクリアされます(更なる情報 については、umask (2)及び chmod (2) man page を参照してください)。 3-38 SUSE Linux Enterprise Real Time Linux User’s Guide もし許可ビット以外のビットが mode 内に設定されているなら、それらは無 視されます。プロセスは mode 引数を、それが共有メモリ・オブジェクトを 生成している時にだけ、指定します。 呼び出しが成功の場合、shm_open はサイズがゼロの共有メモリ・オブジェクトを生成し、そ して呼び出しプロセスにおいてオープンでない最低のファイル記述子を返します。 FD_CLOEXEC ファイル記述子フラッグは、新しいファイル記述子に設定されます。このフラ ッグは、共有メモリ・オブジェクトを識別するファイル記述子は、exec (2)システムコールの実 行で閉じられることを示します(更なる情報については、fcntl (2)システム man page を参照 してください)。 -1 の返り値は、エラーが発生したことを示します。エラーを示すために errno が設定されてい ます。起こり得るエラーの種類のリストについては、shm_open (3) man page を参照してく ださい。 shm_unlink ルーチンの使用 shm_unlink (3)ルーチンによって、呼び出しプロセスが共有メモリ・オブジェクトの名前を取 り除くことができます。もしも1つかまたはそれ以上のアドレス空間の部分が、呼び出し時に 共有メモリ・オブジェクトにマップされれば、shm_unlink が返す前に名前は取り除かれます が、しかし最後のプロセスがオブジェクトへのそのマッピングを取り除くまで、共有メモリ・オブ ジェクト内のデータは取り除かれません。もしもプロセスが munmap (2)、exec (2)、または exit (2)を起動すれば、マッピングは取り除かれます。 概要 #include <sys/types.h> #include <sys/mman.h> int shm_unlink (const chr *name) ; 引数は以下のように定義されます。 name 取り除かれる共有メモリ・オブジェクトを示すヌル終端のストリングへのポ インタです。このストリングは最大 255 文字を含むことに注意します。それ はリーディング・スラッシュ(/)文字を含みますが、しかしそれは、 embedded スラッシュ文字は含みません。この名前はファイル・システム の一部ではないことに注意します。リーディング・スラッシュ文字も現在の 3-39 SUSE Linux Enterprise Real Time Linux User’s Guide ワーキング・ディレクトリも、その解釈には影響を与えないことに注意しま す(/shared_obj と shared_obj は同じ名前であると解釈されます)。しか し、POSIX インターフェイスをサポートするどのシステムにも移植可能な コードを記述しないならば、name はスラッシュ文字で始めることが薦めら れます。 0 の返り値は、shm_unlink への呼び出しが成功したことを示します。-1 の返り値は、エラー が発生したことを示します。エラーを示すために errno が設定されています。起こり得るエラ ーの種類のリストについては、shm_unlink (3) man page を参照してください。もしエラーが 発生すれば、shm_unlink への呼び出しは名前の付けられた共有メモリ・オブジェクトを変更 しません。 System V 共有メモリ 共有メモリによって、2 つまたはそれ以上のプロセスがメモリ、及び結果として、そこに含まれ ているデータを共有することができます。共通のバーチャル・メモリ・アドレス空間へのプロセ スのアクセスの設定を許すことによって、これは成されます。この共有はセグメント・ベースで 起こります。それはメモリ・マネージメントでハードウェアに依存しています。 プロセスははじめに、shmget (2)システムコールを使用して共有メモリ・セグメントを生成しま す。生成の際共有メモリ・セグメントにおいて、このプロセスは全体のオペレーション許可を設 定しバイトでのそのサイズを設定し、そして共有メモリ・セグメントは取り付けにおいては参照 におけるのみ(リードのみ)と指定することができます。 もしも共有メモリ・セグメントが参照におけるのみに指定されていなければ、適切なオペレー ション許可のある他の全てのプロセスは、メモリ・セグメントからリードし、メモリ・セグメントに ライトすることができます。 システム上の共有メモリ・セグメントは、-m オプションを使用して/proc/sysvipc/shm ファイ ル及び ipcs (8)経由で見ることができます。 共有メモリ・オペレーション、shmat (2)(共有メモリ取り付け)、及び shmdt (2)(共有メモリ取 り外し)は、共有メモリ・セグメント上で動作させることができます。shmat によって、プロセス は、もしそれらが許可を持つなら、それ自身を共有メモリ・セグメントと結合させることができま す。そしてそれらは、許されているように、リードまたはライトすることができます。shmdt によ って、プロセスはそれ自身を共有メモリ・セグメントとの結合性から外すことができます。よっ て、それらのプロセスは、共有メモリ・セグメントからリードする、共有メモリ・セグメントにライト することはできなくなります。 3-40 SUSE Linux Enterprise Real Time Linux User’s Guide 共有メモリ・セグメントのオリジナルの所有者/生成者は、shmctl (2)システムコールを使用 して他のプロセスに所有権を手放すことができます。しかし、生成プロセスは、機能が取り除 かれるかまたはシステムが再初期化するまで、生成者のもとにとどまります。許可付の他の プロセスは共有メモリ・セグメント上で、shmctl システムコールを使用して他の機能を動作す ることができます。 プロセスは shmbind (2)システムコールを使用して、共有メモリ・セグメントを IO メモリのセク ションへと連結することができます。shmbind システムコールの詳細については、“共有メモ リ・セグメントの IO 空間への結び付け”のセクションを見てください。 共同プログラムによって共有メモリの使用を簡易化するために、shmdefine (1)と呼ばれる ユーティリティが提供されています。このユーティリティの使用における手順については、 “shmdefine ユーティリティ”で説明されています。共有メモリ・セグメントを生成し、それを物理 メモリのセクションに連結するのを手助けするために、shmconfig (1)と呼ばれるユーティリ ティも提供されています。このユーティリティの使用の手順については、“shmconfig コマンド” で説明されています。 共有メモリの使用 プロセス間のメモリの共有は、バーチャル・セグメント・ベース上で起こります。どの時間にお いてもオペレーティング・システム内には、共有メモリ・セグメントのそれぞれ個々のコピーが ただ1つ存在するだけです。 メモリの共有が実現される前には、ユニークに識別されている共有メモリ・セグメント及びデー タ構造が生成されなければなりません。生成されたユニークな識別子は、共有メモリ識別子 (shmid)と呼ばれ、結合するデータ構造を識別するまたは参照するのに使用されます。この 識別子は、システム内のどのプロセスにも、通常アクセス制約に拠って利用可能です。 データ構造は、それぞれの共有メモリ・セグメントにおいて、以下のものを含みます。 3-41 ・ オペレーション許可 ・ セグメント・サイズ ・ セグメント記述子(内的システム使用のみにおいて) ・ PID 動作の最後のオペレーション ・ 生成者の PID ・ 取り付けられているプロセスの現在の数 ・ 最後の取り付けの時間 SUSE Linux Enterprise Real Time Linux User’s Guide ・ 最後の取り外しの時間 ・ 最後の変更時間 結合している共有メモリ・セグメント・データ shmid_ds の定義は、図 3-6 で示されているメンバ を含みます。 図 3-6 shmid_ds 構造の定義 struct shmid_ds { struct ipc_perm shm_perm; /* operation perms */ int shm_segsz; /* size of segment (bytes) */ time_t shm_atime; /* last attach time */ time_t shm_dtime; /* last detach time */ time_t shm_ctime; /* last change time */ unsigned short shm_cpid; /* pid of creator */ unsigned short shm_lpid; /* pid of last operator */ short shm_nattch; /* no. of current attaches */ }; 共有メモリ・セグメント・データ構造 shmid_ds における、C プログラミング言語データ構造定義 は、<sys/shm.h>ヘッダ・ファイル内に位置します。 この構造の shm_perm メンバは ipc_perm をテンプレートとして使用することに注意します。 Ipc_perm データ構造は、全ての IPC 機能において同じです。それは、<sys/ipc.h>ヘッダ・ ファイル内に位置します。 shmget (2)システムコールは、2 つのタスクを動作します。 ・ それは新しい共有メモリ識別子を得、そして結合する共有メモリ・セグメント・データ 構造を生成します。 ・ 既に結合している共有メモリ・セグメント・データ構造を持つ、既存する共有メモリ識 別子を返す。 動作されるタスクは、shmget システムコールへ key 引数の値によって決定されます。 key は選択する整数でもあり得、また、ftok サブルーチンを使用して生成する整数でもあり得 ます。ftok サブルーチンは、パス名及び供給される識別子に基づくキーを生成します。ftok を使用して、ユニークなキーを取得し、そしてパス名と結合するファイルへのアクセスを制限 することによってユーザのキーへのアクセスを制御することができます。キーが共同プロセス によってのみ使用可能であることを確認するためには、ftok を使用することが推奨されます。 このサブルーチンは以下のように指定されます。 3-42 SUSE Linux Enterprise Real Time Linux User’s Guide key_t ftok ( path_name , id ) path_name 引数は、呼び出しプロセスにアクセス可能な存在するファイルのパス名へのポイ ンタを指定します。id 引数は、共同プロセスのグループをユニークに識別する文字を指定しま す。ftok は、指定されている path_name 及び id に基づくキーを返します。ftok の使用に関 する更なる情報は、ftok (3) man page 内で提供されています。 存在する共有メモリ識別子、及び shmflg 内に設定されている IPC_CREAT フラッグにおいて、 key が未だ使用されていないなら、システム・チューニング可能パラメータが超過されないとし て、新しい識別子が、それのために生成された結合する共有メモリ・セグメント・データ構造と 共に返されます。 プライベート・キー(IPC_PRIVATE)として知られる値がゼロの key を指定することにおいても、 準備があります。指定される時、システム・チューニング可能パラメータが超過されなければ、 新しい shmid は常に、それのために生成された関連する共有メモリ・セグメント・データ構造と 共に返されます。ipcs (8)コマンドは、ゼロにおいてと同様に shmid における key フィールドを 示します。 もし shmid が指定されている key において存在するなら、存在する shmid の値が返されます。 もし既存する shmid が返することが望まれないなら、制御コマンド(IPC_EXCL)が shmflg 引 数内で指定(設定)されて、システムコールへ渡します。 新しい共有メモリ・セグメントが生成される時、shmget を呼ぶプロセスは所有者/生成者に なり、そして結合するデータ構造は、相応に初期化されます。所有者権は変更することができ ますが、生成プロセスは常に生成者にとどまることは覚えておかなければなりません (“shmctl システムコール”を見てください)。共有メモリ・セグメントの生成者はさらに、それに おける初期オペレーション許可を決定します。 ユニークに識別されている共有メモリ・セグメント・データ構造が一度生成されると、shmbind、 shmctl、及び共有メモリ・オペレーション(shmop)を使用することができます。 shmbind システムコールによって、共有メモリ・セグメントを IO メモリのセクションへと連結す ることができます。shmbind システムコールの詳細については、“共有メモリ・セグメントの IO 空間への連結”のセクションを見てください。 shmctl (2)システムコールによって、以下の方法で共有メモリ機能を制御することができま 3-43 SUSE Linux Enterprise Real Time Linux User’s Guide す。 ・ 共有メモリ・セグメントと結合するデータ構造を回収します(IPC_STAT) ・ 共有メモリ・セグメントにおいて、オペレーション許可を変更します(IPC_SET) ・ オペレーティング・システムから、それが結合する共有メモリ・セグメント・データ構造と共 に特定の共有メモリ・セグメントを取り除きます(IPC_RMID) ・ メモリ内で共有メモリ・セグメントをロックします(SHM_LOCK) ・ 共有メモリ・セグメントのアンロックします(SHM_UNLOCK) shmctl システムコールの詳細については、“shmctl システムコール”のセクションを見てくだ さい。 共有メモリ・セグメント・オペレーション(shmop)は、共有メモリ・セグメントの取り付け及び取 り外しから構成されます。これらのオペレーションのそれぞれにおいて、shmat 及び shmdt が提供されています(shmat 及び shmdt システムコールの詳細については、“shmat 及び shmdt システムコール”を見てください)。 さらに shmdefine (1)及び shmconfig (1)ユーティリティによって共有メモリ・セグメントを生 成することができることに注意することが重要です。これらのユーティリティに関する情報につ いては、“共有メモリ・ユーティリティ”のセクションを見てください。 3-44 SUSE Linux Enterprise Real Time Linux User’s Guide shmget システムコール shmget (2)は、新しい共有メモリ・セグメントを生成するか、または既存するものを識別しま す。 このセクションでは、shmget システムコールについて説明します。さらに詳細な情報につい ては、shmget (2) man page を見てください。この呼び出しの使用を説明するプログラムは、 /usr/share/doc/ccur/examples/shmget.c に、README.shmget..txt 内で提供されてい る詳細なコメント付であります。 概要 #include <sys/ipc.h> #include <sys/shm.h> int shmget (key_t key, size_t size, int shmflg) ; これらの#include ファイルの全ては、SUSE Linux Enterprise Real Time オペレーティング・ システムのサブディレクトリ/usr/include 内に位置します。 key_t は、<bits/sys/types.h>ヘッダ・ファイル内の typedef によって整数タイプになるように 定義されています(このヘッダ・ファイルは、<sys/types.h>によって内的にインクルードされ ています)。成功した完了でこのシステムコールから返された整数は、key 値と結合する共有 メモリ・セグメント識別子(shmid)です。(shmid は、この章の先の“共有メモリの使用”のセク ションで論じられています。)失敗した場合、外部変数 errno が設定され失敗した理由を示し、 そして-1 が返されます。 以下の状態の1つが真なら、関連する共有メモリ・データ構造の新しい shmid が生成されま す。 ・ key は IPC_PRIVATE に等しい ・ key は未だそれと結合している shmid を持っておらず、そして(shmflg 及び IPC_CREAT)は、“真”(ゼロでない)である。 shmflg の値は、以下のものの組合せです。 3-45 ・ 制御コマンド(フラッグ) ・ オペレーション許可 SUSE Linux Enterprise Real Time Linux User’s Guide 制御コマンドはディフォルト定義の定数です。以下の制御コマンド shmget システムコールに 適用され、そして<bits/ipc.h>ヘッダ・ファイル内で定義されています。そのヘッダ・ファイルは、 <sys/ipc.h>ヘッダ・ファイルによって内的にインクルードされています。 IPC_CREAT 新しいセグメントを生成するのに使用されます。もし使用されなければ、 shmget は key と結合しているセグメントを見つけ、アクセス許可を確証し、 そしてセグメントが破壊としてマークされていないことを確かにします。 IPC_EXCL IPC_CREAT と共に使用されて、もし指定されている key において共有メ モリ識別子が既に存在するなら、システムコールにエラーを返させます。 プロセスが、そうではないのに新しい(ユニークな)識別子を受信したと認 識するのを防ぐために、これは必要です。 オペレーション許可は、ユーザ、グループ、及びその他における、リード/ライト属性を定義し ます。表 3-2 は、有効なオペレーション許可コードにおける、数値を示しています。 表 3-2 共有メモリ・オペレーション許可コード Operation Permissions Octal Value Read by User 00400 Write by User 00200 Read by Group 00040 Write by Group 00020 Read by Others 00004 Write by Others 00002 望まれるオペレーション許可において、8進値を加算するまたはビットごとに論理 OR すること によって、特定の値が生起されます。つまり、もしも“ユーザによるリード”及び“他のものによ る リ ー ド / ラ イ ト ” が 望 ま れ る な ら 、 コ ー ド 値 は 、 00406 ( 00400 プ ラ ス 00006 ) で す 。 <sys/shm.h>内に位置する SHM_R 及び SHM_W 定数はオーナーによって、リード及びラ イト許可を定義するのに使用されます。 8進オペレーション許可値と共同でフラグ名を使用することによって、shmflg 値は容易に設定 することができます。例として: 3-46 SUSE Linux Enterprise Real Time Linux User’s Guide shmid = shmget (key, size, (IPC_CREAT | 0400)) ; shmid = shmget (key, size, (IPC_CREAT | IPC_EXCL | 0400)) ; 以下の値は<sys/shm.h>内で定義されています。これらの値を超えると常に失敗を引き起 こします。 SHMMNI どの時間においても使用できるユニークな共有メモリ・セグメント (shmids)の最大数を決定します。 SHMMIN 最小共有メモリ・セグメント・サイズを決定します。 SHMMAX 最大共有メモリ・セグメント・サイズを決定します。 SHMALL 最大共有メモリ・ページを決定します。 共有メモリ限定値のリストは、以下のオプションを使用して、ipcs (8)コマンドで得ることがで きます。更なる詳細は、man page を見てください。 ipcs –m –1 エラー状態と同様に、特定の結合するデータ構造初期化については、shmget (2) man page を参照してください。 3-47 SUSE Linux Enterprise Real Time Linux User’s Guide shmctl システムコール shmctl (2)は、共有メモリ・セグメント上で制御オペレーションを動作するのに使用されます。 このセクションでは、shmctl システムコールについて説明します。さらに詳細な情報について は、shmctl (2) man page を見てください。この呼び出しの使用を説明するプログラムは、 /usr/share/doc/ccur/examples/shmctl.c に、README.shmctl.txt 内で提供されている 詳細なコメントと共にあります。 概要 #include <sys/ipc .h> #include <sys/shm .h> int shmctl (int shmid, int cmd, struct shmid_ds *buf) ; これらの#include ファイルの全ては SUSE Linux Enterprise Real Time オペレーティング・ システムのサブディレクトリ/usr/include 内に位置します。 shmctl システムコールは、整数値を返します。それは成功した完了ではゼロを、そうでなけ れば-1 を返します。 shmid 変数は、shmget システムコールを使用して既に生成された、有効な非マイナス値で なければなりません。 cmd 引数は、以下の値のどれか1つです。 IPC_STAT 指定されている shmid において、結合するデータ構造内に含まれるステ ータス情報を返し、そして、ユーザ・メモリ・エリア内の buf ポインタがポイ ントするデータ構造内にそれを置きます。 IPC_SET 指定されている shmid において、有効的なユーザ及びグループ ID、そし てオペレーション許可を設定します。 IPC_RMID それと関連するデータ構造と共に指定されている shmid を取り除きます。 3-48 SUSE Linux Enterprise Real Time Linux User’s Guide SHM_LOCK 共有メモリ・セグメントのスワッピングを防ぎます。ロッキングが許可された 後に提示されなければならないページを、ユーザはページ・フォルトしな ければなりません。プロセスは、スーパーユーザーまたはこのオペレーシ ョンを動作する CAP_IPC_LOCK 権限を持たなければなりません。 SHM_UNLOCK メモリから共有メモリ・セグメントのロックを外します。プロセスは、スーパ ーユーザーまたはこのオペレーションを動作する CAP_IPC_LOCK 権限 を持たなければなりません。 注 shmctl (2)サービスはさらに IPC_INFO、SHM_STAT、及び SHM_INFO コマンドをサポート します。しかし、これらのコマンドは、ipcs (8)ユーティリティによる使用向けのみなので、これ らのコマンドについては論じません。 IPC_SET または IPC_RMID 制御コマンドを動作するためには、プロセスは以下の状態の1 つまたはそれ以上を満たさなければなりません。 ・ 所有者の有効的ユーザ ID を持つ ・ 生成者の有効的ユーザ ID を持つ ・ スーパー・ユーザであること ・ CAP_SYS_ADMIN ケーパビリティを持つ 共 有 メ モ リ ・ セ グ メ ン ト は さ ら に 、 ipcrm (1) コ マ ン ド を 使 用 し 、 そ し て -mshmid ま た は -Mshmkey オプションを指定することによって取り除くことができることに注意します。ここで、 shmid は共有メモリ・セグメントにおける識別子を指定し、そして shmkey はセグメントと結合 するキーを指定します。このコマンドを使用するには、IPC_RMID 制御コマンドを動作するの に必要とされるものと同じ権限をプロセスは持たなければなりません。このコマンドの使用に 関する更なる情報については、ipcrm (1) man page を見てください。 3-49 SUSE Linux Enterprise Real Time Linux User’s Guide 共有メモリ・セグメントの IO 空間への結び付け SUSE Linux Enterprise Real Time によって、共有メモリ・セグメントを IO 空間の領域へ連結 することができます。それを行う手順は、以下の通りです。 1. 共有メモリ・セグメントを生成します(shmget (2))。 2. PCI BAR スキャン・ルーチンを使用して IO 領域の物理アドレスを取得します。 3. セグメントを IO メモリに連結します(shmbind (2))。 4. セグメントをユーザのバーチャル・アドレス空間へ取り付けます(shmat (2))。 コマンド・レベルでは、shmconfig (1)ユーティリティは、共有メモリ・セグメントを生成し、そし てそれを物理メモリ領域へと連結するのに使用されます。詳細については、“共有メモリ・ユー ティリティのセクションを参照してください。 shmat 及び shmdt システムコールを使用して、共有メモリ・セグメントをユーザのバーチャ ル・アドレス空間へ取り付けること、及び共有メモリ・セグメントをユーザのバーチャル・アドレ ス空間から取り外すことができます。これらのシステムコールの使用における手順は、 “shmat 及び shmdt システムコール”の中で説明されています。 shmget の使用 shmget (2)システムコールは最初に共有メモリ・セグメントを生成するのに起動されます。呼 び出しの成功した完了において、size の共有メモリ・セグメント・バイトが生成され、そしてセグ メントにおける識別子が返されます。 IO 空間へ連結する時、PCI BAR スキャン・ルーチンを使用して領域のサイズが取得されます (bar_scan_open (3)を見てください)。 shmget の使用についての完全な情報は、“shmget システムコール”で提供されています。 shmbind の使用 共有メモリ・セグメントを生成した後は、shmbind (2)システムコールを使用して、それを IO 空 間の領域へと連結することができます。この呼び出しを使用するには、ルートであるかまたは CAP_SYS_RAWIO 権限がなければならないことに注意します。 デバイスにおける物理アドレスは、システム内のハードウェアの変化によって変化します。て デバイスの参照を確定するために、PCI BAR スキャン・ルーチンを使用して、物理アドレスが 取得されます(bar_scan_open (3)を見てください)。 3-50 SUSE Linux Enterprise Real Time Linux User’s Guide 最初のプロセスがセグメントに取り付けられる前に shmbind は呼ばれなければなりません。 その後、shmat ( )経由でセグメントへの取り付けによって、物理アドレス空間への呼び出し プロセスにおけるバーチャル・アドレス空間のマッピングを効率的に生成されます。 IO 空間の領域は、その開始アドレスとそれに連結される共有メモリ・セグメントのサイズによ って、定義されます。開始アドレスはページ境界線と並んでいなければなりません。共有メモ リ・セグメントのサイズは、shmget への呼び出し上の size 引数を指定することによって確立 されてきました。例として、1024 バイトの共有メモリ・セグメントを生成し、そして、場所 0x2000000(16 進数表記)で始まる物理メモリのセクションへとそれを結び付けたいなら、物 理メモリの結び付けセクションは、メモリ場所 0x2000000 から 0x2000BFF までを含みます。 デバイスにおける物理アドレスは、システム内のハードウェアの変化によって変化することに 注意してください。確定してデバイスを参照するために、PCI BAR スキャン・ルーチンを使用 して、物理アドレスが取得されます。bar_scan_open (3)を見てください。 shmbind へ呼び出しを行うのに必要な仕様は、以下の通りです。 Int shmbind (int shmid, unsigned long paddr) 引数は以下のように定義されます。 shmid 連結したい物理メモリのセクションへの共有メモリ・セグメントにおける識 別子 paddr それに指定されている共有メモリ・セグメントを連結したい、メモリ・セクショ ンの物理アドレスの開始 3-51 SUSE Linux Enterprise Real Time Linux User’s Guide shmat 及び shmdt システムコール 共有メモリ・オペレーション・システムコール、shmat 及び shmdt は、呼び出しプロセスのアド レス空間へ/から、共有メモリ・セグメントを取り付ける、そして取り外すのに使用されます。 このセクションでは、shmat 及び shmdt システムコールについて説明します。さらに詳細な 情報については、shmop (2)を見てください。これらの呼び出しの使用を説明するプログラム は、/usr/share/doc/ccur/examples/shmop.c に、README.shmop.txt 内で提供されて いる詳細なコメントと共にあります。 概要 #include <sys/types.h> #include <sys/shm.h> void *shmat (int shmid, const void *shmaddr, int shmflg) ; int shmdt (const void *shmaddr) ; これらの#include ファイルの全ては SUSE Linux Enterprise Real Time オペレーティング・ システムのサブディレクトリ/usr/include 内に位置します。 3-52 SUSE Linux Enterprise Real Time Linux User’s Guide 共有メモリ・セグメントの取り付け shmat システムコールは、shmid によって識別された共有メモリ・セグメントを、呼び出しプロ セスのアドレス空間へと取り付けます。それは文字ポイント値を返します。成功した完了にお いて、この値はメモリ内のアドレスになります。そこでプロセスは共有メモリ・セグメントに取り 付けられています。成功しなかった場合は、値は-1 です。 shmid 引数は、有効的な、非マイナスの整数値でなければなりません。shmget システムコ ールを使用して、それは既に生成されています。 shmaddr 引数は、shmat システムコールに渡された時、ゼロ、またはユーザ供給です。もし それがゼロなら、オペレーティング・システムは、共有メモリ・セグメントが取り付けられるアド レスを選択します。もしそれがユーザ供給なら、アドレスは、プログラムのアドレス空間内の 有効的なページに並べられたアドレスでなければなりません。以下のものは、いくつかの典 型的なアドレス領域です。 0xc00c0000 0xc00e0000 0xc0100000 0xc0120000 オペレーティング・システムにアドレスを選択させて移植性を高めます。 shmflg 引数は、SHM_RND(切り捨て)及び SHM_RDONLY(リードのみ)フラッグを shmat システムコールに渡すのに使用されます。 共有メモリ・セグメントの取り外し shmdt システムコールは、shmaddr が指定するアドレスに位置する共有メモリ・セグメントを、 呼び出しプロセスのアドレス空間から取り外します。成功した完了ではそれは整数値ゼロを 返し、不成功の場合の値は-1 です。 共有メモリ・ユーティリティ SUSE Linux Enterprise Real Time は、共有メモリ・セグメントの使用を簡易化する 2 つのユ ーティリティを提供します。shmdefine (1)ユーティリティによって、共同プログラムによって使 3-53 SUSE Linux Enterprise Real Time Linux User’s Guide 用 さ れ る 、 1 つ ま た は そ れ 以 上 の 共 有 メ モ リ ・ セ グ メ ン ト を 生 成 す る こと が で き ま す 。 shmconfig (1)コマンドによって、共有メモリ・セグメントを生成し、それを物理メモリのセクシ ョンへと連結することができます。これらのユーティリティは、後に続くセクション内で論じられ ます。 shmdefine ユーティリティ shmdefine ユーティリティは、共同プログラムの集まりによって、共有メモリの使用を簡易化 するように設計されています。1 つまたはそれ以上の共有メモリ・セグメントの使用において共 同するいくつかのプログラムはありますが、ユーティリティを 1 度だけ起動する必要がありま す。shmdefine は、ソース・オブジェクト・ファイルへリンクされなければならないオブジェクト・ ファイルを生み出しますが、リンクする前にそれを起動しなければなりません。 shmdefine は現在、GNU C、Fortran、及び Ada コンパイラ(gcc, g77,GNAT)で、SUSE Linux Enterprise Real Time システム上で実行するプログラムにおいて動作します。 このユーティリティの使用に関する詳細については、Quick Reference for shmdefine (出版 番号 0898010)及び shmdefine (1) man page を参照してください。 3-54 SUSE Linux Enterprise Real Time Linux User’s Guide shmconfig コマンド shmconfig (1)コマンドは、ある程度のキーと結合し、そしてオプション的にそれを IO メモリ の特定のセクションに連結する共有メモリ・セグメントの生成において手助けします。 コマンドシンタックスは: /usr/bin/shmconfig -i DEVSTR /usr/bin/shmconfig -b BARSTR [-s SIZE] [-g GROUP] [-m MODE] [-u USER] {key | -t FNAME} /usr/bin/shmconfig -s SIZE [-p ADDR] [-g GROUP] [-m MODE] [-u USER] {key | -t FNAME} オプションは、表 3-3 で説明されています。 表 3-3 shmconfig(1)コマンドのオプション オプション 説明 --info=DEVSTR, -I DEVSTR DEVSTR にマッチするそれぞれのデバイス上の それぞれのメモリ領域についての情報をプリント します。DEVSTR は、vendor_id:device_id から 構成されます。--bind を使用する時に有益です。 DEVSTR に関する情報については--bind を見て ください。 --bind=BARSTR, -b BARSTR メモリ内の IO 領域を識別して、共有セグメントへ と連結します。BARSTR は以下から構成されま す: vendor_id:device_id:bar_no[:dev_no] vendor_id 及び device_id は、ハードウェア・デバ イスを識別します。通常、コロンで区切られた 2 つ の 16 進数値で表されます(例:8086:100f)。ベン ダーのマニュアル/usr/share/hwdata/pci.ids ま たは lspci -ns から取得できます。これらの ID を指 定する時、“0x”ベース・プリフィックスが必要です。 3-55 SUSE Linux Enterprise Real Time Linux User’s Guide 例:0x8086:0x100f。下の“例”を見てください。 bar_no は、連結されるメモリ領域を識別します。 この値を取得するために-i オプションを使用しま す(出力は、“Region bar_no: Memory at…”と 表示します)。メモリ領域のみが連結されます。 dev_no は、オプション的で、マッチング・ベンダー 及びデバイス ID でマルチ・ボードの間を差異化す るのみに必要です。この値を取得するために-i オ プションを使用します(出力は“Logical device: dev_no:”と表示します)。 このオプションを使用するためには、ユーザは CAP_SYS_RAWIO 権限を持たなければなりま せん。 --size=SIZE, -s SIZE バイトでセグメントのサイズを指定します。--bind では必要ありません。そこは、デフォルトでは完 全なメモリ領域になっています。 --physical=ADDR, -p ADDR セグメントが連結される物理 IO メモリのセクション の開始アドレスとして、ADDR を指定します。この オプションは悪名高く、--bind を使用します。この オプションを使用するためには、ユーザは CAP_SYS_RAWIO 権限を持たなければなりま せん。 --user=USER, -u USER 共有メモリ・セグメントのオーナーのログイン名を 指定します。 --group=GROUP, -g GROUP それに対してセグメントへのグループ・アクセスが 適用できる、グループの名前を指定します。 3-56 SUSE Linux Enterprise Real Time Linux User’s Guide --mode=MODE, -m MODE 共有メモリ・セグメントへのアクセスを管理する許 可の集まりとして mode を指定します。許可を指 定するためには、8進数法を使用しなければなり ません。 --help, -h 利用可能なオプション及び使用法を説明します。 --version, -v コマンドの現在のバージョンをプリント・アウトしま す。 /proc 及び/sys ファイル・システムは、このコマンドを使用するためにマウントされなければな りません。 -s 引数が指定するセグメントのサイズは、そこに置かれるデータのサイズと一致しなければ ならないことに 注意することが重要です。もしも shmdefine が使用されれば、セグメントのサイズは、共有セ グメントの 一部として宣言されている変数のサイズに一致しなければなりません。 より大きなサイズを指定することもできます。(shmdefine に関する情報については、 “shmdefine ユーティリティ”を見てください。) -u、-g、及び-m オプションを指定して、ユーザ及びセグメントと結合するグループを識別し、そ してそれへの アクセス制御許可を設定することが奨められます。もし指定されなければ、セグメントのデフ ォルトのユーザ ID 及びグループ ID は、オーナーのものです。デフォルト・モードでは、0644 です。 key 引数は、共有メモリ・セグメントにおける、ユーザ選択の識別子を表しています。この識別 子は、整数または、存在するファイルを参照する標準パス名です。 shmconfig が実行される時、指定されているキーにおいて、内的データ構造及び共有メモ リ・セグメントが生成されます。もし-p オプションが使用されるなら、共有メモリ・セグメントは、 3-57 SUSE Linux Enterprise Real Time Linux User’s Guide IO メモリに隣接するセクションへ連結されます。 shmconfig が生成した共有メモリ・セグメントへアクセスするには、プロセスは最初に shmget (2)を呼び出して、セグメントにおける識別子を取得しなければなりません。この識別 子は、共有メモリ・セグメントの操作における、他のシステムコールが必要とします。shmget の仕様は: int shmget (key, size, 0) key の値は、shmconfig で指定されている key の値によって決定されます。key の値が整数 なら、その整数は、shmget への呼び出し上の key として指定されなければなりません。key の値がパス名なら、まず ftok サブルーチンを呼び出してパス名上に基づいた整数値を取得 し、shmget への呼び出し上の key として指定しなければなりません。shmconfig は、それ がパス名をキーへと変換する時、ftok をゼロの id で呼ぶため、ftok への呼び出し上の id 引 数の値はゼロでなければならないことに注意することが重要です。size の値は、-s 引数が shmconfig へと指定するバイト数に等しくなければなりません。共有メモリ・セグメントは既に 生成されているため、0 の値はフラッグ引数として指定されなければなりません。 shmget に関する完全な情報については、“shmget システムコール”を見てください。ftok の 使用におけるアシスタントとしては、“共有メモリの使用”及び“ftok (3) man page を見てくだ さい。マップされたメモリのエリアをグローバル・システム・リソースとして扱われるように生成 する際、/etc/init.d ディレクトリ内の shmconfig スクリプトへ行を加えて shmconfig を起動 するのが手助けになることでしょう。そうすることによって、非共同プロセスがそれを使用でき る前に IPC キーを保存することができ、そしてそれは、共同プロセスがセグメントの使用を必 要とする前に、共有メモリ・セグメント及び物理メモリの間の連結を確立することを許可します。 以下の例に似た行を加えます: /usr/sbin/shmconfig –p 0xf00000 –s 0x10000 –u root –g sys –m 0666 key 例 この例では、RCIM デバイス上の物理メモリ領域は、lspci (8)を使用して識別され、そして共 有メモリ領域へと連結されます。lspci を使用するためには、ルートでなければならないことが 注意されます。もしルート権限がなければ、/usr/share/hwdata/pci.ids をビューし、そしてベ ンダー名(RCIM はベンダー“PLX”です)または、デバイス名(RCIM)を検索することができま す。id 値は、ベンダー/デバイス説明の左にリストされています。もし同じデバイスにおいて、 2 つまたはそれ以上のデバイス id がリストされていれば、リストされているそれぞれの device_id 上で shmconfig -i を使用してどれを使用するかを決定します。 1. RCIM ボードにおける bus:slot:func 識別子を見つけます。 3-58 SUSE Linux Enterprise Real Time Linux User’s Guide # lspci –v | grep –I rcim 0d:06 System peripheral: PLX Techonology, Inc. RCIM II Realtime Clock … 2. rcim 識別子を使用して、vendor_id:device_id 番号を取得します。 # lspci –ns 0d:06.0 0d:06. 0 Class 0880: 10b5:8845 (rev 01) 3. このデバイスにおけるメモリ領域を見つけます。lspci は、vendor_id:device_id 値 を 16 進数法フォーマットでプリントしますが、0x プリフィックス無しでは(10b5:8845)、 shmconfig はベース識別子(0x10b5:0x8845)を必要とします。 # shmconfig –i 0x10b5:0x8845 Region 0: Memory at f8d0400 (non-prefetchable) [size=256] /proc/bus/pci0/bus13/dev6/fn0/bar0 Region 1: I/0 ports at 7c00 [size=256] /proc/bus/pci0/bus13/dev6/fn0/bar1 Region 2: Memory at f8d00000 (non-prefetchable) [size=16384] /proc/bus/pci0/bus13/dev6/fn0/bar2 4. rcim メモリ領域#2に連結します。 # shmconfig –b 0x10b5:0x8845:2 –m 0644 –u me –g mygroup 42 5. システム上の IPC 共有メモリ領域を確認します。phys-addr は、上のステップ3内の shmconfig –i コマンドがレポートしたアドレスに連結し、そして一致させる物理アドレス を表していることに注意します。 # cat /proc/sysvipc/shm key shmid perms 42 3-59 size cpid lpid nattch 0 644 16384 1734 0 uid gid cuid cgid atime dtime 0 5388 100 0 0 0 ctime physaddr 0 1087227538 f8d00000 SUSE Linux Enterprise Real Time Linux User’s Guide 4 プロセス・スケジューリング この章では、SUSE Linux Enterprise Real Time システム上のプロセス・スケジューリングの 概要を提供します。それは、プロセス・スケジューラが次にどのプロセスを実行するのかをど のようにして決めるのかを説明し、そして、POSIX スケジューリング・ポリシー及びプライオリ ティについて述べます。それは、プログラム・インターフェイスの使用、及びプロセス・スケジュ ーリングをサポートするコマンドにおける手順を説明し、そしてパフォーマンスについて論じま す。 概要 SUSE Linux Enterprise Real Time OS において、スケジュール可能なエンティティは常にプ ロセスです。スケジューリング・プライオリティ及びスケジューリング・ポリシーは、プロセスの 属性です。システム・スケジューラはいつプロセスが走るのかを決めます。コンフィグレーショ ン・パラメータ、プロセス動作、そしてユーザ要求に基づいて、それはプライオリティを維持し ます。CPU バインドが CPU へプロセスを割り当てるのと同様に、それはこれらのプライオリテ ィを使用します。 スケジューラは 3 つの異なるスケジューリング・ポリシーを提供します。1 つは、ノーマル非決 定的プロセス(SCHED_OTHER)、そして、リアルタイム・アプリケーションにおける、2 つの固 定プライオリティ・ポリシーです(SCHED_FIFO 及び SCHED_RR)。これらのポリシーは、 “スケジューリング・ポリシー”のセクションで詳細に説明されています。 デフォルトでは、スケジューラは SCHED_OTHER タイムシェアリングスケジューリング・ポリ シーを使用します。SCHED_OTHER ポリシー内のプロセスにおいては、インタラクティブ・プ ロセスへの良い応答時間、及び CPU 集中プロセスへの良いスループットを提供する試みの 中で、スケジューラは動作可能なプロセスのプライオリティを動的に操作します。 固定プライオリティ・スケジューリングによって、ユーザはプロセスごとのベースで静的なプラ イオリティを設定することができます。固定されているプライオリティ・スケジューリング・ポリシ ーの 1 つを使用するプロセスのプライオリティを、スケジューラは決して修正しません。他のプ ロセスが動作可能であっても、最高固定プライオリティは常に、それが動作可能になれば、即 CPU をつかまえます。プロセスがプロセス・プライオリティの設定に拠って走る正確な順を、ア プリケーションは指定することができます。 4-1 SUSE Linux Enterprise Real Time Linux User’s Guide リアルタイム動作が要求されないシステム環境においては、デフォルトのスケジューラ・コンフ ィグレーションは問題無く動作し、固定プライオリティ・プロセスを必要としません。しかし、リア ルタイム・アプリケーション、または厳格な時間制約のあるアプリケーションにおいては、固定 プライオリティ・プロセスは、決定的アプリケーションの要求に応えられることを保証する唯一 の方法です。あるプログラムがとても決定的な応答時間を要する時、固定プライオリティ・ス ケジューリング・ポリシーが使用され、そして最も決定的な応答を要するタスクには、最大プラ イオリティが割り当てられます。 IEEE 標準 1003.1b に基づくシステムコールの集まりは、プロセスのスケジューリング・ポリシ ー及びプライオリティへの直接アクセスを提供します。その集まりに含まれるものは、プロセ スがプロセスのスケジューリング・ポリシー及びプライオリティを取得または設定する、及び、 特定のスケジューリング・ポリシーと関連する最小及び最大のプライオリティを取得する、及 び、ラウンド・ロビン(SCHED_RR)・スケジューリング・ポリシー下でスケジュールされたプロ セスと関連するタイム・クワンタムを収得することを可能にするシステムコールです。run (1) コマンドを使用してコマンド・レベルでのプロセスにおける、スケジューリング・ポリシー及びプ ライオリティを変更します。 システムコール及び run コマンドは、この章の後に手順及び効果的な使用法のヒントを交え て詳細に述べられます。 プロセス・スケジューラはどのように動作するのか 図 4-1 は、どのようにスケジューラが動作するのかを説明しています。 図 4-1 SUSE Linux Enterprise Real Time スケジューラ 4-2 SUSE Linux Enterprise Real Time Linux User’s Guide プロセスが生成される時、それは、そのポリシー内のスケジューリング・ポリシー及びプライオ リティを含めて、そのスケジューリング・パラメータを継承します。デフォルトのコンフィグレーシ ョンでは、SCHED_OTHER ポリシーでスケジュールされたタイムシェアリングプロセスとして、 プロセスは開始します。固定プライオリティ下でプロセスをスケジュールさせるためには、シス テムコール経由または run (1)コマンドで、ユーザ要求が作られなければなりません。 ユーザがプロセスのプライオリティを設定する時、ユーザは“ユーザ・プライオリティ”を設定し ています。これは、ユーザが現在のプライオリティを取り戻す時に、sched_getparam (2)呼 び出しがレポートするプライオリティでもあります。移植可能なアプリケーションは、 sched_get_priority_min ( )及び sched_get_priority_max ( )インターフェイスを使用して、 特定のスケジューリング・ポリシーにおける有効なプライオリティの範囲を決定します。ユー ザ・プライオリティ値(sched_priority)は、それぞれのプロセスに割り当てられています。 SCHED_OTHER プロセスは、0 のユーザ・プライオリティに割り当てられるのみです。 SCHED_FIFO 及び SCHED_RR プロセスは 1 から 99 までの範囲のユーザ・プライオリティ を持ちます。 スケジューラは、スケジューリング・ポリシー特定のプライオリティをグローバル・プライオリテ ィへと変換します。グローバル・プライオリティは、SUSE Linux Enterprise Real Time カーネ ルが内的に使用しているスケジューリング・ポリシー値です。スケジューラは、それぞれのあ り得るグローバル・プライオリティ値において、動作可能なプロセスのリストを維持しています。 SCHED_OTHER スケジューリング・ポリシーと関連する 40 のグローバル・スケジューリング・ プライオリティがあり、固定プライオリティ・スケジューリング・ポリシー(SCHED_RR 及び SCHED_FIFO)と結合する 99 のグローバル・スケジューリング・プライオリティがあります。ス ケジューラは最高グローバル・プライオリティの空でないリストを探し、そして、現在の CPU 上 の実行においてこのリストの最前にあるプロセスを選択します。 スケジューリング・ポリシーは、それぞれのプロセスにおいて、リスト内のプロセスがブロックさ れたかまたは動作可能になった時に、同等のユーザ・プライオリティのプロセスのリストのど こに入れるのか、またこのリスト内でのプロセスの相対的位置を決定します。 固定プライオリティ・プロセスが、ある特定の CPU において即実行のものである限り、その CPU 上でタイムシェアリングプロセスが走ることはありません。 スケジューラが CPU へプロセスを割り当てれば、プロセスは、それがそのタイム・クワンタム、 スリープ、ブロックを使い切るまで、またはより高いプライオリティ・プロセスにプリエンプトされ るまで、走ります。 4-3 SUSE Linux Enterprise Real Time Linux User’s Guide ps (1)及び top (1)によって表示されているプライオリティは、内的に計算された値で、ユーザ が設定したプライオリティを間接的にのみ反映していることに注意します。 スケジューリング・ポリシー POSIX は、3 つのスケジューリング・ポリシーを定義しています。それらは、プロセスがスケジ ュールされる方法を制御します。 SCHED_FIFO 先入れ先出し(FIFO)スケジューリング・ポリシー SCHED_RR ラウンド・ロビン(RR)スケジューリング・ポリシー SCHED_OTHER デフォルトのタイムシェアリングスケジューリング・ポリシー 先入れ先出しスケジューリング(SCHED_FIFO) SCHED_FIFO は、0 よりも高いユーザ・プライオリティでのみ使用されます。これは、 SCHED_FIFO プロセスが動作可能になる時、それは常に高速に、現在走っているどの SCHED_OTHER プロセスもプリエンプトすることを意味します。SCHED_FIFO は、時間分 割のない、シンプルなスケジューリング・アルゴリズムです。SCHED_FIFO ポリシー下でスケ ジュールされているプロセスにおいて、以下のルールが適用されます。より高いプライオリテ ィの他のプロセスによってプリエンプトされた SCHED_FIFO プロセスは、そのプライオリティ のためにリストの前部にとどまり、より高いプライオリティの全てのプロセスが再びブロックさ れると即実行を再開します。SCHED_FIFO プロセスが動作可能になれば、そのプライオリテ ィのためリストの最後に入れられます。sched_setscheduler (2)または sched_setparam (2)への全ての呼び出しは、pid によって識別される SCHED_FIFO プロセスを、もしそれが動 作可能なら、リストの最後に置きます。sched_yield (2)を呼び出すプロセスは、そのプライ オリティ・リストの最後に置かれます。同等のユーザ・プライオリティで動作可能のプロセスの 待ちリストの中で SCHED_FIFO ポリシー下でスケジュールされているプロセスを、他のどの イベントも動かすことはできません。SCHED_FIFO プロセスは、それが IO 要求でブロックさ れるか、より高いプライオリティ・プロセスにプリエンプトされるか、または sched_yield を呼 び出すまで、走ります。 ラウンド・ロビン・スケジューリング (SCHED_RR) SCHED_RR は、SCHED_FIFO を単純に向上させたものです。SCHED_FIFO において上 で述べられている全ては、SCHED_RR にも適用します。例外は、それぞれのプロセスは、最 大タイム・クワンタムにおいて走ることを許されているのみということです。もし SCHED_RR プロセスが、タイム・クワンタムと同等またはより以上の時間走ったなら、それは、そのプライ オリティにおいてリストの最後に置かれます。より高いプライオリティ・プロセスによってプリエ ンプトされ、そして続いて動作プロセスとして実行を再開する SCHED_RR プロセスは、その 4-4 SUSE Linux Enterprise Real Time Linux User’s Guide ラウンド・ロビン・タイム・クワンタムの未満部分を完了します。タイム・クワンタムの長さは、 sched_rr_get_interval (2)によって取り戻すことができます。タイム・クワンタムの長さは、 SCHED_RR スケジューリング・ポリシー下でスケジュールされているプロセスと結合する良 い値に影響されます。より高い良い値には、より大きいタイム・クワンタムを与えられます。 タイムシェアリングスケジューリング (SCHED_OTHER) SCHED_OTHER は、ユーザ・プライオリティ 0 で使用できるのみです。SCHED_OTHER は、 デフォルトの普遍なタイムシェアリングスケジューラ・ポリシーで、それは、特別のユーザ・プラ イオリティ・リアルタイム・メカニズムを要求しない全てのプロセスに志向されています。動作 するプロセスは、ユーザ・プライオリティ 0 リストから選ばれたもので、そのリストはそのリスト 内側でのみ決定されている動的プライオリティに基づいています。動的プライオリティは、良 いレベル上に基づいており(nice (2)または setpriority (2)システムコールによって設定され ています)、そしてプロセスが走ることができる、それぞれのタイム・クワンタムにおいて増加 し、しかしスケジューラには走ることを拒否されます。これは、全ての SCHED_OTHER プロ セス間で均等な進歩を確かなものにします。他の要素、IO オペレーションを動作させることに よってプロセスが自発的にそれ自身をブロックする回数のようなものも、考慮に入れられま す。 動作における手順 プライオリティをどのように設定するか 以下のコード・セグメントは、現在のプロセスを、60 の固定プライオリティの SCHED_RR 固定 プライオリティ・スケジューリング・ポリシーの中へ入れます。POSIX スケジューリング・ルーチ ンに関する情報については、この章の後の“プロセス・スケジューリング・インターフェイス”の セクションを見てください。 #include <sched.h> … struct sched_param sparms ; sparms.sched_priority = 60 ; if (sched_setscheduler (0, SCHED_RR, &sparms) < 0) { perror (“sched_setsched”) ; exit (1) ; 4-5 SUSE Linux Enterprise Real Time Linux User’s Guide } 割り込みルーチン 固定プライオリティ・スケジューリング・ポリシーの 1 つの中でスケジュールされているプロセス には、softirqs 及び tasklet と結合するプロセスよりもより高いプライオリティが割り当てられま す。これらの割り込みルーチンは、ある CPU 上で実行していた割り込みルーチンに代わって 動作します。本当の割り込みルーチンは、ハードウェア割り込みレベルで走り、そして CPU 上 の全ての活動をプリエンプトします(固定プライオリティ・スケジューリング・ポリシーの 1 つの 下でスケジュールされているプロセスも含みます)。Linux 下でのデバイス・ドライバ・ライタは、 デバイスと相互作用してデバイスで割り込みが取り扱われたようにするために要求される最 小量を動作するようにされます。そしてデバイス・ドライバは割り込みメカニズムの1つを取り 上げ、デバイス割り込みルーチンと結合する残りの作業を取り扱います。固定プライオリティ・ プロセスは、これらの割り込みルーチンの上のプライオリティで走るため、この割り込みアー キテクチャによって、固定プライオリティ・プロセスは、割り込みルーチンからのジッタ-の最 少量を経験します。デバイス・ドライバの割り込みルーチンについての更なる情報については、 “デバイス・ドライバ”の章を見てください。 SCHED_FIFO と SCHED_RR 2 つの固定プライオリティ・スケジューリング・ポリシーは、その性質においてとても似ており、 そしてほとんどの状態の下では、それらは類似の動作をします。SCHED_RR は、プロセスと 結合するタイム・クワンタムを持っていますが、そのタイム・クワンタムが満了する時、もしも固 定プライオリティ・スケジューリング・ポリシーの1つの中で同等のプライオリティの即実行する プロセスが現在あれば、プロセスは CPU を放棄するだけです。もしも同等のプライオリティを 即実行するプロセスがなければ、オリジナルの SCHED_RR プロセスは、この CPU 上で即走 る最高プライオリティ・プロセスであり、そして同じプロセスが実行のために再び選択すること をスケジューラは決定します。 これは、SCHED_FIFO と SCHED_RR 下でスケジュールされたプロセスの間に違いがある 時のみが、正確に同様のスケジューリング・プライオリティでスケジュールされている固定プラ イオリティ・スケジューリング・ポリシーの1つの下で複数プロセス動作があることを意味しま す。この場合、SCHED_RR によって、これらのプロセスは、プロセスに割り当てられたタイ ム・クワンタムに拠って CPU を共有することができます。プロセスのタイム・クワンタムは nice (2)システムコールに影響することに注意します。より高い良い値のプロセスには、より大きい タイム・クワンタムが割り当てられます。プロセスのタイム・クワンタムも run (1)コマンド経由 で変更されます(詳細については、この章の後の“run コマンド”を見てください)。 4-6 SUSE Linux Enterprise Real Time Linux User’s Guide CPU のロック・アップを処理する固定プライオリティ SCHED_FIFO 及び SCHED_RR スケジューリング・ポリシー下でスケジュールされているプ ロセス内のノン・ブロッキング・エンドレス・ループは、より低いプライオリティで全てのプロセス をいつまでもブロックします。このシナリオは他のプロセスの CPU を完全に枯渇させてしまう ので、これを避けるための予防措置が取られなければなりません。 ソフトウェア開発の間、評価されているアプリケーションよりもより高いユーザ・プライオリティ 下でスケジュールされているコンソール上のシェルを維持することによって、プログラマはこ のようなエンドレス・ループを壊すことができます。これによって、予期されているようにブロッ クまたは終了することをしない、評価されているリアルタイム・アプリケーションの緊急消滅が 可能になります。SCHED_FIFO 及び SCHED_RR プロセスが他のプロセスを常にプリエンプ トすることができるので、ルート・プロセス、または CAP_SYS_NICE ケーパビリティプロセス のみがこれらのポリシーを起動することができます。 メモリ・ロッキング ページング及びスワッピングはしばしば、アプリケーション・プログラムへ予期できない量のシ ステム・オーバーヘッドを加えます。ページング及びスワッピングによるパフォーマンスのロス を無くすために、mlockall (2)、munlockall (2)、mlock (2)、及び munlock (2)システムコ ールを使用して、物理メモリ内のプロセスのバーチャル・アドレス空間の全てまたは部分をロ ックします。 CPU アフィニティ及びシールドされている CPU システム内のそれぞれのプロセスは CPU バインドマスクを持ちます。CPU バインドマスクは、 どの CPU 上でプロセスが実行することを許すかを決定します。CPU がプロセスからシールド されている時、その CPU はそれらの CPU バインドを、シールドされている CPU を含むのみ の CPU の集まりに明確に設定されているプロセスを走らせるのみです。これらのテクニック を利用することは、どこでどのようにプロセスが実行するのかの制御を追加します。更なる情 報については、このガイドの章、“リアルタイム動作”を見てください。 プロセス・スケジューリング・インターフェイス IEEE 標準 1003.1b に基づくシステムコールの集まりは、プロセスのスケジューリング・ポリシ ー及びプライオリティへの直接的アクセスを提供します。run (1)コマンドを使用してコマンド・ レベルでのプロセスにおいて、スケジューリング・ポリシー及びプライオリティを変更します。こ のシステムコールは、下に詳細されています。run コマンドは、後述されています。 4-7 SUSE Linux Enterprise Real Time Linux User’s Guide POSIX スケジューリング・ルーチン この続くセクションでは、POSIX スケジューリング・システムコールの使用における手順を説 明します。これらのシステムコールは、以下のように手短に述べられます。 スケジューリング・ポリシー: sched_setscheduler プロセスのスケジューリング及びプライオリティを設定します sched_getscheduler プロセスのスケジューリング・ポリシーを取得します スケジューリング・プライオリティ: sched_setparam プロセスのスケジューリング・プライオリティを変更します sched_getparam プロセスのスケジューリング・プライオリティを取得します CPU の放棄: sched_yield CPU を放棄します 低/高プライオリティ: sched_get_prioriorty_min スケジューリング・ポリシーと結合している最低のプライオリテ ィを取得します。 sched_get_prioriorty_max スケジューリング・ポリシーと結合している最高のプライオリテ ィを取得します。 ラウンド・ロビン・ポリシー: sched_rr_get_interval SCHED_RR スケジューリング・ポリシー下でスケジュールさ れているプロセスと結合しているタイム・クワンタムを取得しま す。 sched_setscheduler ルーチン sched_setscheduler (2)システムコールによって、スケジューリング・ポリシー及びプロセス において結合しているパラメータを設定することができます。 sched_setscheduler 呼 び 出 し を 使 用 し て プ ロ セ ス の ス ケ ジ ュ ー リ ン グ ・ ポ リ シ ー を 4-8 SUSE Linux Enterprise Real Time Linux User’s Guide SCHED_FIFO または SCHED_RR ポリシーへと変更する、または SCHED_FIFO または SCHED_RR ポリシー下でスケジュールされているプロセスのプライオリティを変更するには、 以下の状態の1つが満たされなければならないことに注意することが重要です。 z 呼び出しプロセスはルートケーパビリティを持たなければなりません。 z 呼び出しプロセスの有効的な ID(uid)は、ターゲット・プロセス(それに対してスケジュー リング・ポリシー及びプライオリティが設定されています)の有効的なユーザ ID に一致し なければならず、または、呼び出しプロセスはスーパーユーザまたは CAP_SYS_NICE ケーパビリティを持たなければなりません。 概要 #include <sched.h> int sched_setscheduler (pid_t pid, int policy, const struct sched_param *p) ; struct sched_param { … int sched_priotiry ; … }; 引数は以下のように定義されます。 pid それにおいてスケジューリング・ポリシー及びプライオリティが設定されているプロ セスのプロセス ID 番号(PID)。現在のプロセスを指定するには、pid の値をゼロに 設定します。 policy ファイル<sched.h>内で定義されているスケジューリング・ポリシー。policy の値は 以下の1つでなければなりません。 SCHED_FIFO 先入れ先出し(FIFO)スケジューリング・ポリシー SCHED_RR ラウンド・ロビン(RR)・スケジューリング・ポリシー SCHED_OTHER タイムシェアリングスケジューリング・ポリシー p pid が識別するプロセスのスケジューリング・プライオリティを指定する構造へのポ インタ。プライオリティは、指定されているポリシーと結合するスケジューラ・クラスに おいて定義されているプライオリティの範囲内に存在する整数値です。以下のシス テムコールの1つを起動することによって、そのポリシーと関連するプライオリティの 範囲を決定することができます: 4-9 sched_get_priority_min ま た は SUSE Linux Enterprise Real Time Linux User’s Guide sched_get_priority_max(これらのシステムコールの説明については、4-11 ペー ジを見てください)。 スケジューリング・ポリシー及び指定されているプロセスが成功して設定されれば、 sched_setscheduler システムコールがプロセスの先のスケジューリング・ポリシーを返しま す。-1 の返り値はエラーが発生したことを示します。errno はエラーを示すように設定されて います。起こり得るエラーの種類のリストについては、sched_setscheduler (2) man page を参照してください。もしもエラーが発生してもプロセスのスケジューリング・ポリシー及びプラ イオリティは変化しません。 プロセスのスケジューリング・ポリシーを変更する時、そのタイム・クワンタムを、新しいポリシ ー及びプライオリティに結合しているスケジューラにおいて定義されているデフォルトのタイ ム・クワンタムへと変更することに注意することが重要です。run (1)コマンドを使用してコマン ド・レベルで SCHED_RR スケジューリング・ポリシー下でスケジュールされているプロセスに おいてタイム・クワンタムを変更することができます。 sched_getscheduler ルーチン sched_getscheduler (2)システムコールによって、指定されているプロセスにおいてスケジ ューリング・ポリシーを取得することができます。スケジューリング・ポリシーは、以下のように ファイル<sched.h>内で定義されています。 SCHED_FIFO 先入れ先出し(FIFO)スケジューリング・ポリシー SCHED_RR ラウンド・ロビン(RR)・スケジューリング・ポリシー SCHED_OTHER タイムシェアリングスケジューリング・ポリシー 概要 #include <sched.h> int sched_getscheduler (pid_t pid) ; 引数は以下のように定義されます。 pid それにおいてスケジューリング・ポリシーを取得したいプロセスのプロセス ID 番号 (PID)。現在のプロセスを指定するために、pid の値をゼロに設定します。 呼び出しが成功すれば、sched_getscheduler は、指定されているプロセスのスケジューリ 4-10 SUSE Linux Enterprise Real Time Linux User’s Guide ング・ポリシーを返します。-1 の返り値はエラーが発生したことを示します。errno はエラーを 示すように設定されています。起こり得るエラーの種類のリストについては、 sched_getscheduler (2) man page を参照してください。 sched_setparam ルーチン sched_setparam (2)システムコールによって、指定されているプロセスのスケジューリング・ ポリシーと結合しているスケジューリング・パラメータを設定することができます。 sched_setparam 呼び出しを使用して、SCHED_FIFO または SCHED_RR ポリシー下でス ケジュールされているプロセスのスケジューリング・プライオリティを変更するには、以下の状 態の1つが満たされなければならないことに注意することが重要です。 ・ 呼び出しプロセスはルートケーパビリティを持たなければなりません。 ・ 呼び出しプロセスの有効的ユーザ ID(euid)は、ターゲット・プロセス(それにおいて スケジューリング・ポリシー及びプライオリティが設定されているプロセス)の有効的 ユーザ ID に一致しなければならず、または呼び出しプロセスはスーパーユーザ CAP_SYS_NICE ケーパビリティを持たなければなりません。 概要 #include <sched.h> int sched_setparam (pid_t pid, const struct sched_param *p) ; struct sched_param { … int sched_priority ; … }; 引数は以下のように定義されます。 pid それにおいてスケジューリング・プライオリティが変更されるプロセスのプロセス ID 番号(PID)。現在のプロセスを指定するために、pid の値をゼロに設定します。 p pid が識別するプロセスのスケジューリング・プライオリティを指定する構造へのポ インタ。プライオリティは、プロセスの現在のスケジューリング・ポリシーと結合して いるプライオリティの範囲内に存在する整数値です。高い数は、より好ましいプライ 4-11 SUSE Linux Enterprise Real Time Linux User’s Guide オリティ及びスケジューリングを表します。 sched_getscheduler (2)システムコールを呼び起こすことによって、プロセスのスケジュー リング・ポリシーを取得することができます(このシステムコールの説明については、4-7 ペー ジを見てください)。sched_get_priority_min (2)及び sched_get_priority_max (2)シス テムコールを起動することによって、そのポリシーと結合するプライオリティの範囲を決定す ることができます。 0 の返り値は、指定されているプロセスのスケジューリング・プライオリティが成功して変更さ れたことを示します。-1 の返り値は、エラーが発生したことを示します。errno はエラーを示す ように設定されています。起こり得るエラーの種類のリストについては、sched_setparam (2) man page を参照してください。もしエラーが起こっても、プロセスのスケジューリング・プラ イオリティは変化しません。 sched_getparam ルーチン sched_getparam (2)システムコールによって、指定されているプロセスのスケジューリン グ・プライオリティを取得することができます。 概要 #include <sched.h> int sched_getparam (pid_t pid, struct sched_param *p) ; struct sched_param { … int sched_priority ; … }; 引数は以下のように定義されます。 pid それにおいてスケジューリング・プライオリティを取得したいプロセスのプロセス ID 番号(PID)。現在のプロセスを指定するには、pid の値をゼロへ設定します。 p pid が識別するプロセスのスケジューリング・プライオリティが返される構造へのポイ ンタ。 4-12 SUSE Linux Enterprise Real Time Linux User’s Guide 0 の返り値は、sched_getparam への呼び出しが成功したことを示します。指定されている プロセスのスケジューリング・プライオリティは、p がポイントする構造内で返されます。-1 の返 り値は、エラーが発生したことを示します。errno はエラーを示すように設定されています。起 こり得るエラーの種類のリストについては、sched_getparam (2) man page を参照してくだ さい。 sched_yield ルーチン sched_yield (2)システムコールによって、それが即走るようにされる最高プライオリティ・プ ロセスに再びなるまで、呼び出しプロセスが CPU を放棄することができます。そのプライオリ ティが、即走るようにされている呼び出しプロセスのそれと同等の場合にのみ、sched_yield への呼び出しは有効であることに注意します。このシステムコールは、そのプライオリティが 実行する呼び出しプロセスのそれよりも低いプロセスを可能にするためには使用できませ ん。 概要 #include <sched.h> int sched_yield (void) ; 0 の返り値は、sched_yield への呼び出しが成功したことを示します。-1 の返り値は、エラー が起こったことを示します。errno はエラーを示すように設定されています。 sched_get_priority_min ルーチン sched_get_priority_min (2)システムコールによって、指定されているスケジューリング・ポ リシーと結合する最低の(最も好ましくない)プライオリティを取得することができます。 概要 #include <sched.h> int sched_get_priority_min (int policy) ; 引数は以下のように定義されます。 policy ファイル<sched.h>内で定義されているスケジューリング・ポリシー。policy の値は、 以下の1つでなければなりません。 4-13 SUSE Linux Enterprise Real Time Linux User’s Guide SCHED_FIFO 先入れ先出し(FIFO)スケジューリング・ポリシー SCHED_RR ラウンド・ロビン(RR)・スケジューリング・ポリシー SCHED_OTHER タイムシェアリングスケジューリング・ポリシー 数的により高いプライオリティ値のプロセスは、数的により低いプライオリティ値のプロセスよ り も 前 に ス ケ ジ ュ ー ル さ れ ま す 。 sched_get_priority_max が 返 す 値 は 、 sched_get_priority_min が返す値よりも大きいです。 SUSE Linux Enterprise Real Time では、SCHED_FIFO 及び SCHED_RR においては、ユ ーザ・プライオリティ値域は1から 99 で、SCHED_OTHER においては、プライオリティ 0 で す。 もしも呼び出しが成功すれば、sched_get_priority_min は、指定されているスケジューリン グ・ポリシーと結合する最低のプライオリティを返します。-1 の返り値は、エラーが発生したこ とを示します。errno はエラーを示すように設定されています。起こり得るエラーの種類のリス トを得るには、man page の sched_get_priority_max (2)を参照してください。 sched_get_priority_max ルーチン sched_get_priority_max (2)システムコールによって、指定されているスケジューリング・ ポリシーと結合する最高の(最も好ましい)プライオリティを取得することができます。 概要 #include <sched.h> int sched_get_priority_max (int policy) ; 引数は以下のように定義されます。 policy ファイル<sched.h>内で定義されているスケジューリング・ポリシー。policy の値は、 以下の1つでなければなりません。 4-14 SCHED_FIFO 先入れ先出し(FIFO)スケジューリング・ポリシー SCHED_RR ラウンド・ロビン(RR)・スケジューリング・ポリシー SCHED_OTHER タイムシェアリングスケジューリング・ポリシー SUSE Linux Enterprise Real Time Linux User’s Guide 数的により高いプライオリティ値のプロセスは、数的により低いプライオリティ値のプロセスよ り も 前 に ス ケ ジ ュ ー ル さ れ ま す 。 sched_get_priority_max が 返 す 値 は 、 sched_get_priority_min が返す値よりも大きいです。 SUSE Linux Enterprise Real Time では、SCHED_FIFO 及び SCHED_RR においては、ユ ーザ・プライオリティ値域は1から 99 で、SCHED_OTHER においては、プライオリティ 0 で す。 もし呼び出しが成功すれば、sched_get_priority_min は、指定されているスケジューリン グ・ポリシーと関連する最低のプライオリティを返します。-1 の返り値は、エラーが発生したこ とを示します。errno はエラーを示すように設定されています。起こり得るエラーの種類のリス トを得るには、man page の sched_get_priority_max (2)を参照してください。 sched_rr_get_interval ルーチン sched_rr_get_interval (2)システムコールによって、SCHED_RR スケジューリング・ポリシ ー下でスケジュールされているプロセスにおいて、タイム・クワンタムを取得することができま す。タイム・クワンタムは、固定された時間で、それにおいてカーネルは CPU をプロセスへ割 り当てます。それに CPU が割り当てられているプロセスがそのタイム・クワンタムにおいて走 っている時、スケジューリング決定が成されます。同じプライオリティの他のプロセスが走る準 備ができていれば、そのプロセスがスケジュールされます。そうでなければ、他のプロセスが 走り続けます。 概要 include <sched.h> int sched_rr_get_interval (pid_t pid, struct timespec *tp) ; struct timespec { }; 4-15 time_t tv_sec ; /* seconds */ long tv_nsec ; /* nanoseconds */ SUSE Linux Enterprise Real Time Linux User’s Guide 引数は以下のように定義されます。 pid それにおいてタイム・クワンタムを取得したいプロセスのプロセス ID 番号(PID)。現 在のプロセスを指定するには、pid の値をゼロに設定します。 tp それに pid が識別するプロセスのラウンド・ロビン・タイム・クワンタムが返される時 空構造へのポインタ。識別されたプロセスは、SCHED_RR スケジューリング・ポリ シー下で走ります。 0 の返り値は、sched_rr_get_interval への呼び出しが成功したことを示します。指定されて いるプロセスのタイム・クワンタムは、それに tp がポイントする構造の中で返されます。-1 の 返り値は、エラーが発生したことを示します。errno はエラーを示すように設定されています。 起こり得るエラーの種類のリストについては、sched_rr_get_interval (2) man page を参照 してください。 run コマンド run (1)コマンドは、プロセス・スケジューラ属性及び CPU バインドを制御するのに使用されま す。コマンド・シンタックスは: run [オプション] {コマンド[引数] | プロセス/スレッド_指定子} run コマンドは、オプションのリストで述べられている環境内で指定されているコマンドを実行 し、そしてコマンドの終了値で終了します。指定子が与えられれば、run は、指定子が選択し たプロセス/スレッドの集まりの環境を修正します。指定子は、以下で定義されています。コ マンドは、同じコマンド・ライン起動上で指定子と組み合わされません。 run コマンドによって、指定されている POSIX スケジューリング・ポリシー下、及び指定されて いるプライオリティでプログラムを走らせることができます(POSIX スケジューリング・ポリシー の完全な説明については、4 章を見てください)。それによって、SCHED_RR ポリシー下でス ケジュールされているプログラムにおいて、タイム・クワンタムを設定することもできます。 プログラムのスケジューリング・ポリシー及びプライオリティを設定するには、シェルから run コマンドを起動し、そして-policy=policy または-s policy オプションのいずれかを、そして --priority=priority または-P priority オプションのいずれかを指定します。policy における有 4-16 SUSE Linux Enterprise Real Time Linux User’s Guide 効なキーワードは: SCHED_FIFO または fifo 先入れ先出しスケジューリング SCHED_RR または rr ラウンド・ロビン・スケジューリング SCHED_OTHER または other タイムシェアリングスケジューリング priority の値は、指定されているスケジューリング・ポリシー(または、もし-s オプションが使用 されていなければ、現在のスケジューリング・ポリシー)において有効な整数値でなければな りません。より高い数値がより好ましいスケジューリング・プライオリティを表します。 SCHED_RR スケジューリング・ポリシー下でスケジュールされているプログラムにおいてタイ ム・クワンタムを設定するには、さらに、--quantum=quantum または-q quantum オプション を指定します。quantum は、-20 と 19 包含の間の良い値で、-20 が最長の時間割分で、そし て 19 が最小、または良い値に対応しているミリ秒値です。--quantum=list が良い値及びそ れらに同等なミリ秒値を表示します。 --bias=list または-b list オプションを使用して、CPU バインドを設定することができます。list は、コンマで分離されている論理 CPU の数または領域で、例は、“0,2-4,6”です。list はまた、 全てのアクティブ・CPU、またはブート・CPU それぞれをアクティブにする、またはブートする ストリングとして指定されます。CAP_SYS_NICE ケーパビリティは、追加的 CPU を結合に加 えるのに必要とされます。 --negate または-N オプションは、CPU バイアスリストを否定します。バイアスリスト・オプショ ンはまた、否定オプションが指定された時、指定されなければなりません。使用されているバ イアスは、変更リスト内で指定されているものを除いて、システム上の全ての CPU を含みま す。 --copies=count または-c count オプションは、ユーザがコマンドの同一のコピーの指定され ている数を走らせることを許可します。 他のオプションは、情報を表示すること、及びバックグランドでコマンドを走らせることにおい て利用可能です。更なる情報については、run (1) man page を見てください。 プロセス/スレッド_指定子 このパラメータは動作されるプロセスまたはスレッドを指定するのに使用されます。以下のう ちの1つのみが指定されます。複合のコンマで分離されている値は、全ての list において指 4-17 SUSE Linux Enterprise Real Time Linux User’s Guide 定されており、そして領域は適切なところでは許されます。 --all, -a 存在する全てのプロセス及びスレッドを指定します。 --pid=list, -p list 存在する PID のリストを指定して修正します。全てのスケジューラ・オペレーション は、全てのサブ・スレッドも含む、リストされているプロセスの完全な集まりに特定し ています。 --tid=list, -t list 既存する TID のリストを指定して修正します。全てのスケジューラ・オペレーション は、リストされているスレッドのみに特定的で、プロセス内の指定されていない兄弟 スレッドにはそうではありません。 --group=list, -g list プロセス・グループのリストを指定して修正します。リストされているプロセス・グル ープ内に存在する全てのプロセスが修正されます。 --usr=list, -u list ユーザのリストを指定して修正します。リストされているユーザによって所有される、 存在する全てのプロセスが修正されます。リスト内のそれぞれのユーザは、有効的 な数的ユーザ ID または文字ログイン ID のいずれかです。 --name=list, -n list 存在するプロセス名のリストを指定して修正します。 例 1. 以下のコマンドは、デフォルト・プライオリティでデフォルト SCHED_OTHER スケジ ューリング・ポリシー下で CPU 0-3 のどの上でのバックグランド内で、make (1)を走らせ ます。 run –bias=0-3 make & 2. 以下のコマンドは、SCHED_RR(例: ラウンド・ロビン)スケジューリング・ポリシー 内の 10 のプライオリティで date (1)を走らせます。 run –s SCHED_RR –P 10 date 4-18 SUSE Linux Enterprise Real Time Linux User’s Guide 3. 以下のコマンドは、プロセス ID987 のスケジューリング・プライオリティをレベル 32 へと変更します。 run –priority=32 –p 987 4. 以下のコマンドは、プロセス・グループ 1456 内の全てのプロセスを CPU3 へと移動 させます。 run –b 3 –g 1456 5. 以下のコマンドは、名前が“pilot”である全てのプロセスを、プライオリティ 21 で SCHED_FIFO スケジューリング・ポリシー内で走るように設定します。 run –s fifo –P 21 –n pilot 更なる情報については、run (1) man page を参照してください。 4-19 SUSE Linux Enterprise Real Time Linux User’s Guide 5 プロセス間同期化 この章では、プロセス間同期化の様々な要求に応えるために SUSE Linux Enterprise Real Time が提供するツールについて説明します。ここで説明されている全てのインターフェイス は、共有リソースへのアクセスを同期化する共同プロセスの方法を提供します。 マルチ CPU・システム内の多様なプログラムによる共有データへのアクセスの同期化におけ る最も効率的なメカニズムは、スピン・ロックを使用することです。しかし、スピン・ロックを保持 している間に再スケジューリング変数を使用してプリエンプションに対してプロテクトすること なしに、ユーザ・レベルからスピン・ロックを使用することは安全ではありません。 もし移植性が効率性よりも重要であるなら、POSIX カウンティング・セマフォ及び mutex が、 共有データへの同期化アクセスにおける次の最良の選択です。さらに、System V セマフォが 提供されており、それによってプロセスがセマフォ値のやり取りを通して通信することができま す。多くのアプリケーションが 1 つ以上のセマフォの使用を要求するため、このケーパビリティ によってセマフォの集まりまたはキューを生成することができます。 共有メモリ内のデータへの同期化共同プロセスのアクセスに関連する問題は、これらの問題 への解決を提供するためにツールと同様に、論じられます。 プロセス間同期化の理解 それによってリソースの同様の集まりへのアクセスを共同プロセスが対応することができる同 期化メカニズムを複数プロセス・リアルタイム・アプリケーションは必要とします。リソースの例 としては、IO バッファの数、ハードウェア・デバイスのユニット、またはコードの決定的なセクシ ョンがあります。 SUSE Linux Enterprise Real Time は、様々なプロセス間同期化ツールを供給します。これ らには、再スケジューリングへのプロセスの脆弱性を制御するツール、ビジー待ち相互排他 でのクリティカル・セクションへの序キュープロセスのアクセス、クリティカル・セクションへの相 互排他及びプロセス間の相互作用の対応におけるセマフォが含まれます。 2 つまたはそれ以上のプロセスから構成され、共有メモリの使用を通してバーチャル・アドレ ス空間の部分を共有するアプリケーション・プログラムは、共有メモリへのそれらのアクセス へ効率的に対応することができる必要があります。同期化の 2 つの根本的な形式は、共有メ 5-1 SUSE Linux Enterprise Real Time Linux User’s Guide モリへプロセスのアクセスを対応させるのに使用されます。その 2 つは、相互排他、及び状態 同期化です。相互排他メカニズムは、共有リソースへの共同プロセスのアクセスを序キューし ます。状態同期化メカニズムは、アプリケーション定義の状態が満たされるまで、プロセスの 進行を延期します。 相互排他メカニズムは、共同プロセスの 1 つのみがある時のクリティカル・セクション内で実 行可能であることを確かにします。一般的に3つのタイプのメカニズムが相互排他を提供する のに使用されます――ビジー待ちを含むもの、スリープ待ちを含むもの、そしてプロセスがロ ックされているクリティカル・セクションへ入ろうと試みる時に 2 つの組合せを含むもの、です。 スピン・ロックとしても知られているビジー待ちメカニズムは、ハードウェアでサポートされてい るテスト及びセット・オペレーションを使用するロックを取得するロッキング・テクニックを使用し ます。 現在ロック状態にあるビジー待ちロックを、プロセスが取得しようとすれば、現在ロックを保持 しているプロセスがそれを解除し、そして評価及びセット・オペレーションが成功するまで、ロ ッキング・プロセスは評価及び設定オペレーションを再トライし続けます。対照的に、セマフォ のようなスリープ待ちメカニズムは、もしそれが現在ロック状態にあるロックを取得しようとす れば、プロセスをスリープへと置きます。 ロックを取得しようとするほとんどの試みが成功すれば、ビジー待ちメカニズムはとても効率 的です。これは、シンプル評価及び設定オペレーションがビジー待ちロックを取得するために 必要な全てだからです。ロックが保持される時間量が短い時にリソースをプロテクトするのに、 ビジー待ちメカニズムは適切です。これには 2 つの理由があります: 1)ロック保持時間が短 い時、ロックされていない状態内でロッキング・プロセスではロックを見つけやすく、よってロッ ク・メカニズムのオーバーヘッドも最小で、2)ロック保持時間が短い時、ロックの取得におけ る遅延もまた短いからです。ロックがアンロックになる間、ビジー待ちメカニズムは CPU のリ ソースを無駄にするため、ビジー待ち相互排他を使用する時、ロックの取得における遅延は 短く保持することは重要です。一般的なルールとして、ロックが保持されている時間が、2 つ のコンテキスト・スイッチを実行する時間よりも短ければ、ビジー待ちメカニズムは適切です。 クリティカル・セクションはしばしばとても短いです。同期化のコストを比較的小さなものに維 持するために、クリティカル・セクションへ/からの入り/出る上で動作される同期化オペレー ションは、カーネルに入ることはできません。クリティカル・セクションへの入り及びクリティカ ル・セクションからの出と結合する実行オーバーヘッドが、クリティカル・セクションそれ自身の 長さよりも長くなることは、望ましくないことです。 5-2 SUSE Linux Enterprise Real Time Linux User’s Guide スピン・ロックが有効的な相互排他ツールとして使用されるためには、プロセスがスピンして 他のプロセスがロックを開放するのを待つ予期される時間は、短いだけではなく、予想可能 でもなければなりません。ページフォールト、シグナル、及びロックを保持するプロセスのプリ エンプションのような予測不可のイベントは、クリティカル・セクション内の実際の経過時間を 予期していた実行時間から多大に超過させます。最良の場合、クリティカル・セクション内のこ れらの予期していなかった遅延は、他の CPU に予期していたよりも長い遅延を引き起こし、 最悪の場合、それらはデッドロックを引き起こします。メモリ内でのページのロッキングは、プ ログラム初期化の間に完了されて、クリティカル・セクションへ入る時間に影響を与えないよう にされます。再スケジューリング制御におけるメカニズムは、シグナル及びプロセスプリエン プションの制御の低いオーバーヘッド方法を提供します。 セマフォは相互排他を提供する他のメカニズムです。既にロックされているセマフォをロックし ようとするプロセスは、ブロックされるかまたはスリープへと置かれるため、セマフォはスリー プ待ち相互排他の形式です。POSIX カウンティング・セマフォは、共有リソースへのアクセス を制御する移植可能な方法を提供します。ロック及びアンロック・オペレーションにおいて最 速の動作を達成するために実行される単純なインターフェイスを、カウンティング・セマフォは 提供します。System V セマフォは、多くの追加的機能を可能にする複雑なデータ・タイプです。 (例として、セマフォ上にいくつのウェイターがあるかを確認する機能、またはセマフォの集ま り上で動作する機能があります)。 再スケジューリング制御を提供するツールは、“再スケジューリング制御”内で述べられてい ます。ビジー待ち相互排他を実行するツールについては、“ビジー待ち相互排他”内で説明さ れています。プロセス間の相互作用に対応させるツールについては、“状態同期化”内で説 明されています。 POSIX カウンティング・セマフォについては、“POSIX カウンティング・セマフォ”のセクション 内で述べられています。System V セマフォについては、“System V セマフォ”のセクション内 で述べられています。 再スケジュール制御 複数プロセス、リアルタイム・アプリケーションはしばしば、短い時間において、CPU の再スケ ジューリングを遅延させたがります。ビジー待ち相互排他を効率的に使用するには、スピン・ ロックの保持時間が小さく、そして予測可能でなければなりません。 CPU の再スケジューリング及びシグナル扱いは、予測不可能性の主要なソースです。プロセ 5-3 SUSE Linux Enterprise Real Time Linux User’s Guide スはそれがスピン・ロックを得る時、再スケジューリングに影響されないようにし、そしてロック を開放する時は再び影響されるようにします。システムコールは、呼び出しのプライオリティを システム内で最高のものにできますが、そのようにすることのオーバーヘッドは禁制です。 再スケジューリング変数は、再スケジューリング及びシグナル扱いにおける制御を提供しま す。アプリケーション内で変数を登録し、そしてアプリケーションから直接的にそれを操作しま す。再スケジューリングが禁止されている間、クワンタム満了、プリエンプション、及びいくつ かの種類のシグナルが保持されます。 システムコール、及び macros の集まりは、再スケジューリング変数の使用を適用します。以 下に続くセクションでは、変数、システムコール、そして macros が述べられており、そしてそ れらの使用の手順が説明されています。 ここで述べられている初歩的なものは、CPU 再スケジューリングの低いオーバーヘッド制御 及びシグナル・配信を提供します。 再スケジューリング変数の理解 再スケジューリング変数は、<sys/rescntl.h>内で定義されており、再スケジューリングから 単一プロセスが受ける影響性を制御します。 struct resched_var { pid_t rv_pid; … volatile int rv_nlocks; … }; それはアプリケーションによって、プロセスごとまたはスレッドごとのベースで割り当てられ、カ ーネルによってではありません。resched_cntl(2)システムコールは変数を登録し、そしてカ ー ネ ル は 再 ス ケ ジ ュ ー リ ン グ 決 定 を す る 前 に 変 数 を 調 べ ま す 。 resched_lock 及 び resched_unlock macros でユーザ・モードからの変数の直接的操作は、再スケジューリン グ変数をロックし、そしてアンロックします。 resched_cntl システムコールの使用は、“resched_cntl システムコールの使用”の中で説 5-4 SUSE Linux Enterprise Real Time Linux User’s Guide 明されています。再スケジューリング制御 macros の集まりによって、アプリケーションから変 数を操作することができます。これらの macros の使用については、“再スケジューリング制 御 Macros の使用”の中で説明されています。 それぞれのスレッドは、それ自身の再スケジューリング変数を登録しなければなりません。再 スケジューリング変数の位置を登録するプロセスまたはスレッドにおいてのみ、再スケジュー リング変数は有効です。現在の実行下では、再スケジューリング変数は単一スレッドされて いるプロセスによってのみ使用することが推奨されます。 resched_cntl システムコールの使用 resched_cntl システムコールによって、様々な再スケジューリング制御オペレーションを動 作させることができます。これらには、再スケジューリング変数の登録及び初期化、その位置 の取得、そして再スケジューリングが遅延される時間の長さに制限を設定することが含まれ ます。 概要 #include <sys/rescntl.h> int resched_cntl (cmd, arg) int cmd; char *arg ; gcc [options] file -lccur_rt … 引数は以下のように定義されます。 cmd 動作されるオペレーション arg その値が cmd の値に依拠している引数へのポインタ cmd は以下の中の 1 つです。それぞれのコマンドと結合している arg の値が示されていま す。 RESCHED_SET_VARIABLE このコマンドは、呼び出しの再スケジューリング変数を登録します。再スケジューリ ング変数は、プロセス・プライベート・ページ内に位置しなければならず、それは、共 有メモリ・セグメントまたは MAP_SHARED にマップされているファイルを排他しま す。 5-5 SUSE Linux Enterprise Real Time Linux User’s Guide 同じプロセスである 2 つのスレッドは、それらの再スケジューリング変数として同じ アドレスを登録するべきではありません。もしも arg が NULL でなければ、それがポ イントする struct resched_var は初期化され、そして物理メモリの中へロックされま す。もし arg が NULL なら、呼び出しは存在する変数から分離され、そして適切なペ ージがアンロックされます。 fork (2)の後、子プロセスはその親から再スケジューリング変数を継承します。子 の再スケジューリング変数の rv_pid フィールドは、子のプロセス ID へとアップデー トされます。 もしも子プロセスが再スケジューリング変数を継承し、そしてそれが次に 1 つまたは それ以上の子プロセスへと分岐すれば、これらの子プロセスはアップデートされた rv_pid フィールドでスケジューリング変数を継承します。 もしも再スケジューリング変数が、fork(2)、vfork(2)、または clone(2)への呼び出 し時に親プロセス内にロックされれば、再スケジューリング変数は中止します。 こ の コ マ ン ド を 使 用 す る に は 、 ル ー ト 権 限 、 ま た は CAP_IPC_LOCK 及 び CAP_SYS_RAWIO 権限を必要とします。 RESCHED_SET_LIMIT このコマンドは、デバッギング・ツールです。もしも arg が NULL でなければ、それは struct timeval をポイントし、呼び出しが再スケジューリングを遅延する時間の最大 長さを指定します。もしも CPU のローカル・タイマーが許可されていれば、この限定 が超過される時、SIGABRT シグナルは呼び出しへ送られます。 RESCHED_GET_VARIABLE このコマンドは、呼び出しの再スケジューリング変数の位置を返します。arg は再ス ケジューリング変数ポインタをポイントしなければなりません。もしも呼び出しが再ス ケジューリング変数を持たなければ、arg が参照するポインタは NULL に設定され、 そしてその他の場合は、再スケジューリング変数の位置に設定されます。 RESCHED_SERVE このコマンドは resched_unlock に使用されて中断しているシグナル及びコンテキス ト・スイッチをサービスします。アプリケーションは、このコマンドを直接的に使用する必 5-6 SUSE Linux Enterprise Real Time Linux User’s Guide 要はありません。arg は、0 でなければなりません。 再スケジューリング制御 Macros の使用 再スケジューリング制御 macros の集まりによって、再スケジューリング変数をロック及びアン ロックし、そして実際上の再スケジューリング・ロックの数を決定します。これらの macros は 以下のように手短に述べられます。 resched_lock 呼び出しプロセスが保持する再スケジューリング・ロックの数を増します。 resched_unlock 呼び出しプロセスが保持する再スケジューリング・ロックの数を減じます。 resched_nlocks 現在有効な再スケジューリング・ロックの数を返します。 resched_lock 概要 #include <sys/rescntl.h> void resched_lock (r) ; struct resched_var *r ; 引数は以下のように定義されます。 r 呼び出しプロセスの再スケジューリング変数へのポインタ resched_lock は値を返しません。呼び出しプロセスが保持する再スケジューリング・ロック 数をそれは増します。プロセスがカーネルに入らない限り、全ての再スケジューリング・ロック が開放されるまで、クワンタム満了、プリエンプション、そしていくつかのシグナル・デリバーは 遅延されます。 しかし、もしもプロセスが例外を生み出す(例: ページフォールト)、またはシステムコールを 作れば、それが保持する再スケジューリング・ロックの数と関係なく、それはシグナルをまた その他の場合はコンテキスト・スイッチを受けます。以下のシグナルはエラー状態を表し、そ して再スケジューリング・ロックに影響されません。再スケジューリング・ロックは、SIGILL、 5-7 SUSE Linux Enterprise Real Time Linux User’s Guide SIGTRAP、SIGFPE、SIGKILL、SIGBUS、SIGSEGV、SIGABRT、SIGSYS、SIGPIPE、 SIGXCPU、及び SIGXFSZ です。 再スケジューリング変数がロックされている間にシステムコールを作ることは可能ですが、奨 められません。しかし、再スケジューリングがロックされている間、呼び出しプロセスをスリー プにする結果になるどのシステムコールも、行うことは有効ではありません。 resched_unlock 概要 #include <sys/rescntl.h> void resched_unlock (r) ; struct resched_var *r ; 引数は以下のように定義されます。 r 呼び出しプロセスの再スケジューリング変数へのポインタ resched_unlock は、値を返しません。もしも減少の後に大きなロックがなく、そしてコンテキ スト・スイッチまたはシグナルが中断されていれば、それらは即実行されます。 注 rv_nlocks フィールドは、アクティブであるとみなされるロックにおいて正数でなければなりま せん。よって、フィールドがゼロまたはマイナスであれば、それはアンロックされるとみなされ ます。 resched_nlocks 概要 #include <sys/rescntl.h> int resched_nlocks (r) ; struct resched_var *r ; 引数は以下のように定義されます。 r 5-8 SUSE Linux Enterprise Real Time Linux User’s Guide 呼び出しプロセスの再スケジューリング変数へのポインタ resched_nlocks は、現在の実際上の再スケジューリング・ロックの数を返します。 これらの macros の使用に関する更なる情報については、resched_cntl (2) man page を見 てください。 再スケジューリング制御ツールの適用 以下の C プログラム・セグメントは、先のセクションで述べられていたツールを使用しての再ス ケジューリングの制御における手順を説明しています。このプログラム・セグメントは、再スケ ジューリング変数(rv)をグローバル変数として定義し、resched_cntl への呼び出しで変数を 登録し、初期化し、そして、resched_lock 及び resched_unlock それぞれへの呼び出しで 再スケジューリング変数をロックし、アンロックします。 static struct resched_var rv ; int main (int argc , char *argv [] ) { resched_cntl (RESCHED_SET_VARIABLE, (char *) &rv ; resched_lock (&rv) ; /* nonpreemptible code */ … resched_unlock (&rv) ; return 0 ; } ビジー待ち相互排他 ビジー待ち相互排他は、同期化変数を共有リソースと結合することによって達成されます。プ ロセスまたはスレッドがリソースへのアクセスを得たい時、それは同期化変数をロックします。 それがそのリソースの使用を完了する時、それは同期化変数をアンロックします。もしも最初 のプロセスまたはスレッドがリソースをロックさせている間に、他のプロセスまたはスレッドが リソースへのアクセスを得ようと試みれば、ロックの状態を繰り返し確認するのでそのプロセ スまたはスレッドは遅延します。同期化のこの形式は、同期化変数がユーザ・モードから直接 にアクセス可能であること、及びロック及びアンロック・オペレーションのオーバーヘッドがとて も低いものであることを要求します。 5-9 SUSE Linux Enterprise Real Time Linux User’s Guide SUSE Linux Enterprise Real Time は、2 つのタイプの低オーバーヘッド・ビジー待ち相互排 他 変 数 を 提 供 し ま す 。 spin_mutex 及 び nopreempt_spin_mutex で す 。 nopreempt_spin_mutex は自動的に再スケジューリング変数を使用して mutex を保持して いる間、スレッドまたはプロセスをプリエンプト不可にします。spin_mutex は、そうではありま せん。 以下に続くセクション内で、変数及びインターフェイスが定義され、そしてそれらの使用におけ る手順が説明されます。 spin_mutex 変数の理解 ビジー待ち相互排他変数は、スピン・ロックとして知られるデータ構造です。spin_mutex 変数 は、<spin.h>内で以下のように定義されています。 typedef struct spin_mutex { volatile int cont ; } spin_mutex_t ; スピン・ロックには 2 つの状態があります。ロックされているものとアンロックされているもので す。初期化される時、スピン・ロックはアンロック状態です。。 スピン・ロックを使用して共有リソースへのアクセスに対応させたいなら、アプリケーション・プ ログラム内でそれらを割り当て、同期化させたいプロセスまたはスレッドが共有しているメモリ 内にそれらを位置付けしなければなりません。“spin_mutex インターフェイスの使用”内で説 明されているインターフェイスを使用して、それらを操作できます。 spin_mutex インターフェイスの使用 ビジー待ち相互排他インターフェイスのこの集まりによって、スピン・ロックを初期化し、ロック し、そしてアンロックすることができ、さらに、ある特定のスピン・ロックがロックされているか否 かを決定することができます。これらは手短に以下のように説明されます。 spin_init スピン・ロックをアンロック状態へと初期化します。 spin_lock 5-10 SUSE Linux Enterprise Real Time Linux User’s Guide スピン・ロックがロックされるまでロックします。 spin_trylock 指定されているスピン・ロックをロックしようと試みます。 spin_islock 指定されているロックがロックされているか否かを決定します。 spin_unlock 指定されているスピン・ロックをアンロックします。 これらのどのインターフェイスによっても無条件にスピン・ロックをロックできるわけではないこ とに注意することが重要です。提供されているツールを使用してこの機能を構築することがで きます。 注意 スピン・ロック上のオペレーションは再帰的ではありません。プロセスまたはスレッドは、もしも それが既にロックしているスピン・ロックを再ロックしようとすれば、デッドロックになります。 spin_init を呼び出して使用する前に、スピン・ロックを初期化しなければなりません。それぞ れのスピン・ロックにおいてただ一度だけ spin_init を呼び出すことができます。もしも指定さ れているスピン・ロックがロックされているなら、spin_init は効果的にそれをアンロックします。 値は返しません。spin_init インターフェイスは以下のように指定されます。 #include <spin.h> void spin_init (spin_mutex_t *m) ; 引数は以下のように定義されます。 m スピンロックの開始アドレス spin_lock は、スピン・ロックがロックされるまでスピンします。それは値を返しません。インタ ーフェイスは以下のように指定されます。 #include <spin.h> void spin_lock (spin_mutex_t *m) ; 呼び出しプロセスまたはスレッドがスピン・ロックのロッキングに成功すれば、spin_trylock は真を返し、成功しなければ偽を返します。spin_trylock は呼び出しプロセスまたはスレッド をブロックしません。インターフェイスは以下のように指定されます。 #include <spin.h> 5-11 SUSE Linux Enterprise Real Time Linux User’s Guide int spin_trylock (spin_mutex_t *m) ; 指定されているスピン・ロックがロックされていれば spin_islock は真を返し、アンロックされ ていれば偽を返します。それはスピン・ロックをロックしようと試みません。インターフェイスは 以下のように指定されます。 #include <spin.h> int spin_islock (spin_mutex_t *m) ; spinlock は、スピン・ロックをアンロックします。それは値を返しません。インターフェイスは以 下のように指定されます。 #include <spin.h> void spin_unlock (spin_mutex_t *m) ; spin_lock 、 spin_trylock 、 及 び spin_unlock は ト レ ー ス ・ イ ベ ン ト を ロ グ し 、 そ れ が NightTrace に モ ニ タ ー す る こ と に 注 意 し ま す 。 <spin.h> を イ ン ク ル ー ド す る 前 に SPIN_TRACE を定義することによって、アプリケーションはこれらのトレース・イベントを許可 することができます。例: #define SPIN_TRACE #include <spin.h> もしも-lpthread とリンクされていれば、アプリケーションは-lntrace、または-lntrace_thr とも リンクされなければなりません。 これらのインターフェイスの使用に関する更なる情報については、spin_init (3) man page を 参照してください。 spin_mutex ツールの適用 ビジー待ち相互排他における spin_mutex ツールの使用の手順は、以下のコード・セグメント によって説明されています。最初のセグメントは、スピン・ロックを得るための再スケジューリ ング制御と共にどのようにこれらのツールを使用するのかを示し、2 つ目は、どのようにして スピン・ロックを開放するのかを示しています。これらのセグメントはシステムコールも手順呼 び出しも含まないことに注意します。 _m 引数はスピン・ロックを指し、そして_r 引数は、呼び出しプロセスまたはスレッドの再スケ 5-12 SUSE Linux Enterprise Real Time Linux User’s Guide ジューリング変数を指します。スピン・ロックが共有メモリ内に位置することが前提とされます。 ページング及びスワッピングと結合するオーバーヘッドを回避するために、クリティカル・セク ション内で参照されるページは物理メモリ内にロックされていることが奨められます(mlock (2)及び shmctl (2)システムコールを見てください)。 #define spin_acqire (_m,_r) ¥ {¥ resched_lock (_r) ; ¥ while (!spin_trylock (_m)) { ¥ resched_unlock(_r) ; ¥ while (spin_islock (_m)) ; ¥ resched_lock (_r) ; ¥ }¥ } #define spin_release (_m,_r) ¥ {¥ spin_unlock (_m) ; ¥ resched_unlock (_r) ; ¥ } 最初のセグメント内では、spin_trylock 及び spin_islock インターフェイスの使用に注意し ます。スピン・ロックをロックしようと試みているプロセスまたはスレッドがそれがロックされて いることを見つければ、spin_islock 呼び出しがロックを開放するのを、それは待ちます。こ の シ ー ケ ン ス は 、 spin_trylock を 直 接 に ポ ー リ ン グ す る よ り も よ り 効 率 的 で す 。 spin_trylock インターフェイスは、スピン・ロック上を自動的に評価及び設定を行う特別の命 令を含みます。これらの命令は、spin_islock 内で動作される単純なメモリ・リードよりも非効 率的です。 再スケジューリング制御インターフェイスの使用にも注意します。デッドロックを防ぐために、 スピン・ロックをロックする前にプロセスまたはスレッドは再スケジューリングを禁止し、そして スピン・ロックをアンロックした後に、それを再許可します。プロセスまたはスレッドはさらに、 spin_islock への呼び出しの前に再スケジューリングを再許可します。よって、再スケジュー リングはもはや必要以上に遅延することはありません。 nopreemtp_spin_mutex 変数の理解 nopreempt_spin_mutex は、ビジー待ち mutex で、それにより複数スレッドまたはプロセスが 共有リソースへのアクセスに同期化することができます。mutex のロックを保持している間、 スレッドを生成するために、またはプリエンプト不可を処理するために、再スケジューリング変 数は使用されます。スレッドまたはプロセスは複数 mutex のロッキングを安全に入れ子にし 5-13 SUSE Linux Enterprise Real Time Linux User’s Guide ます。nopreempt_spin_mutex は、<nopreempt_spin.h>内で以下のように定義されてい ます。 typedef struct nopreempt_spin_mutex { spin_mutex_t spr_mux ; } nopreempt_spin_mutex_t ; スピン・ロックには 2 つの状態があります。ロックされているものとアンロックされているもので す。初期化されている時、スピン・ロックはアンロックの状態です。。 スピン・ロックを使用して共有リソースへのアクセスに対応したいなら、アプリケーション・プロ グラム内でそれらを割り当て、同期化させたいプロセスまたはスレッドが共有しているメモリ 内にそれらを位置付けしなければなりません。“spin_mutex インターフェイスの使用”内で説 明されているインターフェイスを使用して、それらを操作できます。 nopreempt_spin_mutex インターフェイスの使用 このビジー待ち相互排他インターフェイスの集まりによって、プリエンプト不可スピン・ロックを 初期化、ロック、そしてアンロックすることができます。mutex をロックしつつ、スレッドまたはプ ロセスをプリエンプト不可にするのに、再スケジューリング変数が使用されます。これらは手 短に以下のように説明されます。 nopreempt_spin_init スピン・ロックをアンロックの状態へと初期化します。 nopreempt_spin_init_thread プリエンプションをブロックできることを確実にします。 nopreempt_spin_lock スピン・ロックをロックできるまでスピンします。 nopreempt_spin_trylock 指定されているスピン・ロックをロックしようと試みます。 nopreempt_spin_islock 指定されているスピン・ロックがロックされているか否かを決定します。 nopreempt_spin_unlock 指定されているスピン・ロックをアンロックします。 nopreemtp_spin_init を呼び出してそれらを使用する前に、スピン・ロックを初期化しなけれ ばなりません。それぞれのスピン・ロックにつき一度だけこのインターフェイスを呼び出すこと ができます。指定されているスピン・ロックがロックされていれば、nopreempt_spin_init は 有効的にそれをアンロックします。それは返り値を返しません。このインターフェイスは以下の 5-14 SUSE Linux Enterprise Real Time Linux User’s Guide ように指定されます。 #include <nopreempt_spin.h> void nopreempt_spin_init (nopreempt_spin_mutex_t *m) ; 引数は以下のように定義されます。 m スピン・ロックの開始アドレス nopreempt_spin_lock 及 び nopreempt_spin_trylock が 呼 び 出 さ れ る 時 、 nopreempt_spin_init_thread は、プリエンプションがブロックすることを確実にします。 nopreempt_spin_mutex が複数スレッド・プロセス内で使用される時、-lpthread とリンクして いなけれ ばならず、そして それぞれ のスレッドは少なくとも一度は nopreempt_spin_init_thread を呼ばなければなりません。プロセスが複数スレッドでなけ れば、それはこのルーチンを少なくとも一度は呼ばなければなりません。いくつの mutex をプ ロセスまたはスレッドが使用しているのかに関わらず、このルーチンは一度呼ばれる必要が あるだけです。もしプリエンプション・ブロッキングが確実なら、それはゼロ(0)を返し、そうで なければ、それは errno セットと共に-1 を返します。インターフェイスは以下のように指定され ます。 #include <nopreempt_spin.h> int nopreempt_spin_init_thread (void) nopreempt_spin_lock は、スピン・ロックがロックされるまでスピンします。それは値を返し ません。それは以下のように指定されます。 #include <nopreempt_spin.h> void nopreempt_spin_lock (nopreempt_spin_mutex_t *m) ; nopreempt_spin_trylock は、呼び出しプロセスまたはスレッドがスピン・ロックのロッキン グに成功すれば、真を返し、成功しなければ偽を返します。nopreempt_spin_trylock は呼 び出しプロセスまたはスレッドをブロックしません。インターフェイスは以下のように指定され ます。 #include <nopreempt_spin.h> int nopreempt_spin_trylock (nopreempt_spin_mutex_t *m) ; 指定されているスピン・ロックがロックされていれば、nopreempt_spin_islock は真を返し、 アンロックされていれば偽を返します。それはスピン・ロックをロックしようと試みません。イン 5-15 SUSE Linux Enterprise Real Time Linux User’s Guide ターフェイスは以下のように指定されます。 #include <nopreempt_spin.h> int nopreempt_spin_islock (nopreempt_spin_mutex_t *m) ; nopreempt_spin_unlock は、スピン・ロックをアンロックします。それは値を返しません。イ ンターフェイスは以下のように指定されます。 #include <nopreempt_spin.h> void nopreempt_spin_unlock (nopreempt_spin_mutex_t *m) ; nopreempt_spin_lock、nopreempt_spin_trylock、及び nopreempt_spin_unlock は、 ト レ ー ス ・ イ ベ ン ト を ロ グ し 、 そ れ が NightTrace に モ ニ タ ー す る こ と に 注 意 し ま す 。 <nopreempt_spin.h>をインクルードする前に SPIN_TRACE を定義することによって、アプ リケーションはこれらのトレース・イベントを許可することができます。例: #define SPIN_TRACE #include <nopreempt_spin.h> もしも-lpthread ともリンクされているなら、アプリケーションはさらに、-intrace、または -lntrace_thr とリンクしなければなりません。 これらのインターフェイスの使用に関する更なる情報については、nopreempt_spin_init (3) man page を参照してください。 5-16 SUSE Linux Enterprise Real Time Linux User’s Guide POSIX カウンティング・セマフォ 概要 カウンティング・セマフォは、ロック及びアンロック・オペレーションにおいて、最速のパフォーマ ンスを得るために実行することができる単純なインターフェイスを提供します。カウンティン グ・セマフォは、整数値及びそれにおいて定義されているオペレーションの限定された集まり を持つオブジェクトです。これらのオペレーション及び対応する POSIX インターフェイスは、以 下のものを含みます。 ・ セマフォをゼロまたは正数値へと設定する初期化オペレーション-----sem_init または sem_open ・ セ マ フ ォ の 値 を 減 ず る ロ ッ ク ・ オ ペ レ ー シ ョ ン -----sem_wait または sem_timedwait。もしも結果の値が負なら、オペレーションを動作するタスク はブロックします。 ・ セマフォの値を増すアンロック・オペレーション-----sem_post。もしも結果の値 が 0 よりも小さいかまたは等しければ、セマフォ上でブロックされているタスクの 1 つが呼び起こされます。もしも結果の値がゼロよりも大きければ、セマフォ上 でタスクはブロックされません。 ・ 値が正である際のみにセマフォの値を減ずる条件的ロック・オペレーション ----sem_trywait。もしも値がゼロまたは負なら、オペレーションは失敗します。 ・ セマフォの値のスナップショットを提供する問合せオペレーション -----sem_getvalue ロック、アンロック、及び条件的ロック・オペレーションは、atomic です(オペレーションの集ま りが同時に動作され、そしてそれら全てが同時に動作される際のみ)。 複数の共同スレッドが使用するどのリソースへのアクセスをも制御するのにカウンティング・ セマフォは使用されます。カウンティングセマフォには、名前を付ける事も出来ますし、あるい は、名前なしでも使用できます。sem_init (2)ルーチンへの呼び出しを通して、スレッドは名 前の無いセマフォを生成し、そして初期化します。呼び出し上で指定されている値に、セマフ ォは初期化されます。一度 sem_init ルーチン呼び出しで生成されれば、アプリケーション内 の全てのスレッドは名前の無いセマフォへのアクセスを持ちます。 sem_open ルーチンを呼び出しユニークな名前を指定することによってスレッドが名前を つけた空であるセマフォを作ることが出来ます。 セマフォはセマフォを作るための sem_open へのコールで指定する値で初期化されます。 sem_open を使うことによって異 5-17 SUSE Linux Enterprise Real Time Linux User’s Guide なる仮想空間を持つプロセス間でも、セマフォを共有することが出来ます。 名前なし、あるいは名前をつけたセマフォが初期化される際、その値は利用可能なリソース の数へと設定されます。相互排他を提供するために名前の無いカウンティング・セマフォを使 用するには、セマフォ値は1に設定されるべきです。 クリティカルなリソースへアクセスしたがる共同タスクは、そのリソースをプロテクトするセマフ ォをロックしなければなりません。タスクがセマフォをロックする際、システム内の他のどの共 同タスクからの干渉が無く、それはリソースを使用できることをそれは知っています。それを プロテクトしているセマフォが得られた後のみにリソースがアクセスできるように、アプリケー ションが書かれなければなりません。 セマフォ値が正である限り、リソースは使用において利用可能で、リソースの 1 つは、それを 得ようとする次のタスクへ割り当てられます。セマフォ値がゼロであれば、利用可能なリソー スはありません。リソースを得ようとするタスクは、1 つが利用可能になるまで待たなければな りません。セマフォ値が負であれば、ブロックされている 1 つまたはそれ以上のタスクがあり、 そしてリソースの 1 つを得ようと待っています。タスクがリソースの使用を完了した時、それは セマフォをアンロックし、他のタスクの使用にリソースが利用可能であることを示します。 所有者権という概念はカウンティング・セマフォには適応されません。1 つのタスクがセマフォ をロックし、他のタスクがそれをアンロックします。 オペレーションをアンロックするセマフォは、非同期・シグナル・セーフです。つまり、デッドロッ クを引き起こすこと無く、シグナル扱いルーチンからタスクがセマフォをアンロックすることが できます。 所有者権が無いことは、プライオリティの継承を排除します。タスクがセマフォをロックする時、 それはセマフォの所有者にはならないので、それは、同じセマフォをロックしようとする試みを ブロックするよりプライオリティの高いタスクのプライオリティを一時的に継承することができま せん。結果として、無限のプライオリティ転換が起こります。 5-18 SUSE Linux Enterprise Real Time Linux User’s Guide インターフェイス 以下に続くこのセクションでは、POSIX カウンティング・セマフォインターフェイスの使用にお ける手順を説明します。これらのインターフェイスは以下のように手短に説明されます。 sem_init 名前の無いカウンティング・セマフォを初期化します。 sem_destroy 名前の無いカウンティング・セマフォを取り除きます。 sem_open 名前つきカウンティング・セマフォを作成し、初期化します。 sem_close 名前つきカウンティング・セマフォの使用を放棄します。 sem_unlink 名前つきカウンティング・セマフォを削除します。 sem_wait カウンティング・セマフォをロックします。 sem_trywait 現在アンロックである場合にのみ、カウンティング・セマフォをロックします。 sem_timedwait タイムアウト付きで、カウンティング・セマフォをロックします。 sem_post カウンティング・セマフォをアンロックします。 sem_getvalue カウンティング・セマフォの値を取得します。 これらのインターフェイスを使用するには、アプリケーションを pthread ライブラリでリンクしな ければならないことに注意します。以下の例は、共有ライブラリと動的にリンクする際のコマ ンド・ライン起動を示しています。デフォルトでは、Native POSIX Threads Library(NPTL)が 使用されています。 gcc [options] file.c –lpthread 同じアプリケーションが以下の起動ラインで静的に構築されます。これは LinuxThreads ライ ブラリを使用します。 gcc 5-19 [options] -static file.c -lpthread SUSE Linux Enterprise Real Time Linux User’s Guide sem_init ルーチン sem_init (3)ライブラリ・ルーチンによって、セマフォがプロテクトしている利用可能なリソース の数へとセマフォ値を設定することで、呼び出しプロセスが名前の無いカウンティング・セマフ ォを初期化することができます。相互排他においてカウンティング・セマフォを使用するには、 プロセスは値を 1 に設定します。 LinuxThreads ライブラリを使用する静的にリンクされているプログラムは、プロセスに対して ローカルなカウンティング・セマフォを持つことができるのみであることに注意します(pshared パラメータは、0 に設定されなければなりません)。よって、これらのセマフォは同じアプリケー ション内でのスレッド間で共有されるのみです。 アプリケーション内の 1 つのスレッドがセマフォを生成し初期化した後、同じアプリケーション 内の他の共同スレッドは、sem_wiat、sem_trywait、sem_post、及び sem_getvalue ライ ブラリ・ルーチンを使用してセマフォ上で動作することができます。これらのルーチンは、後に 続くセクション内で説明されます。 fork (2)システムコールが生成した子プロセスは、親が既に初期化したセマフォへのアクセス を継承しません。exec (3)または exet (2)システムコールの起動後も、プロセスはセマフォへ のアクセスを失います。 注意 同じセマフォにおいて複数プロセスが sem_init を呼び起こす際に何が起こるのかを、IEEE 1003.1b-1993 標準は示していません。現在、SUSE Linux Enterprise Real Time 実行は単 純に、最初の sem_init 呼び出しの後に生成された sem_init 呼び出し上で指定されている 値へとセマフォを再初期化します。 アプリケーション・コードが、POSIX インターフェイス(将来のシステムも含みます)をサポート するどのシステムにも移植できることを確実にするために、sem_init を使用する共同プロセ スは、単一プロセスが特定のセマフォを初期化し、そしてそれを一度だけ行うことを確かにし ます。 もしも先の sem_init 呼び出しで既に初期化された後に sem_init が呼び出され、そしてこの 同じセマフォ上で待っているスレッドが現在あれば、これらのスレッドはそれらの sem_wait 呼び出しから返ることは決してなく、そしてそれらは明確に終了される必要があります。 5-20 SUSE Linux Enterprise Real Time Linux User’s Guide 名前の無いカウンティング・セマフォは、sem_destroy ルーチンを起動することによって取り 除かれます(このルーチンの説明については、“sem_destroy ルーチン”を見てください)。 概要 #include <semaphore.h> int sem_init (sem_t *sem, int pshared, unsigned int value) ; 引数は以下のように定義されます。 sem 初期化される名前の無いカウンティング・セマフォを表す sem_t 構造への ポインタ pshared セマフォが 他の プロセ スによって 共有さ れる か否かを 示 す整数 値。 pshared がゼロでない値に設定されていれば、セマフォはプロセス間で共 有されます。pshared がゼロに設定されていれば、セマフォは同じアプリ ケーション内のスレッド間でのみ共有されます。LinuxThread ライブラリを 使用する静的にリンクされているプログラムは、プロセス間で共有されて いるセマフォを使用することができず、そして pshared をゼロに設定しな ければなりません。もしゼロに設定されなければ、sem_init は-1 で返さ れ、そして errno は ENOSYS に設定されます。 value セマフォ値を現在利用可能なリソースの数へと初期化するゼロ、または 正整数値。この数は SEM_VALUE_MAX の値を超えることはできません (この値を確認するためには、ファイル<semaphore.h>を見てください)。 0 の返り値は、sem_init への呼び出しが成功したことを示します。-1 の返り値は、エラーが発 生したことを示します。errno はエラーを示すように設定されています。起こり得るエラーの種 類のリストについては、sem_init (3) man page を参照してください。 sem_detroy ルーチン 注意 セマフォ上でどのプロセスも動作する必要が無くなり、セマフォ上で現在ブロックされているプ ロセスが無くなるまで、名前のないカウンティング・セマフォは取り除かれるべきではありませ ん。 5-21 SUSE Linux Enterprise Real Time Linux User’s Guide 概要 #include <semaphore.h> int sem_destroy (sem_t *sem) ; 引数は以下のように定義されます。 sem 名前のない取り除かれるべきカウンティング・セマフォへのポインタ。 sem_init (3)への呼び出しと共に生成されたカウンティング・セマフォのみ が、sem_destroy を起動することによって取り除かれます。 0 の返り値は、sem_destroy への呼び出しが成功したことを示します。-1 の返り値は、エラ ーが発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラ ーの種類のリストについては、sem_destroy (3) man page を参照してください。 sem_wait ルーチン sem_wait (3)ライブラリ・ルーチンによって、呼び出しプロセスが名前のないカウンティング・ セマフォをロックすることができます。セマフォ値がゼロに等しければ、セマフォは既にロックさ れています。この場合、プロセスがシグナルに割り込みされるまで、またはセマフォがアンロ ックされるまで、プロセスはブロックします。セマフォ値がゼロよりも大きければプロセスはセ マフォをロックし、そして続行します。いずれの場合も、セマフォ値は減ぜられます。 概要 #include <semaphore.h> int sem_wait (sem_t *sem) ; 引数は以下のように定義されます。 sem ロックされる名前のないカウンティング・セマフォへのポインタ 0 の返り値は、指定されているセマフォのロッキングにおいてプロセスが成功したことを示しま す。-1 の返り値は、エラーが発生したことを示します。erno はエラーを示すように設定されて います。起こり得るエラーの種類のリストについては、sem_wait (3) man page を参照してく ださい。 5-22 SUSE Linux Enterprise Real Time Linux User’s Guide sem_open ルーチン sem_open ライブラリルーチンは、名前付きカウンティングセマフォを作成し、初期化します。 プロセスが名前付きカウンティングセマフォを生成するとき、システム固有のユニークなセマ フォとなり、排他制御のため、値を1に設定します。 プロセスが名前を付きセマフォを作った後、 同じ名前を指定して sem_open を再び呼び出 すことによって、他のプロセスがそのセマフォに接点を確立することができます。 成功した場 合、 sem_open ルーチンは、名前をつけたもののアドレスを返します。 プロセスがその後そのアドレスを sem_wait 、 sem_trywait と sem_post への呼び出し でセマフォに関係するために使います。 それが sem_close ルーチンあるいは exec(2)あるいは_exit(2) を呼び出すまで、プロセス は名前をつけられたセマフォに作用し続けます。exec(2)または_exit(2)への呼び出しで、プ ロセスは sem_close への呼び出しのように、名前をつけたセマフォを閉じます。 fork(2) システムコールによって作られた子プロセスは、親プロセスが確立した名前をつけ たセマフォへのアクセスを継承します。 もし一つのプロセスが sem_open への多数のコールをして、そして同じ名前を指定するなら、 (1)プロセス自身が介入しているコールを通して sem_close でセマフォを閉じなかったか、 あるいは(2)若干のプロセスが sem_unlink の呼び出しを通して名前を削除しなかったなら、 同じアドレスがそれぞれのコールで返されるでしょう。 もし多数のプロセスが sem_open へのコールをして、そして同じ名前を指定し、若干のプロ セスが sem_unlink へのコールを通して名前を削除しなかったなら、同じセマフォオブジェク トのアドレスがそれぞれの呼び出しで返されるでしょう。 (同じアドレスが必ずしもそれぞれの 呼び出しで返されないであろうことに注意を払ってください。) もしプロセスが sem_unlink 呼び出しで名前を削除したなら、セマフォオブジェクトの新しいアドレスが返されるでしょう。 概要 #include <semaphore.h> sem_t *sem_open(const char *name, int oflag[, mode_t mode,unsigned int value ]); 引数は以下のように定義されます。 name セマフォの名前を指定するヌルで終了したストリング。接頭辞”sem”が名前の前に接 続されます、そしてセマフォは /dev/shm にデータファイルとして現われるでしょう。 先行するスラッシュ(/)キャラクターが許されます(アプリケーションの移植性ために奨 励されます)、しかし、必ずしもスラッシュを埋め込む必要はありません。先行するスラ ッシュキャラクターと現行の作業ディレクトリのいずれもその解釈に影響を与えません、 例えば/mysem と mysem の共に /dev/shm/sem.mysem と解釈されます。このス 5-23 SUSE Linux Enterprise Real Time Linux User’s Guide トリング が、4文字の接 頭辞を含め て、 /usr/include/limits.h で定義さ れ てい る {NAME_MAX}より小さくなければならないことに注意してください。 oflag 以下のビットの1つまたはそれ以上を設定する整数値 O_CREATE カウンティングセマフォが指定した名前が、もし存在しないなら、生成されるよ うにします。 セマフォのユーザーIDは呼び出しプロセスの有効なユーザーID に設定されます;そのグループIDは呼び出しプロセスの有効なグループIDに 設定されます;そしてそのパーミション部分 mode と同時に value アーギュメン トを同時に指定するように定められています。 セマフォの最初の値は value アーギュメントによって指定された値にセットされ ます。 あなたがこのビットを設定するとき、モードと value アーギュメントの両 方を指定しなくてはならないことに注意してください。 もし、カウンティングセマフォが既に存在しているなら、O_EXEC で注意される ように O_CREATE は効果を持たないでしょう。 O_EXECL もし O_CREAT がセットされ、そしてカウンティングセマフォの指定した名前 が存在するなら、 sem_open は失敗します。 もし O_CREAT が設定され ていないなら、このビットは無視されます。 もし O_CREAT と O_EXCL 以外のフラグ部分が oflag アーギュメントで設 定されるなら、 sem_open ルーチンはエラーを返すことに注意してください。 mode カウンティングセマフォのパーミションをビット指定する整数値: プロセスのファイルモード作成マスクがセットされた場合のカウンティングセマフォのモ ード(umask (2)と chmod (2) man page を参照してください). もしパーミション 部分以外のビットが mode にセットされるなら、それらは無視されます。 名前付きカ ウンティングセマフォを生成を作成するときだけ、mode アーギュメントを指定できま す。 value カウンティングセマフォを、0または、正の値で初期化する値。 この値の最大は、<limit.h>で定義される SEM_VALUE_MAX を越えてはなりませ ん。 この値は、プロセスが名前付きカウンティングセマフォを作るときにだけ指定できま す。 5-24 SUSE Linux Enterprise Real Time Linux User’s Guide もし呼び出しが成功しているなら、 sem_open は 名前付きカウンティングセマフォのアドレ スを返します。 リターン値がエラーが発生したことを示した場合; errno は SEM_FAILED を含むエラーを示 します。 発生するかもしれないタイプのエラーのリストのために sem_open (3) man page を参照してください。 5-25 SUSE Linux Enterprise Real Time Linux User’s Guide sem_close ルーチン sem_close (3)ライブラリルーチンは、呼び出しプロセスの名前付きカウンティングセマフォ に対するアクセスを放棄させます。 sem_close ルーチンはプロセスのセマフォの使用に割 り当てられたシステムリソースを解放します。 プロセスにより sem_close(3)が呼び出された 後にセマフォにアクセスすると SIGSEGV シグナルが配信されます。 セマフォのカウント値は sem_close へのプロセスの呼び出しで影響を受けません。 概要 #include <semaphore.h> int sem_close(sem_t *sem); 引数は以下のように定義されます。 sem アクセスが放棄されるはずである 名前付きカウンティングセマフォへのポインター。 sem_open (3)の戻り値であるカウンティングセマフォのアドレス sem のみが指定 できます 0 のリターン値は sem_close への呼び出しが、成功したことを示します。 -1 のリ ターン値はエラーが発生したことを示します; errno はエラーを示します。 発生す るかもしれないタイプのエラーのリストは sem_close (3) man page を参照して ください。 sem_unlink ルーチン sem_unlink (3)ライブラリルーチンは呼び出しプロセスがカウンティングセマフォの名前を 削除します。 その後、同じ名前を使うことによって、セマフォに接続を確立しようと試みるプロ セスがセマフォの異なったインスタンスに接続を確立するでしょう。 それが sem_close(3) を呼び出す、あるいは exec(2) あるいは exit(2) システムコールするまで、コール時点でセ マフォに対する参照を持っているプロセスがセマフォを使い続けるかもしれません。 概要 #include <semaphore.h> int sem_unlink(const char *name); name セマフォの名前を指定するヌルで終了したストリング。接頭辞”sem”が名前の前に 5-26 SUSE Linux Enterprise Real Time Linux User’s Guide 接続されます、そしてセマフォは /dev/shm にデータファイルとして現われるでしょ う。 先行するスラッシュ(/)キャラクターが許されます(アプリケーションの移植性た めに奨励されます)、しかし、必ずしもスラッシュを埋め込む必要はありません。先 行するスラッシュキャラクターと現行の作業ディレクトリのいずれもその解釈に影響 を与えません、例えば/mysem と mysem の共に /dev/shm/sem.mysem と解 釈されます。このストリングが、4文字の接頭辞を含めて、 /usr/include/limits.h で 定義されている {NAME_MAX}より小さくなければならないことに注意してくださ い。 sem_wait ルーチン sem_wait (3)ライブラリルーチンは呼び出しプロセスが名前なしカウンティングセマフォをロ ックします。 もしセマフォ値がゼロと等しいなら、セマフォはすでにロックされています。 この 場合、それがシグナルによって中断させられる、あるいはセマフォがロックがかかっていなく なるまで、プロセスはブロックします。 もしセマフォ値がゼロより大きいなら、プロセスはセマ フォをロックして、そして進みます。 どちらの場合も、セマフォ値は減少します。 概要 #include <semaphore.h> int sem_wait(sem_t *sem); 引数は以下のように定義されます。 sem ロックされるカウンティングセマフォへのポインター。 0 のリターン値はプロセスが指定されたセマフォをロックすることに成功したことを示 します。 -1 のリターン値がエラーが発生したことを示します; errno はエラーを示 します。 発生するかもしれないタイプのエラーのリストは sem_wait (3) man page を参照してください。 sem_timedwait ルーチン sem_timedwait(3)ライブラリルーチンは呼び出しプロセスが名前なしカウンティングセマフォ をロックすることを可能にします;しかし、もしセマフォがもう1つのプロセスあるいはスレッドが sem_post によってそれをアンロックするしないで、指定されたタイムアウトが期限が切れる とき、待ちは終了させられます。 プログラムが libccur_rt ライブラリにリンクされるとき、タイムアウトは CLOCK_REALTIME 時計を利用します。(より詳細は6章「POSIX クロックとタイマー」を見てください) 概要 5-27 SUSE Linux Enterprise Real Time Linux User’s Guide #include <semaphore.h> #include <time.h> int sem_timedwait(sem_t *sem, const struct timespec *ts); 引数は以下のように定義されます。 sem ロックされるカウンティングセマフォへのポインター ts <time.h>で定義される待ちが終了させられる秒とナノ秒で、一つの時間値を指定す る timespec 構造体へのポインタ。 例 ts.tv_sec = (NULL)+2 ts.tv_nsec = 0 2秒のタイムアウトを確立します。 もっと多くの POSIX 時間構造体についての情 報は、6章「POSIX 時間構造体の理解」を参照してください。 0 のリターン値は、プロセスが指定されたセマフォをロックすることに成功したこと を示します。 -1 のリターン値は、エラーが発生したことを示します; errno はエラ ーを示します。 発生するかもしれないタイプのエラーのリストは sem_wait (3) man page を参照してください。 sem_trywait ルーチン sem_trywait (3)ライブラリ・ルーチンによって、セマフォ値がゼロよりも大きくセマフォがアン ロックさていることを示している際にのみ、呼び出しプロセスがカウンティング・セマフォをロッ クすることができます。もしもセマフォ値がゼロと等しければ、セマフォは既にロックされており、 そして sem_trywait への呼び出しは失敗します。もしもプロセスがセマフォのロッキングに成 功すれば、セマフォ値は減ぜられ、その他の場合はそれは何も変更しません。 概要 #include <semaphore.h> int sem_trywait (sem_t *sem) ; 引数は以下のように定義されます。 sem 5-28 SUSE Linux Enterprise Real Time Linux User’s Guide 呼び出しプロセスがロックしようと試みているカウンティング・セマフォへのポインタ 0 の返り値は、呼び出しプロセスが指定されているセマフォのロッキングに成功したことを示し ます。-1 の返り値は、エラーが発生したことを示します。erno はエラーを示すように設定され ています。起こり得るエラーの種類のリストについては、sem_trywait (3) man page を参照 してください。 sem_post ルーチン sem_post (3)ライブラリ・ルーチンによって、呼び出しプロセスはカウンティング・セマフォをア ンロックすることができます。1 つまたはそれ以上のプロセスがブロックされてセマフォを待っ ていれば、最高プライオリティの待ちプロセスが、セマフォがアンロックされる時に呼び起こさ れます。 概要 #include <semaphore.h> int sem_post (sem_t *sem); 引数は以下のように定義されます。 sem アンロックされるカウンティング・セマフォへのポインタ 0 の返り値は、sem_post への呼び出しが成功したことを示します。-1 の返り値は、エラーが 発生したことを示します。erno はエラーを示すように設定されています。起こり得るエラーの 種類のリストについては、sem_post (3) man page を参照してください。 sem_getvalue ルーチン sem_getvalue (3)ライブラリ・ルーチンによって、呼び出しプロセスが名前のないカウンティ ング・セマフォの値を得ることができます。 概要 #include <semaphore.h> 5-29 SUSE Linux Enterprise Real Time Linux User’s Guide int sem_getvalue (sem_t *sem, int *sval) ; 引数は以下のように定義されます。 sem 値を得たいカウンティング・セマフォへのポインタ sval 指定されているカウンティング・セマフォの値が返される位置へのポインタ。 返される値は、呼び出し間の指定されていない間のセマフォの実際の値 を表します。しかし、この値は、呼び出しからの返り時でのセマフォの実際 の値ではないことに注意することが重要です。 0 の返り値は、sem_getvalue への呼び出しが成功したことを示します。-1 の返り値は、エラ ーが発生したことを示します。erno はエラーを示すように設定されています。起こり得るエラ ーの種類のリストについては、sem_getvalue (3) man page を参照してください。 System V セマフォ 概要 System V セマフォは、プロセス間通信(IPC)メカニズムで、それはセマフォ値のやり取り経 由でプロセスが同期化することを可能にします。多くのアプリケーションは 1 つ以上のセマフ ォの使用を要求するため、オペレーティング・システムは、セマフォの集まりまたは配列を生 成する機能を持ちます。セマフォの集まりは、SEMMSL(<linux/sem.h>で定義されているよ うに)の制限まで、1 つまたはそれ以上のセマフォを含むことができます。セマフォの集まりは、 semget (2)システムコールを使用して生成されます。 単純なセマフォだけが必要とされる時、カウンティング・セマフォはさらに効率的になります (“POSIX カウンティング・セマフォ”のセクションを見てください)。 semget システムコールを動作しているプロセスは、所有者/生成者になり、いくつのセマフ ォが集まりの中にあるのかを決定し、そしてそれ自身をも含む全てのプロセスにおいて、初期 オペレーション許可を設定します。このプロセスは続いて集まりの所有者権を破棄し、または semctl (2)システムコールを使用してオペレーション許可を変更します。生成プロセスは、機 能が存在する限り、生成者として残ります。許可がある他のプロセスは、semctl を使用して 5-30 SUSE Linux Enterprise Real Time Linux User’s Guide 他の制御機能を動作します。 もしセマフォの所有者が許可を出せば、どのプロセスもセマフォを操作することができます。 集まり内のそれぞれのセマフォは、semop (2)システムコールで増し、そして減ずることがで きます(この章の後の“semop システムコール”のセクションを見てください)。 セマフォを増すために、望まれる大きさの整数値は、semop システムコールへと渡されます。 セマフォを減らすためには、望まれる大きさの負(-)値が渡されます。 どの時間においても 1 つのプロセスだけがセマフォの集まりを操作することができることを、 オペレーティング・システムは確かにします。同時の要求は、恣意的な方法で逐次的に動作 されます。 その値よりも 1 つ大きいものでセマフォを減らすことを試みることによって、プロセスはセマフ ォ値がある値よりも大きいことを確認することができます。もしプロセスが成功すれば、セマフ ォ値はその値よりも大きいです。そうでなければ、セマフォ値はそうではありません。これを行 っている間、セマフォ値がオペレーションを許可する(他のプロセスがセマフォを増します)、ま たはセマフォ機能が取り除かれるまで、プロセスはその実行を中断することができます (IPC_NOWAIT フラッグは設定されていません)。 実行を中断する機能は、ブロッキング・セマフォ・オペレーションと呼ばれています。ゼロに等 しいセマフォを確認するプロセスにおいてもこの機能は利用可能で、この確認においてはリ ード許可のみが要求され、ゼロの値を semop システムコールへと渡すことによって、それは 完了されます。 一方、プロセスが成功せず、そしてその実行の中断を要求しなかったならば、それは、ノンブ ロッキング・セマフォ・オペレーションと呼ばれます。この場合、プロセスは-1 を返され、そして 外部 errno 変数が相応に設定されます。 ブロッキング・セマフォ・オペレーションによって、異なる時間点でのセマフォ値経由でプロセ スが同期化することができます。許可されたプロセスによって取り除かれるか、またはシステ ムが再初期化されるまで、IPC 機能はオペレーティング・システム内に残ることも覚えておき ます。 セマフォの集まりが生成される時、集まり内の最初のセマフォは、番号ゼロです。集まり内の 最後の信号番号は、集まりの全体より 1 つ少なく番号付けられます。 5-31 SUSE Linux Enterprise Real Time Linux User’s Guide セマフォの集まり上のこれらのブロッキング/ノンブロッキング・オペレーションのシーケンス を動作するのに、単一システムコールが使用されます。オペレーションのシーケンスを動作す る時、ブロッキング/ノンブロッキング・オペレーションは、集まり内のどのまたは全てのセマ フォに適用されます。さらに、オペレーションはセマフォ番号のどの順序にも適用されます。し かし、それら全てが成功しなければ、オペレーションは行われません。例として、10 のセマフ ォの集まり上の 6 のオペレーションの最初の 3 つ全てが成功し、しかし 4 つ目のオペレーショ ンがブロックされれば 6 つ全てのオペレーションがブロッキング無しに動作されるまで、集まり に変更は行われません。全てのオペレーションが成功し、信号が変更されるか、または 1 つ またはそれ以上の(ノンブロッキング)オペレーションが成功せず、そして何も変更されないか のいずれかになります。要するに、オペレーションはアトム的に動作されます。 単一信号、または信号の集まりにおける不成功のノンブロッキング・オペレーションは、オペ レーションが何も行われない即刻の返りを引き起こすことを覚えておいてください。これが起 こる時、-1 がプロセスに返され、そして外部変数 errno が相応に設定されます。 システムコールはこれらの信号機能をプロセスに利用可能にします。呼び出しプロセスは、シ ステムコールに引数を渡し、そしてシステムコールは成功、または不成功にその機能を動作 します。システムコールが成功の場合は、それはその機能を動作し、そして適切な情報を返 します。その他の場合は、-1 がプロセスに返され、そして外部変数 errno が相応に設定され ます。 POSIX Mutexes の拡張 mutex は共有データ構造を同時に発生する変更から保護して、クリティカルセクションを実 行することに役立つ相互排除機構です。 mutex は2つの状態を持っています:アンロックさ れる(スレッドによって所有されない)、そしてロックされる(1つのスレッドによって所有され る):。 所有しているスレッドが最初に mutex をアンロックするまで、すでにもう1つのスレッ ドによってロックされる mutex をロックしようと試みているスレッドが停止されます。 SUSE Linux Enterprise Real Time の利用可能なスタンダードな POSIX pthread mutex は次の関数を含みます。 これらについての完全な情報は man page を参照してください。 pthread_mutex_init (3)は mutex を初期化します。 pthread_mutex_lock (3)は mutex をロックします。 pthread_mutex_trylock (3)は mutex をロックしようとします。 pthread_mutex_unlock (3)は mutex のロックを開けます。 pthread_mutex_destroy (3)は mutex を破壊します。 5-32 SUSE Linux Enterprise Real Time Linux User’s Guide pthread_mutexattr_init (3)は mutex 属性オブジェクトを初期化します。 pthread_mutexattr_destroy (3)は mutex 属性オブジェクトを破壊します。 pthread_mutexattr_settype (3)は mutex 属性タイプを設定します。 pthread_mutexattr_gettype (3)は mutex 属性タイプを検索します。 それらのサービスのほかに、 SUSE Linux Enterprise Real Time はロバストネスとプライオ リティインヘリタンスを供給する次の POSIX pthread 拡張を含みます。 もしアプリケーショ ンスレッドの1つが、 mutex を持つ間に、死ぬなら、ロバストネスがアプリケーションに回復 するチャンスを与えます。 プライオリティインヘリタンスは、直接、あるいは間接的に、そのス レッドによって所有される mutexes のどれででも寝ている最も高いプライオリティスレッドの プライオリティに自動的にスレッドのスケジューリングプライオリティを引き上げます。 これら の細部の条件は後述されます。 これらの pthread 拡張は下記にセクション“Alternative glibc”で論じられる、glibc の置き換 えで利用できます。 詳細は続くセクションと man page で記述されます。 pthread_mutex_consistent_np (3)は整合性がない mutex の矛盾をなくします。 pthread_mutex_getunlock_np (3)は mutex をアンロックしているポリシーを返します。 pthread_mutex_setconsistency_np (3)は整合性に mutex の状態を割り当てます。 pthread_mutex_setunlock_np (3)は mutex をアンロックしている政策を設定します。 pthread_mutexattr_getfast_np (3)は操作上のモードを返します。 pthread_mutexattr_getprotocol (3)はプロトコルを返します。 pthread_mutexattr_getrobust_np (3)はロバストなレベルを返します。 pthread_mutexattr_getunlock_np (3)はアンロックしているポリシーを返します。 pthread_mutexattr_setfast_np (3)は操作上のモードをセットします。 pthread_mutexattr_setprotocol (3)はプロトコルをセットします。 pthread_mutexattr_setrobust_np (3)はロバストなレベルを設定します。 pthread_mutexattr_setunlock_np (3)はアンロックしているポリシーを設定します。 ロバストな Mutexes ロバストな mutex を使っているアプリケーションは、 mutex を持つ間に、 mutex の前の 所有者が終わったかどうか検出することができます。 新しい所有者はそれから mutex によ って保護される状態をきれいにして、そしてもしそうすることが可能であるなら、 mutex に再 び健全であるというマークを付けようと試みることができます。 もし状態をクリーンアップでき ないなら、それをロックするどんな未来の試みでもリカーバー出来ないため、mutex は unrecoverable であることを示しているようにするように、マーします。 これを実行するために、2つの新しい 5-33 errno コ ー ド 、 EOWNERDEAD と SUSE Linux Enterprise Real Time Linux User’s Guide ENOTRECOVERABLE 、が利用可能です。 mutex を持つ間に、スレッドが死ぬとき、 mutex は自動的にアンロックされて、そして死んでいるとマークを付けられます。 死んだ mutex に関するそれぞれの成功したロックが成功よりむしろ EOWNERDEAD エラーを返 すこと以外、機能を失ったロックが標準的なロックのように稼働します。 そのためにロバストネスに利害関係を有するアプリケーションがすべてのロックのリクエスト のリターンステータスを調べなくてはなりません。 EOWNERDEAD が見られるとき、アプリ ケーションはそれを無視して、所有者の死のためにアプリケーションで間違っているものは何 でも修復して、そして(健康で)それが矛盾がないとマークを付けるか、あるいはもしそれが修 復されることができないなら、それが unrecoverable であるとマークを付けます。 unrecoverable マークが付いた mutex はその mutex の上にすべての未来のオペレーショ ンを ENOTRECOVERABLE エラーで拒絶します。 唯一の例外は mutex を再度初期化 するサービスと mutex 状態を問うサービスです。 unrecoverable マークが付いた mutex で眠っていたスレッドはすぐに ENOTRECOVERABLE エラーで目を覚まします。 プライオリティインヘリタンス プライオリティインヘリタンス mutex を使っているアプリケーションは、優先度を時折、一時 的に引き上げられます。 引き上げは mutex を獲得したそれらのスレッドに起こります、そし て他のより高いプライオリティスレッドがその mutex を眠って待つために動きます。 この場 合、その所有者がロックを持つ限りずっと長い間、眠っているスレッドのプライオリティは一時 的にロック所有者に譲渡されます。 これらの眠っているスレッドの優先度は、ベースではなく、その mutex を所有することのでき る、他のスレッドの優先度に順に引き上げられることに注意してください。 ユーザーインターフェース この章で記述されているサービスをコンパイルして利用するためには、“Alternative glibc”で記 述されるccur-gccとリンクすることで利用可能です。 これらのサービスの完全な記述は、続くセクションで、そして対応するオンラインの man page で提供されます。 次のサービスは mutex の状態に作用します: pthread_mutex_consistent_np (3)は整合性がない mutex を一貫させます。 pthread_mutex_getunlock_np (3)は mutex をアンロックしているポリシーを返します。 pthread_mutex_setconsistency_np (3)は整合性に mutex の状態を割り当てます。 5-34 SUSE Linux Enterprise Real Time Linux User’s Guide pthread_mutex_setunlock_np (3)は mutex をアンロックしているポリシーを設定します。 下記のサービスは作成あるいは、変更されます。mutex 属性オブジェクトにストアされて属 性を問います。 mutex 属性オブジェクトはどの mutex 機能はその属性オブジェクトで作ら れた mutexes で利用可能であるか定義するデータ構造です。 mutexes は多くの機能を 持っていますから、 mutex 属性オブジェクトは、アプリケーションが1つの mutex 属性オブ ジェクトのすべての望ましい属性を定義して、そのオブジェクト属性のそのセットを持っている すべての mutexes を作ることを行います。 加えるに、 mutex の寿命のために直されなくてはならないそれらの属性は mutex 属性オ ブジェクトを通してだけ定義可能です。 同じく、 mutex の寿命の間に変えることができる属 性は mutex 属性オブジェクトを通して最初の定義を与えることができ、mutex 自身の上に 同等の属性オペレーションによって後に変ることができます。 属性を返すために。 pthread_mutexattr_getfast_np (3)は操作上のモードを返します。 pthread_mutexattr_getprotocol (3)はプロトコルを返します。 pthread_mutexattr_getrobust_np (3)はロバストなレベルを返します。 pthread_mutexattr_getunlock_np (3)はアンロックしているポリシーを返します。 特質を設定するために:。 pthread_mutexattr_setfast_np (3)は操作上のモードをセットします。 pthread_mutexattr_setprotocol (3)はプロトコルをセットします。 pthread_mutexattr_setrobust_np (3)はロバストなレベルを設定します。 pthread_mutexattr_setunlock_np (3)はアンロックしているポリシーを設定します。 pthread_mutex_consistent_np このサービスは整合性がない mutex を矛盾をなくします。 概要 int pthread_mutex_consistent_np (pthread_mutex_t *mutex) もしその所有者が、それを持つ間に死ぬなら、mutex に整合性がなくなります。 加えるに、 所有者の死の検出で、 pthread_mutex_unlock が実行されたかのように、アンロックされま す。 次の所有者がそれに所有権を与えた pthread_mutex_lock から EOWNERDEAD エラーリターンを受けること以外、錠は正常として機能し続けます。 これは新しい所有者に 獲得された mutex が整合性がないことを示します。 このサービスはただ整合性がない mutex の所有者によってのみコールすることができま す。 5-35 SUSE Linux Enterprise Real Time Linux User’s Guide pthread_mutex_getunlock_np このサービスはこの mutex をアンロックしているポリシーを返します。 int pthread_mutex_getunlock_np(const pthread_mutex_t *mutex,int *policy) アンロックしているポリシーは*policy で返されます。 PTHREAD_MUTEX_UNLOCK_SERIAL_NP pthread_mutex_unlock が所有者からロックを待っている最も高いプライオリティスレッ ドまで直接ロックにパスするはずです。 PTHREAD_MUTEX_UNLOCK_PARALLEL_NP ロックはロックされていない、そして、もし待っているスレッドがいるなら、それらの最も重 要なものは目覚めさせられます。 それがもし初めてロックを獲得しようとるとき、呼び起 こされたスレッドはロックを求めて争います。 PTHREAD_MUTEX_UNLOCK_AUTO_NP POSIX スケジューリングポリシーに基づく2つ(SCHED_FIFO,SCHED_RR)の場合 to-be-awakened のポリシーで選択してください。 もしスレッドが SCHED_OTHER で あるなら PARALLEL ポリシーを使ってください、さもなければ SERIAL ポリシーを使って ください。 pthread_mutex_setconsistency_np このサービスは整合性に所定の mutex の状態を割り当てます。 int pthread_mutex_setconsistency_np (pthread_mutex_t * mutex , int state) 状態は次の1つです: PTHREAD_MUTEX_ROBUST_CONSISTENT_NP 整合性がない mutex の矛盾を解決してください。 それが mutex を整合性がないとマ ークを付けられた問題を解決することが可能であった場合に限り、アプリケーションがこ れをするべきです。 PTHREAD_MUTEX_ROBUST_NOTRECOVERABLE_NP 整合性がない mutex に unrecoverable であるというマークを付けてください。 もしそ れが mutex を整合性がないとマークを付けられた問題を解決することが可能ではない なら、アプリケーションがこれをするべきです。 mutex は元来整合性がない状態にあるに違いありません、あるいはこのサービスはエラーを返し ます。 ただ mutex の所有者だけがその整合性状態を変えることができます。 5-36 SUSE Linux Enterprise Real Time Linux User’s Guide pthread_mutex_setunlock_np このサービスはこの mutex をアンロックしているポリシーを設定します。 概要 int pthread_mutex_setunlock_np (pthread_mutex_t * mutex ,int policy) ポリシーは PTHREAD_MUTEX_UNLOCK_SERIAL_NP 、 PTHREAD_MUTEX_UNLOCK_PARALLEL_NP、 PTHREAD_MUTEX_UNLOCK_AUTO_NP です。 定義の詳細は上記の「pthread_mutex_getunlock_np」に参照してください。 pthread_mutexattr_getfast_np attr 属性のセットで初期化された mutexes が速く、あるいは遅いモードで走っているかにか かわらず、この関数はリターンします。 概要 int pthread_mutexattr_getfast_np(const pthread_mutexattr_t *attr,int *mode). 答えは*mode で返されます。 PTHREAD_MUTEX_FASTPATH_NP attr で初期化された Mutexes は速いモード上で動作します。このモードでは、ロックし たりアンロックする操作はカーネルに入りません。 PTHREAD_MUTEX_SLOWPATH_NP attr で初期化された Mutexes が遅いモード上で動作します。 このモードでは、すべて の pthread_mutex_lock と pthread_mutex_unlock の操作はカーネルに入ります。 pthread_mutexattr_getprotocol これは mutexes のためのプロトコルが属性のこのセットで初期化したリターンに応じます。 概要 int pthread_mutexattr_getprotocol(pthread_mutexattr_t *attr, int *protocol) 利用可能なプロトコル: PTHREAD_PRIO_NONE スレッドのプライオリティをスケジュールすることは、この mutex の上にオペレーション に影響を与えません。 PTHREAD_PRIO_INHERIT スレッドのスケジューリングプライオリティはプライオリティインヘリタンスプロトコルの規 則に従って変えられます:スレッドが mutex の所有者である限り、それは直接、あるい 5-37 SUSE Linux Enterprise Real Time Linux User’s Guide は間接的に mutex を獲得するのを待っている最も高い優先度待ちのプライオリティを 継承するでしょう。 pthread_mutexattr_getrobust_np この関数はこの属性で初期化された mutexes のためにロバストなレベルを返します。 概要 int pthread_mutexattr_getrobust_np(const pthread_mutexattr_t *attr, int *robustness) 利用可能なレベル: PTHREAD_MUTEX_ROBUST_NP この属性オブジェクトで作られた Mutexes はロバストであるでしょう。 PTHREAD_MUTEX_STALLED_NP この属性オブジェクトで作られた Mutexes はロバストではないでしょう。 ロバストな mutex はその所有者がいつ死んで、そして整合性がない状態に移行するか検 出するものです。整合性がない状態の定義のために「pthread_mutex_consistent_np」を見 てください。 非ロバスト mutex はその所有者がいつ死ぬか検出しません、そしてそれで(すなわち、それ がシグナルによって中断させられる、あるいは何か他のスレッドが機能を失ったプロセスのた めに mutex をアンロックするまで)いつまでもロックされているままでいます。 pthread_mutexattr_getunlock_np このサービスは属性のこのセットで初期化された mutexes のためにアンロックしているポリシー を返します。 int pthread_mutexattr_getunlock_np(const phtread_mutexattr_t *attr, int *mode) 利用可能なポリシーは PTHREAD_MUTEX_UNLOCK_SERIAL_NP 、 PTHREAD_MUTEX – UNLOCK_PARALLEL_NP と PTHREAD_MUTEX_UNLOCK_AUTO_NP - です。 それらの定義のためにセクション「pthread_mutex_getunlock_np」を見てくださ い。 pthread_mutexattr_setfast_np このサービスは属性のこのセットで作られた mutexes のために操作上のモードを設定します。 概要 int pthread_mutexattr_setfast_np(pthread_mutexattr_t *attr, int mode) 5-38 SUSE Linux Enterprise Real Time Linux User’s Guide モードは PTHREAD_MUTEX_FASTPATH_NP あるいは PTHREAD_MUTEX_SLOWPATH_NP であるかもしれません。 それらの定義のためにセ クション「pthread_mutexattr_getfast_np」を見てください。 pthread_mutexattr_setprotocol このサービスは mutex 属性のこのセットから作られるどんな mutex のプロトコルでもセット します。 概要 int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol) プロトコルは PTHREAD_PRIO_NONE あるいは PTHREAD_PRIO_INHERIT であるか もしれません。 それらの定義はセクション「pthread_mutexattr_getprotocol」を見てくださ い。 pthread_mutexattr_setrobust_np このサービスはたくましいレベルをこの mutex 特質オブジェクトで作られる mutexes のた めに準備します。 概要 int pthread_mutexattr_setrobust_np(pthread_mutexattr_t *attr, int robustness). ロ バ ス ト ネ ス は PTHREAD_MUTEX_ROBUST_NP あ る い は PTHREAD_MUTEX_STALLED_NP であるかもしれません。 定義のは「pthread_mutexattr_getrobust_np」を見てください。 pthread_mutexattr_setunlock_np このサービスはこの mutex 属性オブジェクトで作られる mutexes のためにアンロックして いるモードを設定します。 int pthread_mutexattr_setunlock_np(pthread_mutexattr_t *attr, int mode) モードは PTHREAD_MUTEX_UNLOCK_SERIAL_NP 、 PTHREAD_MUTEX_UNLOCK – PARALLEL_NP 、あるいは PTHREAD_MUTEX_UNLOCK_AUTO_NP であるかもしれません。 それらの定義はセクション「pthread_mutex_getunlock_np」を見て ください。 5-39 SUSE Linux Enterprise Real Time Linux User’s Guide Alternative glibc 上述された追加の pthread mutex サービスは Alternative glibc を使うアプリケーションで 利用可能です。 一般に、これらの mutexes は POSIX 1003.1-2001 スタンダードを越え て拡張したロバストネスとプライオリティインヘリタンスの追加の機能をサポートします。 Alternative glibc は fusyn-2.3.1 と rtnptl-2.3 オープンソースのパッチに基づいています。 コンパイルして、そしてアプリケーションを ccur - gcc とリンクすることによって、利用できま す。 このライブラリの実験的な性質のために、アプリケーションがこのライブラリの pthreads 部 に対して静的にリンクすることを認められません。 特別なシステムアドミニストレーション考慮。 Alternative ライブラリは /lib/ccur/sbin/ldconfig に、最初から最後まで、同じアーギュメント で呼び出しがなされなくてはならないことを要求します。 例えば、もし管理者は次のことを実行するために必要とします: $ /sbin/ldconfig なら、 彼 / 彼女は同じく実行するべきです: $ /lib/ccur/sbin/ldconfig /usr/lib 5-40 SUSE Linux Enterprise Real Time Linux User’s Guide System V セマフォの使用 セマフォが使用される(動作される、または制御される)前に、ユニークに識別されたデータ構 造及びセマフォ・セット(配列)が生成されなければなりません。ユニークな識別子は、セマフ ォ・セット識別子(semid)と呼ばれ、特定のデータ構造及びセマフォ・セットを識別するまたは 参照するのに、それは使用されます。システム内のどのプロセスからもこの識別子はアクセ ス可で、通常アクセス制約に準じます。 セマフォ・セットは、配列内にディフォルト定義の構造数を含み、集まり内のそれぞれのセマフ ォにおいて 1 つの構造です。セマフォ・セット内の信号の数(nsems)は、ユーザが選択できま す。 semop (2)システムコールで使用される、sembuf 構造は、図 5-1 で示されています。 図 5-1 sembuf 構造の定義 struct sembuf { unsigned short int sem_num; /* semaphore number */ short int sem_op; /* semaphore operation */ short int sem_flg; /* operation flag */ }; sembuf 構造は、<sys/sem.h>ヘッダ・ファイル内で定義されています。 ある semctl (2)サービス呼び出し上で使用されている、struct semid_ds 構造は、図 5-2 で 示されています。 図 5-2 semid_ds 構造の定義 struct semid_ds { struct ipc_perm sem_perm; /* operation permission struct */ __time_t sem_otime; /* last semop() time */ unsigned long int __unused1; __time_t sem_ctime; /* last time changed by semctl() */ unsigned long int __unused2; unsigned long int sem_nsems; /* number of semaphores in set */ unsigned long int __unused3; unsigned long int __unused4; }; 5-41 SUSE Linux Enterprise Real Time Linux User’s Guide semid_ds データ構造は、<bits/sem.h>内に位置しますが、ユーザ・アプリケーションは <sys/sem.h>ヘッダ・ファイルを含み、それは内的に<bits/sem.h>ヘッダ・ファイルを含みま す。 この構造の sem_perm メンバは、ipc_perm タイプであることが注意されます。このデータ構 造は、全ての IPC 機能において同じで、それは<bits/ipc.h>ヘッダ・ファイル内に位置し、し かしユーザ・アプリケーションは<sys/ipc.h>ファイルを含み、それは内的に<bits/ipc.h>ヘッ ダ・ファイルを含みます。ipc_perm データ構造の詳細は、3 章の“System V メッセージ”という タイトルのセクション内で提供されています。 semget (2)システムコールは次の 2 つのタスクの 1 つを行います。 ・ 新しいセマフォ・セット識別子を生成し、そしてそれにおいて結合しているデータ構造 及びセマフォ・セットを生成します。 ・ 結合しているデータ構造及びセマフォ・セットを既に持つ既存のセマフォ・セット識別 子の位置を見つけます。 semget システムコールに渡される key 引数の値が、行われるタスクを決定します。既存の semid 及び IPC_CREAT フラッグの設定において、もし key が未だ使用されていなければ、 システム・チューニング可能パラメータが超過しないものとして、新しい semid は結合するデ ータ構造及びそのために生成されたセマフォ・セットと共に返されます。 プライベート・キー(IPC_PRIVATE)として知られる値ゼロ(0)の key を指定するための準備 もあります。このキーが指定される時、システム・チューニング可能パラメータが超過しない限 り、新しい識別子が常に結合するデータ構造及びそのために生成されたセマフォと共に返さ れます。ipcs (8)コマンドは全てがゼロとしての semid における key フィールドを示します。 セマフォ・セットが生成される時、semget を呼び出すプロセスは所有者/生成者になり、そし て結合するデータ構造が相応に初期化されます。所有者権を変更することはできますが、生 成プロセスは常に生成者にとどまることを覚えます(“semctl システムコール”のセクションを 見てください)。セマフォ・セットの生成者はさらに簡易性における初期オペレーション許可も 確定します。 もしも指定されているキーにおいてセマフォ・セット識別子が存在するなら、既存の識別子の 値が返されます。既存のセマフォ・セット識別子が返することを望まないのであれば、システム コールに渡される semflg 引数内で、制御コマンド(IPC_EXCL)を指定(設定)することができ ます。実際にセット内にある数よりも大きな数のセマフォ(nsems)において、それが値を渡す 5-42 SUSE Linux Enterprise Real Time Linux User’s Guide ならシステムコールは失敗します。もしセット内にいくつのセマフォがあるのかを知りたくなけ れば、nsems においては 0 を使用します(更なる情報については、“semget システムコール” を見てください)。 ユニークに識別されたセマフォ・セット及びデータ構造が生成される、または既存のものが見 つかれば、semop (2)及び semctl (2)を使用することができます。 セマフォ・オペレーションはゼロにおける増加、減少、そして評価から構成されます。semop システムコールはこれらのオペレーションを行うのに使用されます(semop システムコール の詳細については“semop システムコール”を見てください)。 semctl システムコールによって、以下の方法でセマフォ機能を制御することができます。 ・ セマフォの値を返します(GETVAL) ・ セマフォの値を設定します(SETVAL) ・ セ マ フ ォ ・ セ ッ ト上 の 最 後 の オ ペ レ ー シ ョ ン の 動 作 プロ セ ス の P I D を 返 し ま す (GETPID) ・ セマフォ値がその現在の値よりも大きくなることを待っているプロセス数を返します (GETNCNT) ・ セマフォ値がゼロに等しくなることを待っているプロセス数を返します(GETZCNT) ・ セット内の全てのセマフォ値を取得し、そしてユーザ・メモリ内の配列にそれらを配置 します(GETALL) ・ ユーザ・メモリ内の値の配列からセマフォ・セット内の全てのセマフォ値を設定します (SETALL) ・ セマフォ・セットと結合しているデータ構造を取得します(IPC_STAT) ・ セマフォ・セットにおけるオペレーション許可を変更します(IPC_SET) ・ その結合しているデータ構造及びセマフォ・セットと共にオペレーティング・システム から特定のセマフォ・セット識別子を取り除きます(IPC_RMID) semctl システムコールの詳細については“semctl システムコール”のセクションを見てくださ い。 semget システムコール semget (2)は新しいセマフォ・セットを生成するか、または既存するものを識別します。 5-43 SUSE Linux Enterprise Real Time Linux User’s Guide このセクションではどのように semget システムコールを使用するのかを説明します。さらに 詳細な情報については、semget (2) man page を見てください。この呼び出しの使用を説明 す る プ ロ グ ラ ム は 、 README.semget.txt 内 で 提 供 さ れ て い る 詳 細 な コ メ ン ト と 共 に /usr/share/doc/ccur/examples/semget.c の中にあります。 概要 #include <sys/types .h> #include <sys/ipc .h> #include <sys/sem .h> int semget (key_t key, int nsems, int semflg) ; #include ファイルの全ては SUSE Linux Enterprise Real Time オペレーティング・システムの サブディレクトリ/usr/include 内に位置します。 key_t は、ヘッダ・ファイル<bits/sys/types.h>内の typedef によって全体的タイプになるよう に定義されています(このヘッダ・ファイルは、<sys/types.h>によって内的にインクルードさ れています。成功した完了におけるこのシステムから返された整数は、セマフォ・セット識別 子です(semid)。semid はこの章の先の“System V 信号の使用”のセクション内で論じられ ています。 結合しているセマフォ・セット及びデータ構造と共の新しい semid は、もし以下の状態の 1 つ が真であれば生成されます。 ・ key は IPC_PRIVATE と等価である。 ・ key は 未 だ そ れ と 関 連 す る semid を 持 っ て お ら ず 、 そ し て ( semflg 及 び IPC_CREAT)が“真”(ゼロでない)です。 ・ semflg のの値は以下のものの組合せです。 ・ 制御コマンド(flgs) ・ オペレーション許可 制御コマンドはディフォルト定義の定数です。以下の制御コマンドは semget システムコール に適用され、そして<bits/ipc.h>ヘッダ・ファイル内で定義され、それは<sys/ipc.h>ヘッダ・フ ァイルによって、内的にインクルードされています。 IPC_CREAT 新しいセマフォ・セットを生成するのに使用されます。もし使用されなければ、 5-44 SUSE Linux Enterprise Real Time Linux User’s Guide semget は key と結合しているセマフォ・セットを見つけ、そしてアクセス許可を確証 します。 IPC_EXCL もし指定されている key においてセマフォ・セット識別子が既に存在するなら、シス テムコールにエラーを返させるように IPC_CREAT と共に使用されます。これは、プ ロセスがそうではないのに新しい(ユニークな)識別子を受信したと認識することを 防ぐために必用です。 オペレーション許可は、ユーザ、グループ、そして他におけるリード/変更属性を定義します。 表 5-1 は有効なオペレーション許可コードにおける数値(16 進数表記で表される)を示してい ます。 表 5-1 セマフォオペレーション許可コード Operation Permissions Octal Value Read by User 00400 Write by User 00200 Read by Group 00040 Write by Group 00020 Read by Others 00004 Write by Others 00002 特定の値は、望まれているオペレーション許可において、16 進数を追加するかビットごとに 論理 OR することによって得られます。つまり、もし“ユーザにリードされる”及び“他にリード /変更される”が望まれるなら、コード値は 00406(00400 プラス 00006)になります。 16 進オペレーション許可値と共にフラグ名を使用することによって、semflg 値は簡単に設定 することができます。例として: semid = semget (key, nsems, (IPC_CREAT | 0400)) ; semid = semget (key, nsems, (IPC_CREAT | IPC_EXCL | 0400)) ; 以下の値は<linux/sem .h>内で定義されています。これらの値を超過することは常に失敗 を引き起こします。 SEMMNI 5-45 SUSE Linux Enterprise Real Time Linux User’s Guide どの時間においても使用できるユニークなセマフォ・セット(semids)の最大値を確 定します。 SEMMSL それぞれの信号セット内のセマフォの最大数を確定します。 SEMMNS 全てのセマフォ・セット・システム・ワイドの中で振動の最大数を確定します。 以下のオプションを使用して ipcs (8)コマンドで、セマフォ制限値のリストを取得されます。更 なる詳細については、man page を見てください。 ipcs –l 特定のエラー状態と同様に特定の結合するデータ構造初期化について、semget (2) man page を参照してください。 semctl システムコール セマフォ・セット上の制御オペレーションを行うために semctl (2)は使用されます。 このセクションでは semctl システムコールについて説明します。更なる詳細な情報について は、semget (2) man page を見てください。この呼び出しの使用を説明するプログラムは、 README.semctl.txt 内 で 提 供 さ れ て い る 詳 細 な コ メ ン ト と 共 に /usr/share/doc/ccur/examples/semctl.c にあります。 概要 #include <sys/types .h> #include <sys/ipc .h> int semctl (int semid, int semnum, int cmd, int arg) ; union semun { int val ; struct semid_ds *buf ; ushort *array ; } arg: ; #include ファイルの全ては、SUSE Linux Enterprise Real Time オペレーティング・システム のサブディレクトリ/usr/include 内に位置します。 5-46 SUSE Linux Enterprise Real Time Linux User’s Guide semget 引数は、semget システムコールを使用して既に生成された、有効な、非マイナスの 整数値でなければなりません。 Semnum 引数はその番号によってセマフォを選択するのに使用されます。これは、セット上 のオペレーションのシーケンス(アトミックに行われた)に関係します。セマフォのセットが生成 される時、第 1 のセマフォは番号 0 で、そして最後のセマフォは、セット内のトータルより1少な く番号付けされます。 cmd 引数は、以下の値のどれか 1 つです。 GETVAL セマフォ・セット内で単一セマフォの値を返します。 SETVAL セマフォ・セット内で単一セマフォの値を設定します。 GETPID セマフォ・セット内のセマフォ上の最後のオペレーションを行ったプロセスの PID を 返します。 GETNCNT 特定のセマフォの値がその現在の値よりも大きくなるのを待っているプロセスの数 を返します。 GETZCNT 特定のセマフォの値がゼロに等価になるのを待っているプロセスの数を返します。 GETALL セマフォ・セット内の全てのセマフォにおける値を返します。 SETALL セマフォ・セット内の全てのセマフォ値を設定します。 IPC_STAT 指定されている semid において結合しているデータ構造内に含まれるステータス情 報を返し、そして arg.buf がポイントするデータ構造内にそれを置きます。 IPC_SET 指定されているセマフォ・セット(semid)における有効なユーザ/グループ識別を 設定します。 IPC_RMID その関連するデータ構造と共に指定されているセマフォ・セット(semid)を取り除き ます。 5-47 SUSE Linux Enterprise Real Time Linux User’s Guide 注 semctl (2)サービスはさらに IPC_INFO、SEM_STAT 及び SEM_INFO コマンドをサポート します。しかし、これらのコマンドは ipcs (8)ユーティリティによる使用向けのみなので、これら のコマンドについては論じられません。 IPC_SET または IPC_RMID 制御コマンドを動作させるためには、プロセスが以下の状態の 1 つまたはそれ以上の状態にならなければなりません。 ・ OWNER の有効的ユーザ ID を持っている ・ CREATOR の有効的ユーザ ID を持っている ・ スーパ・ユーザである ・ CAP_SYS_ADMIN ケーパビリティを持っている ipcrm (1)コマンドを使用して、そして-s semid または-S semkey オプションを使用しても、セ マフォ・セットを取り除くことができることに注意します(ここで、semid はセマフォ・セットにおけ る識別子を指定し、そして semkey はセマフォ・セットと結合しているキー指定しています)。こ のコマンドを使用するためには、IPC_RMID 制御コマンドを動作するのに要求されるのと同 様の機能をプロセスは持たなければなりません。このコマンド使用の追加的情報については ipcrm (1) man page を見てください。 残りの制御コマンドは、適切に、リードまたはライト許可を要求します。 制御コマンドが行われるために、適切なユニオン・メンバにシステムコールを渡すために、arg 引数は使用されます。いくつかの制御コマンドでは、arg 引数は要求されず、単に無視されま す。 ・ 要求される arg .val: SETVAL ・ 要求される arg. .buf: IPC_STAT_IPC_SET ・ 要求される arg .array: GETALL、SETALL ・ 無視される arg: GETVAL、 GETPID、 GETNCNT、 GETZCNT、 IPC_RMID semop システムコール semop (2)は、セマフォ・セットの選択されたメンバ上でオペレーションを行うのに使用されま す。 このセクションでは semop システムコールについて説明します。更に詳細な情報については、 semop (2) man page を見てください。この呼び出しの使用を説明するプログラムは、 5-48 SUSE Linux Enterprise Real Time Linux User’s Guide README.semop.txt 内 で 提 供 さ れ て い る 詳 細 な コ メ ン ト と 共 に /usr/share/doc/ccur/examples/semop.c にあります。 概要 #include <sys/types .h> #include <sys/ipc .h> #include <sys/sem .h> int semop (int semid, struct semfub *sops, unsigned nsops) ; #include ファイルの全ては、SUSE Linux Enterprise Real Time オペレーティング・システム のサブディレクトリ/usr/include 内に位置します。 semop システムコールは、整数値を返します。それは成功した完了ならゼロ、その他の場合 は-1 です。 semid 引数は、有効な、非マイナスの整数値でなければなりません。換言すれば、それは先 の semget (2)システムコールから既に返されていなければなりません。 sops 引数は、ユーザ・メモリ・エリア内の構造の配列をポイントし、それは、変更されるそれぞ れのセマフォにおいて以下のものを含みます。 ・ セマフォ数(sem_num) ・ 動作されるオペレーション(sem_op) ・ 制御フラッグ(sem_flg) *sops 宣言は配列名(それは配列の最初の要素のアドレス)、または配列へのポインタが使 用できることを意味します。sembuf は、配列内の構造メンバにおいてテンプレートとして使用 されるデータ構造のタグ名で、それは<sys/sem. h>ヘッダ・ファイル内に位置します。 nsops 引数は配列の長さ(配列内の構造の数)を指定します。この配列の最大サイズは、 SEMOPM システム・チューニング可能パラメータによって決定されます。よって、SEMOPM オペレーションの最大は、それぞれの semop システムコールにおいて動作されます。 セマフォ数(sem_num)は、それにオペレーションが動作されるセット内の特定の信号を確定 します。 5-49 SUSE Linux Enterprise Real Time Linux User’s Guide 動作されるオペレーションは、以下のものによって確定されます。 ・ もし sem_op が正なら、sem_op の値によってセマフォ値は増加されます。 ・ もし sem_op が負なら、sem_op の絶対値によってセマフォ値は減少されます。 ・ もし sem_op がゼロなら、セマフォ値がゼロに等しいか確認されます。 以下のオペレーション・コマンド(フラッグ)が使用されます。 IPC_NOWAIT 配列内のどのオペレーションにおいても設定されます。もし、それに IPC_NOWAIT が設定されているどのオペレーションの動作も成功しなけ れば、どのセマフォ値も全く変更することなくシステムコールの返りは不成 功になります。現在のその値よりもセマフォを減少しようとする時、または セマフォがそうではない時にゼロに等しいかを確認する時、システムコー ルは不成功になります。 SEM_UNDO プロセスが存在する時に、プロセスのセマフォが自動的に変化するのを システムにアンドゥ-するように指示し、それによりプロセスがデッドロック 問題を回避します。この機能を実行するために、システムはシステム内の それぞれのプロセスにおけるエントリと共にテーブルを維持します。それ ぞれのエントリはアンドゥ-構造のセットをポイントし、それぞれのセマフ ォはプロセスが使用するものです。システムはネット変更をレコードしま す。 状態同期化 以 下 の セ ク シ ョ ン で は 、 共 同 プ ロ セ ス を 操 作 す る の に 使 用 で き る 、 postwait (2) 及 び server_block/server_wake (2)システムコールについて説明します。 postwait システムコール postwait (2)関数は、プロセスの共同グループの間で使用される、速い、効率的な、スリープ /ウェーク・アップ/タイマー・メカニズムです。 スリープへ行くには、プロセスは pw_wait ( )を呼び出します。プロセスは以下の時に、ウェー ク・アップします。 ・ 5-50 タイマーが期限切れする SUSE Linux Enterprise Real Time Linux User’s Guide ・ 共同グループが pw_post ( )を呼び出す中で、他のプロセスがプロセスを置く ・ 呼び出しが割込みされる 概要 #include <sys/time .h> #include <sys/rescntl .h> #include <sys/pw .h> int pw_getukid (ukid_t *ukid) ; int pw_wait (struct timespec *t, struct resched_var *r) ; int pw_post (ukid_t ukid, struct resched_var *r) ; int pw_postv (int count, ukid_t targets [ ], int errors [ ], struct resched_var *r ) ; int pw_getvmax (void) ; gcc [options] file –lccur_rt ... postwait (2)を使用しているプロセスはそれらの ukid によって識別されます。その ukid を取 得するためにプロセスは pw_getukid ( )を呼び出します。ukid は pid へマップします。そして この値は、このプロセスへ送るかもしれない他の共同プロセスと共に共有されます。 もしも送られれば pw_wait ( )は 1 の値を返し、もしもタイム・アウトすれば 0 を返します。 pw_wait ( )は時間切れ及び再スケジューリング値と共に呼び出されます。もしも呼び出し元 が再スケジューリング値を指定すれば(つまり、値はヌルではない)そのロック・カウントは減 少されます。 もしも時間切れ値がヌルなら、プロセスは時間切れしません。もしもタイム・アウト値が 0 でも し送られれば pw_wait ( )は即 1 で返り、またはその他の全ての場合は、EAGAIN を返しま す。 もしも時間切れ値において指定されている時間が 0 よりも大きければ、それがタイム・アウト する前にそれが送られなければ、その時間の量の間、プロセスはスリープします。もしもプロ セスが送られるかまたは割込みされるなら、残りの時間量を反映するようにタイム・アウト値 はアップデートされます。 pw_wait 前に 1 つまたはそれ以上の pw_post または pw_postv オペレーションが起こっ たなら、pw_wait 呼び出しは、呼び出しプロセスをブロックしません。もしも指定されている時 間がタイム・アウトにおいてゼロよりも大きければ、続く pw_wait は pw_post または pw_postv 呼び出しに干渉せず、ブロックします。 5-51 SUSE Linux Enterprise Real Time Linux User’s Guide pw_postv ( )は一度に複数プロセスを送るのに使用されます。target 内で指定されている全 てのプロセスをそれは送ろうとします。pw_postv ( )が送るターゲットのデフォルト(最大)値 は 64 です。それぞれのターゲットにおけるエラーは、errors 配列内で返されます。全てが成 功すれば、pw_postv ( )は 0 を返し、もし何らかのエラーがあれば、エラーを引き起こした最 後のターゲットのエラー値を返します。 もしも呼び出し元が再スケジューリング変数を指定するなら(つまり、最スケジューリング変数 がヌルではない)、そのロック・カウントは減少されます。 pw_getmax ( )は、1 つの pw_postv ( )呼び出しで送ることができるターゲットの最大数を返 します。 起こり得るエラーの種類のリストについては、postwait (2) man page を参照してください。 サーバ・システムコール システムコールのこのセットによって、PowerMAX オペレーティング・システムと互換性のあ るインターフェイスを使用して、プロセスがサーバとして動作するように操作することができま す。これらのシステムコールは以下のように手短に説明することができます。 server_block は、server_block からの最後の返しから何もウェイクアップ要求が起こらな い時のみ、呼び出しプロセスをブロックします。もしもウェーク・アップが起こったなら、 server_block は即返ります。 server_wake1 は、もしもそれが server_block システムコール内でブロックされていれば、 サーバをウェークします。もしもこの呼び出し内で指定されているサーバがブロックされてい なければ、ウェーク・アップ要求は server_block へのサーバの次の呼び出しへ適用されま す。 server_wakevec は、server_wake1 と同様の目的をサーブします。例外は、1 つのプロセ スよりもプロセスのベクトルが指定することです。 注意 これらのシステムコールは、単一スレッド・プロセスによってのみ使用されるべきです。マルチ プレックス・スレッドのグローバル・プロセスは、その上にスレッドが現在スケジュールされてい るプロセスによって変化します。よって、これらのインターフェイスがマルチプレックス・スレッド によって使用される時、間違ったスレッドがウェークされる、またはブロックされる可能性があ 5-52 SUSE Linux Enterprise Real Time Linux User’s Guide ります。 server_block server_block は、server_block からの最後の返しから何もウェーク・アップ要求が起こらな い時のみ、呼び出しプロセスをブロックします。 概要 #include <sys/types .h> #include <sys/time .h> #include <sys/pw .h> int server_block (options, r, timeout) int options ; struct resched_var *r ; struct timeval *timeout ; gcc [options] file –lccur_rt .. 引数は以下のように定義されます。 Options この引数の値はゼロでなければならない r 呼び出しプロセスの再スケジューリング変数へのポインタ。この引数はオプシ ョン的で、その値はヌルでもあり得ます。 timeout 呼び出しプロセスがブロックされる時間の最大長を含む timeval 構造へのポイ ンタ。この引数はオプション的で、その値はヌルでもあり得ます。もしその値が ヌルであるなら、タイム・アウトはありません。 もしも呼び出しプロセスが中断しているウェーク・アップ要求を持つなら、server_block シス テムコールはすぐに返り、その他では、呼び出しプロセスが次のウェーク・アップ要求を受け た時にそれは返ります。0 の返りは、呼び出しが成功だったことを示します。-1 の返りはエラ ーが発生したことを示します。errno はエラーを示すように設定されています。返りにおいて、 それのブロックを引き起こした状態を、呼び出しプロセスが再確認することに注意します。プ ロセスが時期尚早にシグナルによって呼び起こされたために状態が変化したという保証はあ りません。 5-53 SUSE Linux Enterprise Real Time Linux User’s Guide server_wake1 server_wake1 は、server_block 呼び出し内でブロックされていたサーバをウェークするた めに起動されます。 概要 #include <sys/types .h> #include <sys/time .h> #include <sys/pw .h> int server_wake1 (server, r) global_lwpid_t server ; struct resched_var *r ; gcc [options] file –lccur_rt .. 引数は以下のように定義されます。 server 起こされるサーバ・プロセスのグローバル・プロセス ID r 呼び出しプロセスの再スケジューリング変数へのポインタ。この引数はオプション的 で、その値はヌルであり得ます。 server_wake1 呼び出しを使用するには、呼び出しプロセスの本当のまたは有効な ID が、 server が指定しているプロセスの本当のまたは(exec から)保存されているユーザ ID に一 致しなければならないことに注意することが重要です。 もしもそれが server_block 呼び出し内でブロックされているなら、server_wake1 は指定さ れているサーバをウェークします。もしサーバがこの呼び出し内でブロックされていなければ、 server_block へのサーバの次の呼び出しのために、ウェーク・アップ要求は保持されます。 server_wake1 はさらに r が指定する再スケジューリング変数と結合する再スケジューリン グ・ロックの数を減少します。 0 の返りは呼び出しが成功したことを示します。-1 の返りはエラーが発生したことを示します。 errno はエラーを示すように設定されています。 5-54 SUSE Linux Enterprise Real Time Linux User’s Guide server_wakevec server_wakevec システムコールは server_block 呼び出し内でブロックされているサーバ の集まりをウェークするために起動されます。 概要 #include <sys/types .h> #include <sys/time .h> #include <sys/pw .h> int server_wakevec (server, nservers, r) global_lwpid_t *servers ; int nservers ; struct resched_var *r ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 servers 起こされるサーバ・プロセスのグローバル・プロセス ID の配列へのポイン タ。 nservers 配列内の要素の数を指定する整数値。 r 呼び出しプロセスの再スケジューリング変数へのポインタ。この引数はオ プション的で、その値はヌルであり得ます。 server_wakevec 呼び出しを使用するには、呼び出しプロセスの本当のまたは有効な ID が、 server が指定しているプロセスの本当のまたは(exec から)保存されているユーザ ID に一 致しなければならないことに注意することが重要です。 もしもそれらが server_block 呼び出し内でブロックされているなら、server_wakevec は指 定されているサーバをウェークします。もしもサーバがこの呼び出し内でブロックされていな ければ、server_block へのサーバの次の呼び出しのために、ウェーク・アップ要求は保持さ れます。 server_wakevec はさらに r が指定する再スケジューリング変数と結合する再スケジューリン グ・ロックの数を減少します。 5-55 SUSE Linux Enterprise Real Time Linux User’s Guide 0 の返りは呼び出しが成功したことを示します。-1 の返りはエラーが起こったことを示します。 errno はエラーを示すように設定されています。 これらの呼び出しの使用に関する追加的情報については、server_block (2) man page を 参照してください。 5-56 SUSE Linux Enterprise Real Time Linux User’s Guide コンディション同期化ツールの適用 共有メモリ領域内のメールボックスの使用を通して、生産者と消費者のプロセスのデータの やり取りを許可する関数を設計するのに、再スケジューリング変数、スピン・ロック、そしてサ ーバ・システムコールを使用することができます。消費者がメールボックスが空であるのを見 つければ、新しいデータが到着するまでそれはブロックします。生産者がメールボックスに新 しいデータを置けば、それは待っている消費者をウェークします。消費者がそれを処理できる 以上の速さで生産者がデータを生成する時に、類似の状況が生まれます。生産者がメール ボックスが満杯であることを見つければ、データが取り除かれるまでそれはブロックします。 消費者がデータを取り除いた後に、それは待っている生産者をウェークします。 メールボックスは以下のように表されます。 struct mailbox { struct spin_mutex mx ; /* serializes access to mailbox */ queque_of consumers : /* waiting consumers */ queue_of deta ; /* the data, type varies */ }; mx フィールドはメールボックスへのアクセスを順にするのに使用されます。data フィールドは 生産者から消費者へと渡される情報を表しています。full フィールドは、メールボックスが満杯 なのか空であるのかを示すのに使用されます。producer フィールドはメールボックスが空に なるのを待っているプロセスを識別します。consumer フィールドはデータの到着を待ってい るプロセスを識別します。 spin_acquire 及び spin_release 関数を使用して、消費者がメールボックスからデータを抽 出するのを許可する関数は以下のように定義されます。 void consume (box, data) struct mailbox *box; any_t *data; { spin_acquire (&box–>mx, &rv); while (box–>data == empty) { enqueue (box–>consumers, rv.rv_glwpid); spin_unlock (&box–>mx); server_block (0, &rv, 0); spin_acquire (&box–>mx, &rv); } *data = dequeue (box–>data; spin_release (&box–>mx, &rv); 5-57 SUSE Linux Enterprise Real Time Linux User’s Guide } この関数では、データのチェックと取り除きの前に消費者プロセスがメールボックスををロック していることに注意します。もしもそれがメールボックスが空であることを見つければ、それは メールボックスをアンロックして生産者にデータを置くことを許可し、そしてそれは server_block を呼び出してデータの到着を待ちます。消費者が起こされる時、それは再びメ ールボックスをロックしてそしてデータをチェックします。メールボックスがデータを含んでいる ことの保証はありません。消費者はシグナルによって時期尚早に起こすることがあります。 メールボックス内に生産者がデータを置くことを許可する、似ている関数は以下のように定義 されます。 void produce (box, data) struct mailbox *box; any_t data; { spin_acquire (&box–>mx, &rv); enqueue (box–>data, data); if (box–>consumer == empty) spin_release (&box–>mx, &rv); else { global_lwpid_t id = dequeue (box–>consumers); spin_unlock (&box->mx); server_wake1 (id, &rv); } } この関数では、新しいデータを置く前に生産者プロセスがメールボックスが空になるのを待ち ます。消費者が待っている時のみ、生産者はデータの到着を通知ます。メールボックスをアン ロックした後にそれはそのようにすることに注意します。起こされた消費者がそれをロックして データをチェックしそして取り除くことができるように、生産者は最初にメールボックスをアンロ ックしなければなりません。server_wake1 への呼び出し前にメールボックスをアンロックす ることは、mutex が短時間保持することをも確実にします。不必要なコンテキスト・スイッチン グを防ぐために、消費者が起こされるまで再スケジューリングは禁止されます。 5-58 SUSE Linux Enterprise Real Time Linux User’s Guide 6 プログラム可能なクロック及びタイマー この章では、タイミングに使用できるいくつかの機能の概要を提供します。POSIX クロック及 びタイマー・インターフェイスは IEEE 標準 1003.1b-1993 に基づいています。クロック・インタ ーフェイスは高精度クロックを提供し、それは、時間承認またはコード・セグメントの長さの計 測のような目的に使用することができます。タイマー・インターフェイスはシグナルの受信方法 または後の時間における非同期のウェーク・アップのプロセスを提供します。さらに、高精度 システムコールが提供されており、それはとても短いタイム・クワンタムのスリープにプロセス を置くこと、そしてスリープ期間の計測にどのクロックが使用されるべきかを指定するのに使 用されます。RCIM PCI カードが追加的クロック及びタイマーを提供しています。 クロック及びタイマーの理解 アプリケーションまたはシステム・イベントをスケジュールするために、厳格なタイミング制約 内でリアルタイム・アプリケーションはデータを動作することができなければなりません。高精 度クロック及びタイマーによって、アプリケーションは高精度クロックに基づく相対的または絶 対的時間を使用することができ、そして 1 回または周期的ベース上のイベントをスケジュール することができます。それぞれのプロセスにおいて、アプリケーションは複数のタイマーを生 成することができます。 いくつかのタイミング機能が iHawk システム上で利用できます。これらは、リアルタイム・クロ ックと割込みモジュール(RCIM)PCI カードが提供する非割込みクロックとリアルタイム・クロ ック・タイマーと同様に、SUSE Linux Enterprise Real Time 下の POSIX クロックとタイマーを 含みます。これらのクロックとタイマーとそれらのインターフェイスは後に続くセクション内で説 明されます。 システム・クロック及びタイマーに関する情報については 7 章を見てください. RCIM クロック及びタイマー リアルタイム・クロック及び割込みモジュール(RCIM)は 2 つの非割込みクロックを提供します。 RCIM が共につなげられる時に、これらのクロックは他の RCIM と同期化することができます。 RCIM クロックは以下のものです。 プライマリ(tick)クロック 共通の 400ns クロック・シグナルのそれぞれのチック上のものによって増加される、 6-1 SUSE Linux Enterprise Real Time Linux User’s Guide 64 ビット非割込みクロック。このクロックはゼロに再設定し、そして RCIM チェーンに わたって同期化することができ、共通の時間認可を提供します。 デバイス・ファイル/dev/rcim/sclk がプログラムのアドレス空間の中へマップされる 時に、直接リードを使用して、第 1 クロックはどのシステム上でも、マスターまたはス レーブに関わりなくリードすることができます。 セカンダリ(POSIX)クロック POSIX 1003.1 フォーマット内でエンコードされている 64 ビット非割込みカウンタ。 上位の 32 ビットは秒を含み、下位の 32 ビットはナノ秒を含みます。共通 400ns ク ロック・シグナルのそれぞれによって、このクロックは増加されます。主に、高精度ロ ーカル・クロックとして使用されます。 同じユーティリティとデバイス・ファイルが使用されているという点において、セカン ダリクロックはプライマリクロックに似た方法でアクセスされます。どの望みの時間 でもセカンダリクロックをロードすることができますが、ロードされた値は RCIM チェ ーン内の他のクロックと同期化されません。ホストにくっ付けられている RCIM のセ カンダリクロックのみがアップデートされます。 RCIM はさらに 4 つのリアルタイム・クロック(RTC)・タイマーを提供します。特別デバイス・フ ァイルを使用して、これらのカウンタのそれぞれはアクセスすることができ、そしてそれぞれは、 ほとんどどのタイミング/周期/制御機能において使用することができます。いくつかの異な る精度へプログラムすることができ、それらはクロック・カウント値と組み合わされる時、様々 なタイミング間隔を提供します。これにより、ある周期(例: 100Hz)でプロセスを走らせるこ とにおいて、またはタイミング・コード・セグメントにおいて、それらは理想的になります。ホス ト・システム上に割り込みを生成することができるのに加えて、RTC の出力は、それらの対応 するホスト・システムへのデリバリにおいて他の RCIM ボードへ分配することができる、または RCIM 外部出力割込みラインの1つにくっ付けられている外部装備へデリバーすることができ ます。RTC タイマーは open (2)、close (2)、そして ioctl (2)システムコールによって制御され ています。 RCIM ク ロ ッ ク 及 び タ イ マ ー に 関 す る 完 全 な 情 報 に つ い て は 、 Real-Time Clock and Interrupt Module (RCIM) PCI Forum Factor User’s Guide を参照してください。 POSIX クロック及びタイマー 時間の計測及び表示において、POSIX クロックは高精度メカニズムを提供します。以下のシ 6-2 SUSE Linux Enterprise Real Time Linux User’s Guide ステム・ワイド POSIX クロックが利用可能です。 CLOCK_REALTIME ファイル<time .h>内で定義されているシステムの実時間クロック CLOCK_REALTIME_HR ファイル・システム生成及び修正、レコードのアカウンティング及び査定、 そして IPC メッセージキュー及びセマフォにおいて使用される時間をこ のクロックは供給します。両方のクロックが 1 マイクロ秒精度を持ち、同 じ特性を共有し、そして同時に動作できるという事実から、 CLOCK_REALTIME_HR は廃物になります。この章で説明されてい る POSIX クロック・ルーチンに加えて、以下のコマンド及びシステムコ ールはこのクロックをリードし設定します。 date (1)、gettimeofday (2)、settimeofday (2)、stime (2)、time (1)、そして adjtimex (2)。 CLOCK_MONOTONIC CLOCK_MONOTONIC_HR システムがブートされてから、時間を秒及びナノ秒で計測するシステ ム・アップタイム・クロック。CLOCK_MONOTONIC を設定することはで きません。両方のクロックが 1 マイクロ秒精度を持ち、同じ特性を共有 し 、 そ し て 同 時 に 動 作 で き る と い う 事 実 か ら 、 CLOCK_REALTIME_HR は廃物になります。 2 つのタイプのタイマーがあります。1 回だけのものと周期的なものです。それらは初期期限 切れ時間及び繰返し間隔によって定義されます。初期期限切れ時間は何時タイマーが最初 に期限切れするのかを示します。それは絶対的なものか(例として、8:30 a.m.)、または現在 の時間に相対的なものです(例として、30 秒後)。繰返し間隔は、タイマーの 1 つの期限切れ と次のものとの間に経過する時間量を示します。タイミングに使用されるクロックは、タイマー が生成される時に指定されます。 1 回タイマーは絶対的または相対的初期期限切れ時間及びゼロの繰返し間隔で準備してい ます。それは初期期限切れ時間で 1 度だけ期限切れして、そして開放されます。 周期的タイマーは絶対的または相対的初期期限切れ時間及びゼロよりも大きい繰返し間隔 で準備しています。最後のタイマー期限切れの時点において繰返し間隔は常に相対的です。 初期の期限切れ時間が起こる時、タイマーは繰返し間隔の値で再ロードされ、そしてカウント を続けます。タイマーはその初期期限切れ時間をゼロに設定することによって開放されま す。 6-3 SUSE Linux Enterprise Real Time Linux User’s Guide スケジューリング POSIX タイマーの期限切れにおいて、ローカル・タイマーは割込みソースと して使用されます。ローカル・タイマーに関する情報については 7 章を見てください。 注 /usr/lib/libccur_rt.a 内に位置する POSIX システムコールと関連するセットにより、高精度ク ロックとタイマーへのアクセスが提供されています。タイマー機能のいくつかも、標準 gnu libc librt ライブラリにより低精度として提供されています. POSIX 時間構造の理解 クロックとタイマーに関連する POSIX ルーチンは時間仕様において 2 つの構造を使用しま す: timespec 構造と itimerspec 構造です。これらの構造はファイル<time .h>内で定義され ています。 timespec 構造は、秒とナノ秒で単一時間値を指定します。クロックの時間を設定する、また はクロックの時間または精度を取得するためにルーチンを起動する時に、timespec 構造へ ポインタを供給します(これらのルーチンに関する情報については、“POSIX クロック・ルーチ ンの使用”を見てください)。その構造は以下のように定義されます。 struct timespec { time_t tv_sec ; long tv_nsec ; }; 構造の中のフィールドは以下のように説明されます。 tv_sec 時間値内の秒の数を指定します。 tv_nsec 時間値内の追加的ナノ秒の数を指定します。このフィールドの値はゼロから 999,999,999 までの領域になければなりません。 itimerspec 構造は、タイマーにおける初期期限切れ時間及び繰返し間隔を指定します。その 時間にタイマーが期限切れする時間を設定する、またはタイマーの期限切れ時間について の情報と取得するためにルーチンを起動する時に、itimerspec 構造へポインタを供給します (これらのルーチンに関する情報については、“POSIX タイマー・ルーチンの使用”を見てくだ さい)。その構造は以下のように定義されます。 struct itimerspec { struct timespec it_interval ; struct timespec it_value ; }; 6-4 SUSE Linux Enterprise Real Time Linux User’s Guide 構造の中のフィールドは以下のように説明されます。 it_interval タイマーの繰返し間隔を指定します。 it_value タイマーの初期期限切れを指定します。 POSIX クロック・ルーチンの使用 クロックに関連する様々な機能を動作することを可能にする POSIX ルーチンは以下のように 手短に説明されます。 clock_settime 指定されているクロックの時間を設定する。 clock_gettime 指定されているクロックから時間を取得する。 clock_getres 指定されているクロックのナノ秒の精度を取得する。 これらのルーチンのそれぞれの使用についての手順は、後に続くセクション内で説明されま す。 clock_settime ルーチンの使用 clock_settime(2) シ ス テ ム コ ー ル に よ っ て 、 シ ス テ ム 現 時 間 ク ロ ッ ク の 時 間 、 CLOCK_REALTIME を 設 定 す る こ と が で き ま す 。 呼 び 出 し プ ロ セ ス に は ル ー ト CAP_SYS_NICE ケ ー パ ビ リ テ ィ が な け れ ば な り ま せ ん 。 定 義 に よ っ て 、 CLOCK_MONOTONIC クロックは設定することができません。 システムの起動後に CLOCK_REALTIME を設定するなら、以下の時間が正確でないことが 注意されるべきです。 ・ ファイル・システム生成及び修正時間 ・ レコードのアカウンティング及び査定の時間 ・ カーネル・タイマーキューエントリにおける期限切れ時間 システム・クロックの設定は、キューイングされているされている POSIX タイマーへ影響を与 えません。 概要 6-5 SUSE Linux Enterprise Real Time Linux User’s Guide #include <time .h> int clock_settime (clockid_t which_clock, conct struct timespec *setting) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 which_clock それのために時間が設定されるクロックにおける識別子。 CLOCK_REALTIME のみが設定することができる。 setting それに which_clock が設定されている時間を指定する構造へのポインタ。 which_clock が CLOCK_REALTIME であれば、現時間クロックは新しい値へ 設定されます。クロック精度の整数複数ではない時間値は短縮されます。 0 の返り値は指定されているクロックの設定が成功したことを示します。-1 の返り値はエラー が発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラー の種類のリストについては clock_settime (2) man page を参照してください。 clock_gettime ルーチンの使用 clock_gettime (2)システムコールによって、指定されているクロックから時間を取得すること ができます。この呼び出しはクロックにとって最良の利用可能な精度を常に返します。通常、 マイクロ秒よりも良いです。 概要 #include <time .h> int clock_gettime (clockid_t which_clock, struct timespec *setting) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 which_clock それから時間を取得するクロックにおける識別子。which_clock の値は、 CLOCK_REALTIME または CLOCK_MONOTONIC です。 setting 6-6 SUSE Linux Enterprise Real Time Linux User’s Guide which_clock の時間が返される構造へのポインタ。 0 の返り値は clock_gettime への呼び出しが成功したことを示します。-1 の返り値はエラー が発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラー の種類のリストについては clock_gettime (2) man page を参照してください。 clock_getres ルーチンの使用 clock_getres (2)システムコールによって、指定されているクロックのナノ秒での精度を得る ことができます。clock_settime (2)で設定されているタイミングの期限切れの整った正確性、 及び clock_nanosleep (2)が使用する精密性、及び同じクロックを使用しての nanosleep (2)呼び出しを、この精度は確定します。 クロック精度はシステムに依存しており、ユーザが設定できません。 概要 #include <time .h> int clock_getres (clockid_t which_clock, struct timespec *resolution) ; gcc [options] file -lccur_rt. ... 引数は以下のように定義されます。 which_clock それについて精度の取得が望まれるクロックにおける識別子。which_clock は CLOCK_REALTIME または CLOCK_MONOTONIC です。 resolution which_clock の精度が返される構造へのポインタ。 0 の返り値は clock_getres への呼び出しが成功したことを示します。-1 の返り値はエラーが 発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラーの 種類のリストについては clock_getres (2) man page を参照してください。 POSIX タイマー・ルーチンの使用 プロセスはタイマーを生成し、取り除き、設定し、そして問合せすることができ、そしてタイマー 6-7 SUSE Linux Enterprise Real Time Linux User’s Guide が期限切れする時には通知を受けます。 タイマーと関連する様々な機能を動作することを可能にする POSIX システムコールは、手短 に以下のように説明されます。 timer_create 指定されているクロックを使用してタイマーを生成します。 timer_delete 指定されているタイマーを取り除きます。 timer_settime 期限切れ時間を設定することによって、指定されているタイマーを取り付ける か、取り離します。 timer_gettime 指定されているタイマーにおける繰返し間隔とタイマーが期限切れするまでの 残り時間を取得します。 timer_getoverrun 指定されている周期的タイマーにおいてオーバーランを取得します。 nanosleep 指定されている時間において実行を一時停止します。 clock_nanosleep 指定されているクロックに基づいたより高精度の一時停止を提供します。 これらのシステムコールのそれぞれの使用の手順は、後に続くセクション内で説明されます。 timer_create ルーチンの使用 timer_create (2)システムコールにより、指定されているクロックをタイミング・ソースとして使 用することで呼び出しプロセスはタイマーを生成することができます。 生成される時は、タイマーは取り離されています。プロセスが timer_settime (2)システムコ ールを起動する時に、それは取り付けられます(このシステムコールの説明として “timer_settime ルーチンの使用”を見てください)。 以下のことに注意することは重要です。 ・ プロセスが fork システムコールを起動する時、それが生成したタイマーは子プロセスによ って継承されません。 6-8 SUSE Linux Enterprise Real Time Linux User’s Guide ・ プロセスが exec システムコールを起動する時、それが生成したタイマーは取り離されそし て削除されます。 同 じ ス レ ッ ド ・ グ ル ー プ 内 の Linux ス レ ッ ド は タ イ マ ー を 共 有 す る こ と が で き ま す 。 timer_create を呼び出すスレッドはシグナルの全てを受けるが、同じスレッド・グループ内の 他のスレッドは timer_settime (2)への呼び出しを通してタイマーを操作することができま す。 概要 #include <time .h> #include <signal .h> int timer_create (clockid_t which_clock, struct sigevent *timer_event_spec, timer_t created_timer_id) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 which_clock タイマーにおいて使用されるクロックにおける識別子。which_clock の値は CLOCK_REALTIME でなければなりません。 timer_event_spec ヌル・ポインタ定数または構造へのポインタであり、呼び出しプロセスが非同期 にタイマーの期限切れを知らされる方法を指定します。 NULL SIGALRM タイマーが期限切れする時にプロセスへ送られます。 sigev_notify=SIGEV_SIGNAL タイマーが期限切れする時に、sigev_signo が指定するシ グナルはプロセスへ送られます。 sigev_notify=SIGEV_THREAD タイマーが期限切れする時に、指定されている sigev_notigy 機能は新しいスレッド内で sigev_value と 共に引数として呼び出されます。 6-9 SUSE Linux Enterprise Real Time Linux User’s Guide sigev_notify=SIGEV_THREAD_ID タイマーが期限切れする時に、シグナル sigev_signo を 受 け る ス レ ッ ド の pthread_t id を 、 sigev_notify_thread_id ナンバーは含むべきです。 sigev_notify=SIGEV_NONE タイマーが期限切れする時に、通知はデリバーされな い。 注 タイマーの期限切れを示すシグナルは、それがシグナル扱いシステムコールを指定して いなければ、プロセスの終了を引き起こします。特定のシグナルへのデフォルトのアクシ ョンを確定するには、signal (2) man page を参照してください。 created_timer_id タイマーID が記憶される位置へのポインタ。この識別子は他の POSIX タイマ ー・システムコールによって要求され、そして timer_delete (2)システムコール がタイマーを削除するまで、呼び出しプロセス内でユニークです。 0 の返り値は timer_create への呼び出しが成功したことを示します。-1 の返り値はエラーが 発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラーの 種類のリストについては timer_create (2) man page を参照してください。 timer_delete ルーチンの使用 timer_delete (2)システムコールによって、呼び出しプロセスは指定されているタイマーを取 り除くことができます。もしも選択されているタイマーが既に開始しているなら、それは禁止さ れ、そしてタイマーに割当てられているどのシグナルまたはアクションもデリバーまたは実行 されません。しかし、期限切れしているタイマーからの中断しているシグナルは取り除かれま せん。 概要 #include <time .h> int timer_delete (timer_t timer_id) ; 6-10 SUSE Linux Enterprise Real Time Linux User’s Guide gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 timer_id 取り除かれるタイマーにおける識別子。この識別子は、以前の timer_create (2)への呼び出しから来ています(このシステムコールの説明については、 “timer_create ルーチンの使用”を見てください)。 0 の返り値は指定されているタイマーの取り除きが成功したことを示します。-1 の返り値はエ ラーが発生したことを示します。errno はエラーを示すように設定されています。起こり得るエ ラーの種類のリストについては timer_delete (2) man page を参照してください。 timer_settime ルーチンの使用 timer_settime (2)システムコールにより、その時にそれが期限切れになる時間を設定する ことによって、呼び出しプロセスが指定されているタイマーを取り付けることができます。期限 切れになる時間は絶対的または相対的に定義されます。呼び出しプロセスはこのシステムコ ールを使用して取り付けられているタイマーから取り外されているタイマーへとすることがで き、またはタイマーの次の期限切れまでタイマーを再設定することができます。 概要 #include <time .h> int timer_settime (timer_t timer_id, int flags, const struct itimerspec *new_setting, const struct itimerspec *old_setting) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 timer_id タイマーが設定される識別子です。この識別子は、以前の timer_create (2) への呼び出しから来ています(このシステムコールの説明については “timer_create ルーチンの使用”を見てください)。 flags 以下の内の 1 つを指定する整数値。 6-11 SUSE Linux Enterprise Real Time Linux User’s Guide TIMER_ABSTIME 選択されているタイマーに絶対的期限切れが取り付けら れるようにします。タイマーと結合しているクロックが it_value が指定する値に達する時にタイマーは期限切 れします。もしもこの時間が既に過ぎているなら、 timer_settime は成功し、そしてタイマー期限切れ通知 が生成されます。 0 選択されているタイマーに相対的期限切れが取り付けら れるようにします。タイマーと結合しているクロックが it_value が指定する値に達する時にタイマーは期限切 れします。 new_setting 繰返し間隔及びタイマーの初期期限切れ時間を含む構造へのポインタ。 1 回だけのタイマーを望まれるなら、ゼロの繰返し間隔(it_interval)を指定しま す。この場合、初期期限切れ時間が起こる時に 1 度だけタイマーは期限切れ し、そして取り離されます。 周期的タイマーを望まれるなら、繰返し間隔(it_interval)をゼロに不等にしま す。この場合、初期期限切れ時間が起こる時、繰返し間隔の値でタイマーは 再ロードされ、そしてカウントを続けます。 いずれの場合も、初期期限切れ時間を絶対的な(例として、3:00 p.m.)、また は現在の時間に対して相対的な(例として、30 秒後)値に設定します。初期期 限切れ時間を絶対時間に設定するには、flags 引数内で TIMER_ABSTIME ビットを設定しなければなりません。以前のタイマー期限切れのために既に中 断しているどのシグナルも、指定されているタイマーにおいてプロセスにデリバ ーされます。 old_setting ヌル・ポインタ定数または構造へのポインタで、それに対してタイマーの以前の 繰返し間隔及び初期期限切れ時間が返されます。もしもタイマーが取り離され ているなら、初期期限切れ時間の値はゼロです。old_setting のメンバはタイマ ーの精度に依拠しており、そしてその時点で timer_gettime (2)呼び出しで返 6-12 SUSE Linux Enterprise Real Time Linux User’s Guide されるものと同値です。 0 の返り値は指定されているタイマーの設定が成功したことを示します。-1 の返り値はエラー が発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラー の種類のリストについては timer_settime (2) man page を参照してください。 timer_gettime ルーチンの使用 timer_gettime (2)システムコールによって、呼び出しプロセスは指定されているタイマーに おける繰返し間隔、及びタイマーが期限切れするまでの残りの時間量を得ることができま す。 概要 #include <time .h> int timer_gettime (timer_t timer_id, struct itimerspec *setting) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 timer_id それの繰返し間隔及び残り時間が要求されるタイマーにおける識別子で す。この識別子は、以前の timer_create (2)への呼び出しから来ていま す(このシステムコールの説明については“timer_create ルーチン”を見 てください)。 setting それに繰返し間隔及びタイマー上の残り時間量が返される構造へのポイ ンタです。残り時間量は現在の時間に相対的です。もしタイマーが取り外 されれば、値はゼロです。 0 の返り値は timer_gettime への呼び出しが成功したことを示します。-1 の返り値はエラー が発生したことを示します。errno はエラーを示すように設定されています。起こり得るエラー の種類のリストについては timer_gettime (2) man page を参照してください。 6-13 SUSE Linux Enterprise Real Time Linux User’s Guide timer_getoverrun ルーチンの使用 timer_getoverrun (2)システムコールによって、呼び出しプロセスは特定の周期的タイマー におけるオーバラン・カウントを得ることができます。システムがシグナルをアプリケーション へデリバーするよりも早くタイマーが期限切れすることがあります。シグナルが他のシグナル をキューイングされているするのではなく、以前のタイマー期限切れからまだ中断しているな ら、失われた期限切れのカウントは中断シグナルで維持されます。これはオーバラン・カウン トです。 シグナルがアプリケーションによってブロックされているために、またはタイマーが超稼動して いるために、タイマーはオーバランします。 タイマー期限切れ通知 SIGEV_SIGNAL を使用するタイマーでのプロセスにおいて、シグナ ルが既にキューイングされているされているかまたは中断しているものと仮定します。もしも シグナルがキューイングされているしているか中断している時にこのタイマーが期限切れす ると、タイマー・オーバランが起こり、そして追加のシグナルが送られます。 注 タイマー期限切れシグナル扱いからこのシステムを起動しなければなりません。もしもこのシ ステムコールの外からそれを起動すると、返されるオーバラン・カウントは、最後にとられたタ イマー期限切れシグナルにおいて有効ではありません。 概要 #include <time .h> int timer_getoverrun (timer_t timer_id) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 timer_id オーバラン・カウントを得たい周期的タイマーのための識別子。この識別子は 以前の timer_creare (2)に由来します(このシステムコールの説明について は、“timer_create ルーチンの使用”を見てください)。 この呼び出しが成功すれば、timer_getoverrun は指定されているタイマーにおいて、オー バラン・カウントを返します。このカウントは、ファイル<limits .h>内の DERAYTIMER_MAX 6-14 SUSE Linux Enterprise Real Time Linux User’s Guide を超えることはできません。-1 の返り値はエラーが発生したことを示します。errno はエラーを 示すように設定されています。起こり得るエラーの種類のリストについては timer_getoverrun (2) man page を参照してください。 POSIX スリープ・ルーチンの使用 nanospeep (2)と clock_nanosleep (2) POSIX システムコールは高精度なスリープ・メカニ ズムを提供し、それは指定されている時間期間が経過するまで、またはシグナルが受信され て結合しているアクションがシグナル扱いシステムコールを実行するまたはプロセスを終了す るまで、呼び出しプロセスの実行またはスレッドの中断を引き起こします。 clock_nanosleep (2)システムコールは、指定されているクロック付の高精度スリープを提 供します。それは、rqtp が指定する時間が経過するまたはスレッドがシグナルを受信するま で、現在走っているスレッドの実行を中断します。 これらのシステムコールは、どのシグナルのアクションまたは妨害にも影響を与えません. nanospeep ルーチンの使用 概要 #include <time .h> int nanospleep (const struct timespec *req, struct timespec *rem) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 req プロセスがスリープに入る時間長を含む timespec 構造へのポインタ。req 値 がスリープ精度の整数複数へと切り上げられるため、またはシステムによる他 の活動のスケジューリングのため、中断時間は要求されたものよりも長くなり ます。シグナルによる割込みを例外として、中断時間は CLOCK_REALTIME によって計られるので req が指定するより短くなりません。ブロッキング要求で 1 マイクロ秒の精度を得ることができます。 rem ヌル・ポインタ定数または timespec 構造へのポインタで、それに対して、もしも nanosleep がシグナルによって割込みされるなら、スリープ間隔内の残りの 時間量が返されます。もし rem が NULL でそして nanosleep がシグナルによ って割込みされるなら、残りの時間は返されません。 6-15 SUSE Linux Enterprise Real Time Linux User’s Guide 0 の返り値は、要求された時間期間が経過したことを示します。-1 の返り値はエラーが発生し たことを示します。errno はエラーを示すように設定されています。起こり得るエラーの種類の リストについては nanosleep (2) man page を参照してください。 clock_nanosleep ルーチンの使用 概要 #include <time .h> int clock_nanosleep (clockid_t which_clock, int flags, const struct timespec *rqtp, struct timespec *rmtp) ; gcc [options] file -lccur_rt ... 引数は以下のように定義されます。 which_clock 使 用 さ れ る ク ロ ッ ク に お け る 識 別 子 。 which_clock の 値 は 、 CLOCK_REALTIME または CLOCK_MONOTONIC です。 flags 以下の 1 つを指定する整数値 TIMER_ABSTIME rqtpが指定する時間に割込みし、which_clock が指定するクロ ック値において絶対的なります。 0 rqtp が指定する時間に割込みし、現在の時間において相対的 になります。 rqtp プロセスがスリープに入る時間長を含む timespec 構造へのポインタ。も しも TIMER_ABSTIME フラッグが指定されており、そして rqtp が指定す る時間値が指定されているクロックの時間値(またはクロックの値がこの ような時間に変更されている)の現在の時間値より少ないかまたは等しい なら、関数はすぐに返されます。さらに、スリープされる時間は、 6-16 SUSE Linux Enterprise Real Time Linux User’s Guide clock_nanosleep (2)への呼び出し後のクロックへの変更に影響されま す。つまり、設定によるかまたは時間の実際的な経過によるかまたはこ れらの組合せによって、どのようにしてクロックがその時間に達するかに 関わり無く、実際的時間が要求されている時間に等しいかまたはそれ以 上になる時に呼び出しは完了します。 指定されている時間値が切り上げられてクロック精度の整数複数になる ために、またはスケジューリング及び他のシステム活動のために、スリー プする時間は要求されているよりも長くなります。シグナルの割り込みに よるものは例外として、中断時間は決して要求されているものより決して 短くなりません。 rmtp TIMER_ABSTIME が 指 定 さ れ て い な い な ら 、 rmtp が ポ イ ン ト す る timespec 構造は間隔内の残り時間の量を含むようにアップデートされま す(例: 要求されている時間から実際にスリープした時間を引く)。もしも rmtp が NULL なら、残り時間は設定されません。絶対時間値の場合、 rmtp 値は設定されません。 成功の場合、少なくとも指定されている時間が経過した後に clock_nanosleep は 0 の値を 返します。失敗の場合、clock_nanosleep は値-1 を返しそして errno はエラーを示すように 設定されています。起こり得るエラーの種類のリストについては clock_nanosleep (2) man page を参照してください。 POSIX タイマーへの/proc インターフェイス ほとんどのアプリケーションにおいて、POSIX タイマー及びナノスリープ機能性におけるデフ ォルトの精度は受容可能です。タイミングが起こる様式にアプリケーションが問題を持つなら、 またはアプリケーションを変更するのが禁止されているなら、または終了を集めるのが望ま れるなら、調整が適切な処置です。POSIX タイマーへのカーネル・インターフェイスは、/proc ファイル・システムを通します。以下にリストされているファイルは POSIX タイマーとナノスリ ープ機能性の精度を制御し、し、タイマーが終了するレートを制限するのに使用することがで きます。ディレクトリ/proc/sys/kernel/posix-timers 内のファイルは以下の通りです。 6-17 SUSE Linux Enterprise Real Time Linux User’s Guide max_expiries 単一割り込みから処理する期限切れの最大数。デフォルトは 20。 recovery_time もしも max_expiries 制限に差し掛かったなら、更なるタイマー期限切れを処 理する前に遅延するナノ秒での時間。デフォルトは 100000。 min_delay ナノ秒でのタイマー割り込みの間の最小時間。これはタイマー割り込みが CPU 時間の全てを消費しないことを確実にします。デフォルトは 10000。 nanosleep_res ナノ秒での nanosleep (2)の精度。デフォルトは 1000。 resolution clock_nanospleep (2)を含む他の POSIX タイマー機能の精度。デフォルト は 1000。 6-18 SUSE Linux Enterprise Real Time Linux User’s Guide 7 システム・クロック及びタイマー この章ではローカル・タイマーとグローバル・タイマーについて説明します。さらに、システム 機能上のローカル・タイマーのディセーブリングの効果についても論じます。 ローカル・タイマー システム上では、それぞれの CPU はローカル(プライベート)タイマーを持っており、それは、 CPU へローカルな周期的割り込みのソースとして使用することができます。デフォルトではこ れらの割り込みは 1 秒あたり 100 回起こり、時間内でよろめくので、1 度にただ 1 つの CPU のみがにローカル・タイマー割り込みを処理します。 ローカル・タイマー割り込みルーチンは以下のローカル・タイミング機能を動作します。それら は、後に続くセクション内でさらに詳細に説明されます。 z CPU 利用性統計を集め、それらは top (1)及び他のユーティリティに使用され ます。 z CPU 上を走るプロセスが周期的にそのタイム・クワンタムを消費するようにし ます。 z そのタイム・クワンタムが使い果たされた時に、他の稼動プロセスのために、 稼動プロセスに CPU を開放するようにします。 z CPU にわたって稼動可能なプロセスのロードのバランスを周期的にとります。 z プロセス及びシステム・プロファイリングを実行します。 z この機能が許可されているこれらのプロセスにおいて、システムの現時間 (wall)クロック及び実行時間割当て制限を実行する。 z POSIX タイマーにおいて割り込みソースを提供する。 ローカル・タイマーは CPU ベースあたりで禁止することができます。これは、最悪のケースの 割り込み応答時間及び、“リアルタイム・パフォーマンス”内で説明されている CPU 上のプロ グラム実行の決定性の両方を向上させます。しかし、ローカル・タイマーのディセーブリング は、通常 SUSE Linux Enterprise Real Time が提供するいくつかの機能性に影響を与えま す。これらの影響は以下で説明されます。 機能性 ローカル・タイマーは以下のセクションで述べられている機能を行います。ローカル・タイマー のディセーブリングは、いくつかの機能における実行可能な代替物と同様に論じられます。 7-1 SUSE Linux Enterprise Real Time Linux User’s Guide CPU アカウンティング プロセスごとのユーザ及びシステム実行時間は以下のシステム機能でレポートされます: ps (1)、top (1)、times (2)、wait4 (2)、sigaction (2)、uptime (1)、w (1)、getrusage (2)、 mpstat (1)、clock (3)、acct (2)、及び/proc/pid/stat。一般的な構築前の SUSE Linux Enterprise Real Time カーネル上では、ローカル・タイマーはこれらの値を取得するのに使用 されます。このカーネルを使用してローカル・タイマーから CPU がシールドされている時、 CPU アカウンティングは行われません。しかし、高精度プロセス・アカウンティング機能がコン フィグされているカーネル上では、ローカル・タイマーの代わりにそれが CPU アカウンティン グのために使用され、そしてローカル・タイマーからの CPU のシールディングは CPU アカウ ンティングに影響を与えません。 高精度プロセス・アカウンティングは、コンテキスト・スイッチング、システムコール、そして割り 込み処理の間に、タイム・スタンプ・カウンター(TSC)登録をサンプリングします。TSC サンプ リング・レートは CPU のクロック・スピードであるため、このアカウンティング方法は最小のオ ーバーヘッドでのとても高い精度をもたらします。それは、システム内のそれぞれのプロセス における、システム、ユーザ、割り込みシステム、そして割り込みユーザ時間を維持します。 高精度プロセス・アカウンティングは、/proc ファイル・システム及びいくつかの“hracct”ライブ ラリ・ルーチンによって提供されます。パフォーマンス・モニターは、システム・パフォーマンス を分析するのに使用される時に、その計測のためにこのタイミング機能を使用します。事前 構築の“デバッグ”及び“トレース”カーネルにはこの機能がコンフィグされています。もし望ま れれば、カーネル・コンフィグレーション GUI 上の General Serup 下でアクセスできるチュー ニング可能カーネル HRACCT 経由で他のカーネル上でそれをコンフィグすることができます。 この機能の完全な情報については、hracct (3)及び hracct (7) man page を参照してくださ い。 プロセス実行時間クワンタム及び制限 ローカル・タイマーは、SCHED_OTHER 及び SCHED_RR スケジューリング・ポリシー内でス ケジュールされているプロセスのクワンタムを期限切れするのに使用されます。これにより、 同等のスケジューリング・プライオリティのプロセスがラウンド・ロビン形式で CPU を共有する ことができます。もしも CPU 上でローカル・タイマーが禁止されているなら、その CPU 上のプ ロセスのクワンタムはもはや期限切れしません。この CPU 上で実行しているプロセスは、そ れがブロックするまで、またはより高いプライオリティのプロセスが稼動可能になるまで、走る ことをこれは意味します。換言すれば、ローカル・タイマー割り込みが禁止されている CPU 上 では、SCHED_RR スケジューリング・ポリシー内でスケジュールされているプロセスは、あた かも SCHED_FIFO スケジューリング・ポリシー内でスケジュールされているように動作すると いうことです。ローカル・タイマーがまだ許可されている CPU 上でスケジュールされているプ 7-2 SUSE Linux Enterprise Real Time Linux User’s Guide ロセスは影響されないことに注意します。プロセス・スケジューリング・ポリシーに関する更な る情報については、4 章“プロセス・スケジューリング”を見てください。 setrlimit (2)及び getrlimit (2)システムコールによって、プロセスが消費することができる CPU 時間の量を設定し、そして制限を得ることをプロセスが行うことができます。この時間期 間が期限切れしたなら、プロセスにはシグナル SIGXCPU が送られます。CPU 時間の蓄積 は、ローカル・タイマー割り込みルーチン内で行われます。よって、もしも CPU 上でローカル・ タイマーが禁止されるなら、プロセスが CPU 上で実行する時間は計上されません。もしもこ れがプロセスが実行する唯一の CPU なら、それは決して SIGXCPU シグナルを受信しませ ん。 インターバルタイマー減少 setitimer (2)及び getitimer (2)システムコールによって、プロセスが“バーチャル・タイマー” をセット・アップし、そしてそれぞれがタイマーの値を得ることができます。プロセスが実行して いる時のみバーチャル・タイマーが減少されます。2 つのバーチャル・タイマーの種類がありま す。1 つは、ユーザ・レベルでプロセスが実行する時のみに減少するもの、もう 1 つは、ユー ザ・レベルでもカーネル・レベルでもプロセスが実行する時に減少するものです。バーチャル・ タイマーが期限切れする時、シグナルがプロセスへ送られます。バーチャル・タイマーの減少 は、ローカル・タイマー・ルーチン内で行われます。よって、CPU 上でローカル・タイマーが禁 止される時、使用された時間がバーチャル・タイマーから減少することはありません。もしもこ れがプロセスが実行する唯一の CPU なら、そのバーチャル・タイマーは決して期限切れする ことはありません。 システム・プロファイリング ローカル・タイマーはシステム・プロファイリングを進めます。プロファイラがレコードするサン プルはローカル・タイマー割り込みの発動によってトリガされます。もしもある CPU 上でローカ ル・タイマーが禁止されるなら、その CPU 上を走るプロセスにおいて gprof (1)コマンド、及び profil (2)システム・サービスは正確に機能しません。 CPU ロード・バランス ローカル・タイマー割り込みルーチンは周期的に load balancer を呼び出し、この CPU 上の 稼動可能なプロセスの数が、システム内の他の CPU 上の稼動可能なプロセスの数より極度 に少なくないことを確認します。もしこれが問題であれば、load balancer は他の CPU からプ ロセスを取得して CPU 全体にわたってのロードのバランスをとります。ローカル・タイマー割り 7-3 SUSE Linux Enterprise Real Time Linux User’s Guide 込みが禁止されている CPU 上では、CPU が実行するプロセスを何も持たない時に、load balancer が呼び出されるのみです。シールドされている CPU 上でバックグランド・プロセスを 走らせることは望ましくないので、この機能のロスはシールドされている CPU においては一 般的に問題ではありません。 CPU 再スケジューリング resched_cntl (2)システムコールの RESCHED_SET_LIMIT 機能によって、ユーザは再ス ケジューリング変数がロックされたままであることが可能な時間量に上限を設定することがで きます。時間制限が超過された時は、SIGABRT シグナルがプロセスへ送られます。この機 能は、アプリケーション開発中に問題をデバッグするために提供されます。その上でローカ ル・タイマーが禁止されている CPU 上で、ロックされている再スケジューリング変数でのプロ セスが走らされる時、時間制限は減少されないので、よってプロセスが指定されている時間 制限をオーバランする時にシグナルは送られません。 POSIX タイマー ローカル・タイマーは POSIX タイマーにおいてタイミング・ソースを提供します。もしも CPU が ローカル・タイマー割り込みからシールドされており、もしもその CPU 上のプロセスがアクティ ブな POSIX タイマーまたは nanosleep (2)機能を持つなら、ローカル・タイマー割り込みはシ ールドされている CPU 上でまだ起こります。もしもシールドされている CPU 上で走ることをプ ロセスが許されていないなら、プロセスが走ることを許される CPU へとそのタイマーは移りま す。 その他 上にリストされた機能性に加え、もしもそのローカル・タイマーが禁止されているなら、標準 Linux コマンド及びユーティリティが提供するいくつかの機能は正確に機能しません。 これらには以下のものが含まれます。 bash (1) sh (1) strace (1) これらのコマンド及びユーティリティに関するさらなる情報については、対応する man page を 参照してください。 7-4 SUSE Linux Enterprise Real Time Linux User’s Guide ローカル・タイマーのディセーブリング shield (1)コマンド経由または/proc/shield/ltrmrs へ 16 進値を割り当てることによって、ど の CPU の割り当てにおいてもローカル・タイマーを禁止することができます。この 16 進値は CPU のビットマスクで、それぞれのビットの基数位置は 1 つの CPU を識別し、そしてビット値 はその CPU のローカル・タイマーが禁止される(=1)、または許可される(=0)かを指定します。 更なる情報については、2 章の“リアルタイム・パフォーマンス”及び shield (1) man page を 見てください。 グローバル・タイマー iHawk システム上で、プログラム可能割り込みタイマー(PIT)はグローバル・システム・ワイ ド・タイマーとして機能します。この割り込みは IRQ 0 と呼ばれており、デフォルトでは割り込 みのそれぞれの発生は割り込みを現在処理していないどの CPU へもデリバーされます。 以下のシステム・ワイド・タイマー機能を行うためにグローバル・タイマーは使用されます。 ・ システム現時間(wall)クロック及び ticks-since-boot 時間をアップデートします。 ・ システム・タイマー・リストからイベントを取り去る。これには driver watchdog timer 及 び alarm (2)のようなプロセス・タイマー機能が含まれます。 グローバル・タイマー割り込みは禁止することはできません。しかし、shield (1)コマンド経由 または許容されている CPU のビットマスクの 16 進数形式での、/proc/irq/0/smp_affinity への割り当て経由で、いくつかの望まれる CPU のサブセットへそれを方向させることができ ます。CPU シールディングに関する更なる情報については、2 章の“リアルタイム・パフォーマ ンス”を見てください。 7-5 SUSE Linux Enterprise Real Time Linux User’s Guide 8 ファイル・システム及びディスク IO この章では、SUSE Linux Enterprise Real Time オペレーティング・システム上の xfs ジャー ナル・ファイル・システム及び直接ディスク IO を行うための手順について説明します。 ファイル・システムのジャーナル 伝統的なファイル・システムでは、割り込み後、特別なファイル・システムのチェックを行わな ければなりません。それは、ファイル・システムがどれほど大きいかに依存して、完了するの に多くの時間がかかります。ジャーナル・ファイル・システムは、失敗適応的ファイル・システム で、journal と呼ばれる特別なログ・ファイルを維持することによってデータ完全性を確実にし ます。ファイルがアップデートされる時、オリジナルのディスク・ブロックがアップデートされる 前に、ファイルのメタデータがディスク上のジャーナルにライトされます。ジャーナル・エントリ が完了する前にシステム・クラッシュが起こっても、オリジナルのデータはまだディスク上にあ り、新しい変更のみが失われます。ディスク・アップデート中にもしもクラッシュが起これば、ジ ャーナル・エントリは何が起こったかを示します。リブートにおいて、ジャーナル・エントリは再 生され、そして割り込みされていたアップデートが完了されます。これはファイル・システム・チ ェックの複雑性を大幅に減らし、また回復時間を減少させます。 SGI からの XFS ジャーナル・ファイル・システムにおけるサポートは、SUSE Linux Enterprise Real Time ではデフォルトで許可されています。XFS は複数スレッドの、64 ビット・ファイル・ システムで 100 万テラ・バイトの大きさのファイルを扱う能力があります。大きなファイル及び 大きなファイル・システムに加えて、XFS は拡張された属性、変数ブロック・サイズをサポート し、拡がりベースであり、そして Btrees(ディレクトリ、拡がり、フリー空間)を広範に使用して パフォーマンス及びスケーラブル(scalability)両方を補助します。ユーザ及びグループ割り 当て両方がサポートされています。 構造及びアルゴリズムのログのジャーナルはデータ・トランザクションを高速にリード及びライ トし、ジャーナルのパフォーマンス影響を最小にします。XFS には raw(生)に近い IO パフォ ーマンスをデリバーする能力があります。 拡張された属性は、ファイルと結合する名/値ペアです。属性は、一般ファイル、ディレクトリ、 記号的リンク、デバイス・ノード、そして全ての他の inode の種類にくっ付けることができます。 属性値は恣意的なバイナリ・データの最大 64KB までを含むことができます。2 つの属性名空 間が利用可能です。通常ファイル許可が保護する全てのユーザが利用できるユーザ名空間、 そして権限ユーザのみがアクセス可能なシステム名空間です。システム名空間は、アクセス 8-1 SUSE Linux Enterprise Real Time Linux User’s Guide 制御リスト(ACL)及び階層的記憶マネージ(HSM)・ファイル移動ステータスのような保護さ れているファイル・システム・メタデータにおいて使用することができます。 NFS バージョン 3 は、そのプロトコルをサポートする他のシステムへ 64 ビット・ファイル・シス テムをエクスポートするのに使用することができます。NFS バージョン 2 システムはプロトコ ルが要求する 32 ビット制限を持ちます。 ローカル及びリモートの SCSI テープまたはファイルへの XFS ファイル・システムのバックアッ プ及び復帰は、xfsdump 及び xfsrestore を使用して行われます。拡張された属性及び割り 当てのダンピングの情報はサポートされています。 データ・マネージメント API(DMAPI/XDSM)によって、ファイル・システム構造のディスク及び 情報への生の(raw)アクセスを必用とせず、高パフォーマンスダンプ・プログラムと同様に階 層的記憶マネージメントの実行が可能です。 ツールの完全なセットは XFS で提供されています。XFS ファイル・システムの広範なドキュメ ントは以下で見ることができます。 http://oss.sgi.com/projects/xfs XFS ファイル・システムの生成 XFS ファイル・システムの生成には、以下のものが要求されます。 ・ その上に XFS ファイル・システムを生成するパーティションを識別します。それは、 新しいディスクから、または既存するディスク上のパーティション化されていない空 間から、または既存するパーティションへの上書きからです。もしも新しいパーティシ ョンを生成するなら、fdisk (1) man page を参照してください。 ・ mkfs.xfs (8)を使用してパーティション上に XFS ファイル・システムを生成します。も しもターゲット・ディスク・パーティションが現在ファイル・システムでフォーマットされて いるなら、-f (force)オプションを使用します。 mkfs.xfs [-f] /dev/devfile ここで、devfile はファイル・システムを生成したいパーティションです。例として、 sdb3 です。これはそのパーティション上の現在のいくつかのデータを破壊すること に注意します。 XFS ファイル・システムのマウンティング mount (8)コマンドを使用して XFS ファイル・システムをマウントします。 8-2 SUSE Linux Enterprise Real Time Linux User’s Guide mount -t xfs /dev/devfile /mountpoint XFS ファイル・システムをマウントする時に利用可能なオプションについては mount (8) man page を参照してください。 XFS はジャーナル・ファイル・システムであるため、それがファイル・システムをマウントする前 にそれは終了されていないトランザクションでのトランザクション・ログをチェックし、ファイル・ システムをアップデートします。 データ・マネージメント API(DMAPI) DMAPI は、カーネルと階層的記憶マネージメント・システム(HSM)との間でファイル・マネー ジメント要求を渡すための XFS ファイル・システム内のメカニズムです。 DMAPI を構築するためには、構築の一部としてのカーネル・コンフィグレーション GUI 上のフ ァイル・システム下で XFS_DMAPI システム・パラメータをアクセス可能に設定します。 DMAPI の構築についてのさらなる情報については、以下を参照してください。 http://oss.sgi.com/projects.xfs/dmapi.html 直接ディスク IO 通常、ファイルへの全てのリード及びライトはファイル・システム・キャッシュを通り抜けます。 データベース・プログラムのようないくつかのアプリケーションはそれら自身のキャッシングを 必要とします。直接 IO は、カーネルのデータのバッファリングをバイパスする IO のバッファさ れていない形式です。直接 IO では、ファイル・システムはディスクとユーザ供給のバッファと の間を直接にデータをトランスファします。 SUSE Linux Enterprise Real Time によって、ユーザはディスクから直接リードしバーチャ ル・アドレス空間内へのディスクへ直接にへライトすることができ、中間のオペレーティング・ システム・バッファリングをバイパスしそしてディスク IO スピードを増大します。直接ディスク IO はさらに、トランスファされたデータのコピーを消すことによってシステム・オーバーヘッドを 減少させます。 直接 IO においてディスク・ファイルをセット・アップするには、open (2)または fcntl (2)システ ムコールを使用します。以下の手順の 1 つを使用します。 ・ 8-3 プログラムから open システムコールを起動して、ディスク・ファイルのパス名を指定 SUSE Linux Enterprise Real Time Linux User’s Guide し、oflag 引数内で O_DIRECT ビットを設定します。 ・ オープン・ファイルでは、fcntl システムコールを起動します。オープン・ファイル記述 子を指定し、F_SETFL コマンドを指定し、そして arg 引数内で O_DIRECT ビットを 設定します。 直接ディスク IO トランスファは、以下の要求の全てを満たさなければなりません。 ・ ユーザ・バッファは、_PC_REC_XFER_ALIGN pathconf (2)変数の総体的複数で あるバイト境界線上で整列されていなければなりません。 ・ ファイル・ポインタの現在の設定はファイル内のオフセットの位置を見つけ、そこで次 の IO オ ペ レ ー シ ョ ン を 開 始 し ま す 。 こ の 設 定 は 、 _PC_REC_XFER_ALIGN pathconf (2)変数において返される値の総体的複数でなければなりません。 ・ IO オペレーション内でトランスファされるバイト数は、_PC_REC_XFER_ALIGN pathconf (2)変数において返される値の総体的複数でなければなりません。 直接 IO をサポートしていないファイル・システム上のファイルにおいて直接 IO を許可すると エラーを返します。ファイル・システム特定 soft オプションでマウントされているファイル・シス テム内のファイル上の直接ディスク IO を許可しようとしてもエラーを引き起こします。soft オプ ションは、アンマウンティング前までファイル・システムがキャッシュから物理ディスクへデータ をライトする必要がないことを指定します。 推奨はされませんが、両モードのパフォーマンスを劣化する代償で、直接及びキャッシュ(非 直接)モード両方で同時にファイルを開くことができます。 直接 IO の使用はシステム不具合後にファイルを復活することができることを確実にするもの ではありません。確実にするためには、POSIX 同期化 IO フラッグを設定しなければなりませ ん。 もしもプロセスが mmap (2)システムコールでその一部を現在マップするなら、直接モードで ファイルを開くことはできません。同様に、もしも呼び出し内で使用されているファイル記述子 が直接モードで開かれているファイルにおいてのものなら、mmap への呼び出しは失敗しま す。 タスクにおいて直接 IO がより良い IO スループットを提供するか否かはアプリケーションに依 存します。 ・ 8-4 全ての直接 IO は同期的で、よって、アプリケーションによる IO と処理は重なりませ SUSE Linux Enterprise Real Time Linux User’s Guide ん。 ・ オペレーティング・システムは直接 IO をキャッシュすることはできないので、前リード または後ライト・アルゴリズムはスループットを向上させません。 しかし、データはデータの他のコピー無しでユーザ・メモリからデバイスへと直接に移動する ため、直接 IO は常にシステム・ワイド・オーバーヘッドを削減します。embedded SCSI ディス ク・コントローラ(CPU・ボード上のディスクコントローラ)と同じ CPU ボード上のローカル・メモ リの間を直接ディスク IO する時に、システム・オーバーヘッドの省略ができます。 8-5 SUSE Linux Enterprise Real Time Linux User’s Guide 9 メモリ・マッピング この章では、他のプロセスのアドレス空間のコンテンツへのアクセスの処理において SUSE Linux Enterprise Real Time が提供する方法について説明します。 ターゲット・プロセスのアドレス空間へのマッピングの確立 それぞれの稼動プロセスにおいて、/proc ファイル・システムはプロセスのアドレス空間を表 すファイルを提供します。このファイルの名前は/proc/pid/mem で、pid はそのアドレス空間 が表されているプロセスの ID を示します。プロセスは/proc/pid/mem ファイルを open (2)す ることができ、そして read (2)と write (2)システムコールを使用して他のプロセスのアドレス 空間の内容をリードし修正することができます。 libccur_rt ライブラリ内に常駐する usermap (3)ライブラリ・ルーチンは、単純な CPU のリー ド及びライトの使用を通して現在実行しているプログラム内で位置を効率的にモニターし修正 する方法でアプリケーションを提供します。 このルーチンの基となるカーネル・サポートは/proc ファイル・システム mmap (2)システム・ サービス呼び出しで、それはプロセスに他のプロセスのアドレス空間の部分をそれ独自のア ドレス空間へマップさせます。よって、他の実行プログラムのモニターリング及び修正は、 /proc ファイル・システム read (2)及び write (2)呼び出しのオーバーヘッドを受けること無く、 アプリケーションの独自のアドレス空間内の単純な CPU リード及びライトになります。 以下のセクションではこれらのインターフェイスを説明し、アプリケーション内で mmap (2)ま たは usermap (3)を使用するか否かを決定する際の考慮をリストしています。 mmap (2)の使用 プロセスは mmap (2)を使用してそのアドレス空間の部分を/proc/pid/mem ファイルへマップ することができ、よって他のプロセスのアドレス空間の内容に直接にアクセスします。 /proc/pid/mem ファイルへのマッピングを確立するプロセスは以下からモニターリング・プロ セスとして言及されています。そのアドレス空間がマップされているプロセスはターゲット・プロ セスとして言及されています。 /proc/pid/mem ファイルへのマッピングを確立するためには以下の要求が満たされなけれ ばなりません。 ・ ファイルは少なくともリード許可で開かれなければなりません。もしもターゲット・プロセスの 9-1 SUSE Linux Enterprise Real Time Linux User’s Guide アドレス空間を修正する意図があるなら、ファイルはライト許可でも開かれなければなりませ ん。 ・ マッピングを確立する mmap への呼び出しで、ターゲット・プロセスのアドレス空間 へのリード及びライトがターゲット・プロセスとモニターリング・プロセスとの間で共有 されるように、フラッグ引数は MAP_SHARED オプションを指定するべきです。 ・ ターゲット・マッピングはリアル・メモリ・ページになければならず、HUGETLB エリア 内ではありません。現在の実行は IO 空間ページへのマッピングの生成または HUGETLB エリアの生成のサポートはしていません。 モニターリング・プロセスの結果の mmap マッピングが領域内で現在マップされているターゲ ット・プロセスの物理メモリ・ページ[offset, offset + length]になることに注意することが重要で す。結果としてもしも mmap 呼び出しがつくられた後にターゲットのマッピングが変化するなら、 ターゲット・プロセスのアドレス空間へのプロセスのマッピングのモニターリングは無効になり ます。このような状況では、モニターリング・プロセスは基となる物理ページへのマッピングを 保持していますが、しかしマッピングはもはやターゲット・プロセスと共有されていません。モ ニターリング・プロセスはマッピングがもはや有効ではないことを検出することができないため、 アプリケーション内にモニターリング・プロセスとターゲットの間の関係を制御するための装備 をしなければなりません。(表記 [startI, end]は start から end までの間隔を示します。start は含みますが、end は含みません。) ターゲット・プロセスのアドレス空間へのモニターリング・プロセスのマッピングが無効になる 状態は以下のものです。 z ターゲット・プロセスが終了します。 z 領域[offset, offset + length]内で munmap (2)または mremap (2)のいずれかで、 ターゲット・プロセスがページをアンマップします。 z ターゲット・プロセスが領域[offset, offset + length]内のページを mmap (2)で異な るオブジェクトへマップします。 z ターゲット・プロセスが fork (2)を起動して領域[offset, offset + length]内でアンロッ クされた、プライベートな、ライト可能なページ内へ、子プロセスがそうする前に、ラ イトします。この場合、ターゲット・プロセスはページのプライベートなコピーを受け取 り、そのマッピング及びライト・オペレーションはコピーされたページへとリダイレクト されます。モニターリング・プロセスはオリジナル・ページへのマッピングを保持して います。 z ターゲット・プロセスが fork (2)を起動してそして領域[offset, offset + length]内のプ ライベートでライト可能なページをメモリ内へとロックします。ここでこのページはま だ子プロセスと共有されています(ページは copy-on-write とマークされています)。 9-2 SUSE Linux Enterprise Real Time Linux User’s Guide この場合、ロック・オペレーションを行うプロセスはページのプライベートなコピーを 受け取ります(あたかもそれが最初にページにライトしたように)。もしもそれがペー ジをロックするターゲット(親)・プロセスなら、プロセスのマッピングのモニターリング はもはや有効ではありません。 z タ ー ゲ ッ ト ・プ ロ セ ス は mprotect (2) を 起 動 し て、 ま だ 子 プ ロ セ ス ( ペ ー ジは copy-on-write とマークされています)と共有している領域[offset, offset + length] 内のロックされた、プライベートな、リード・オンリー・ページ上のライト許可を許可し ます。この場合、ターゲット・プロセスはページのプライベートなコピーを受け取りま す。モニターリング・プロセスはオリジナル・メモリ・オブジェクトへのマッピングを保 持しています。 もしもアプリケーションがモニターリング・プロセスのアドレス空間マッピングのターゲットにな るように予期されていれば、以下のことを行うようにアドバイスされます。 ・ ターゲット・プロセス内のメモリ・ロッキング・オペレーションを、そのアドレス空間がモ ニターリング・プロセスによってマップされる前に行います。 ・ fork (2)を起動する前に、それに対して親によるマッピング及びモニターリング・プロ セスが保持される必要があるページをメモリ内へとロックします。 もしもアプリケーションがアドレス空間マッピングへのターゲットになるように予期されていな ければ、fork を起動する後までメモリ内のロッキング・ページを延期します。 追加的詳細については mmap (2) man page を参照してください。 usermap (3)の使用 /proc ファイル・システム mmap (2)システム・サービス呼び出しサポートに加えて、SUSE Linux Enterprise Real Time はさらに、ターゲット・プロセスのアドレス空間の部分をモニター リング・プロセスのバーチャル・アドレス空間の中へマッピングする別の方法として、usermap (3)ライブラリ・ルーチンを提供します。このルーチンは libccur_rt ライブラリの中にあります。 usermap ライブラリ・ルーチンは基となる/proc mmap システム・サービス呼び出しインター フェイスを内的に使用してターゲット・アドレス空間マッピングを生成すると共に、usermap は 以下の追加的機能を提供します。 ・ 呼び出し元はターゲット・プロセスのアドレス空間内の必要なバーチャル・アドレス及びバ ーチャル・エリアの長さを指定すればよいだけです。この要求を、開始アドレス及び mmap を 呼び出す前のページ・サイズの複数である長さ値と整列されるページの中へ変換する詳細を、 usermap ルーチンは扱います。 9-3 SUSE Linux Enterprise Real Time Linux User’s Guide ・ usermap ルーチンは複数ターゲット・プロセス・データ・アイテムのために使用される ように意図されており、よって重複する mmap マッピングの生成を避けるようにそれ は書かれています。usermap は存在する全てのマッピングについての内的 mmap 情報を維持しており、そして要求されているデータ・アイテム・マッピングが既存する マッピングの領域の中に含まれる時、重複する新しいマッピングを生成する代わり にこの既存するマッピングが再使用されます。 ・ mmap を起動する時、既に開かれているファイル記述子を供給しなければなりませ ん。適切な時間においてターゲット・プロセスのファイル記述子を open (2)そして close (2)する責任があります。 usermap を使用する時、呼び出し元はターゲット・プロセスのプロセス ID(pid_t)を指定する 必要があるだけです。usermap ルーチンは正確な/proc/pid/mem ファイルを開くことを扱い ます。それはまたこのファイル記述子のオープンを維持し、よってこの同じターゲット・プロセ ス ID における追加的な usermap (3)呼び出しはこの/proc ファイル記述子を再開することを 要求しません。 全ての場合においてファイル記述子をオープンにして離れることが適切ではないことに注意 します。しかし、明確にファイル記述子を閉じて、そして 0 の“len”パラメータ値と共にルーチン を呼び出すことによって usermap が使用している内的マッピング情報を取り去ることは可能 です。全てのターゲット・マッピングが生成された後にのみ、モニターリング・プロセスがこの “閉じる-そして-取り去る”機能を使用することが推奨されます。そうすれば、呼び出し元はま だ usermap の中に構築されている最適化を利用することができます。この機能に関するさら なる詳細については usermap (3) man page を見てください。 usermap ライブラリ・ルーチンも同じ基となる/proc/pid/mem mmap (2)システムコールサポ ートを内的に使用しているため、“mmap (2)の使用”で論じられた、プロセスのマッピングの モニターリングがもはや有効ではなくなる同じ制限が usermap マッピングにも適用すること に注意します。 usermap (3)ルーチンの使用に関するさらなる情報については、usermap (3)man page を 参照してください。 備考 既に言及した usermap の機能に加えて、使用しているアプリケーションで usermap (3)ライ ブラリ・ルーチンまたは mmap (2)システム・サービス呼び出しのどちらを使用するかを決定 する際に、以下の残りの点も考慮することが推奨されます。 9-4 SUSE Linux Enterprise Real Time Linux User’s Guide ・ /proc/pid/mem ファイルへのマッピングを確立するためにそれを使用する機能は SUSE Linux Enterprise Real Time 拡張ですが、 mmap (2)システムコールは標 準的な System V インターフェイスです。usermap (3)ルーチンは完全に SUSE Linux Enterprise Real Time 拡張です。 ・ mmap (2)はモニターリング・プロセス内でのページ保護及びマッピングの位置の直 接制御を提供します。usermap (3)は提供しません。 カーネル・コンフィグレーション・パラメータ /proc ファイル・システム mmap (2)呼び出しの動作にに直接的に影響を与える、2 つの SUSE Linux Enterprise Real Time カーネル・コンフィグレーション・パラメータがあります。 usermap (3)はさらに/proc ファイル・システム mmap (2)サポートも使用するため、 usermap (3)も同様にこれらのコンフィグレーション・パラメータに影響されます。 カーネル・コンフィグレーション・パラメータは、カーネル・コンフィグレーション GUI 上の Pseudo File Systems 下でアクセス可能です。 PROCMEM_MMAP もしもこのカーネル・コンフィグレーション・パラメータが許可されているなら、 /proc ファイル・システム mmap (2)サポートはカーネル内へ構築されま す。 もしもこのカーネル・コンフィグレーション・パラメータが禁止されているなら、 /proc ファイル・システム mmap (2)サポートはカーネル内へ構築されま せん。この場合、usermap (3)と/proc mmap (2)呼び出しが ENODEV の errno 値を返します。 このカーネル・コンフィグレーション・パラメータは、全ての SUSE Linux Enterprise Real Time カーネル・コンフィグレーション・ファイルにおいてデ フォルトで許可されています。 PROCMEM_ANYONE もしもこのカーネル・コンフィグレーション・パラメータが許可されているなら、 モニターリング・プロセスがリードまたはリード/ライト・アクセスで成功し て open (2)することができるどの/proc/pid/mem ファイルも、/proc mmap (2)または usermap (3)呼び出しにおいてターゲット・プロセスとし て使用されます。 もしもこのカーネル・コンフィグレーション・パラメータが禁止されているなら、 モニターリング・プロセスはモニターリング・プロセスが現在 ptrace してい るターゲット・プロセスを/proc mmap (2)または usermap (3)することが できるのみです。さらに、ptrace されているターゲット・プロセスは、/proc 9-5 SUSE Linux Enterprise Real Time Linux User’s Guide mmap (2)システム・サービス呼び出しがつくられる時に停止した状態で なければなりません。(他のプロセスの ptrace に関するさらなる情報につ いては ptrace (2) man page を見てください。) このカーネル・コンフィグレーション・パラメータは、全ての SUSE Linux Enterprise Real Time カーネル・コンフィグレーション・ファイル内でデフォ ルトで許可されています。 9-6 SUSE Linux Enterprise Real Time Linux User’s Guide 10 Non-Uniform Memory Access (NUMA) NUMA サポートは、 Opteron システムで利用可能で、あなたにそこからプログラムの ページが割り当てられるはずであるメモリの場所に影響を与えることを許します。 概観 非ユニフォームのメモリアクセス(NUMA)のシステムでは、ローカルメモリ以外のメモリ にアクセスすることはもっと長くかかります。 マルチプロセッサ Opteron システムは NUMA アーキテクチャです。 これはそれぞれの CPU チップがそれ自身のメモリリソー スと結び付けられるからです。 CPU とその関連づけられたメモリはユニークな物理的なバスに位置しています。 CPU はそのローカルメモリバスの上にあるメモリに高速にアクセスします、しかし他の CPU がその CPU にローカルではないメモリにアクセスするためには、1つ以上の追加の物理 的なバス接続を越えなくてはなりません。 CPU とバスの間の関係は図10-1に示され ます。 図 10-1 NUMA システムに関する CPU/バス関係 これは Opteron システムでメモリにアクセスする時間がプログラムが走るCPUとプロ グラムのページが割り当てられるメモリ領域の上に依存することを意味します。 NUMA ノードが NUMA ノードのメモリ領域と同じ物理的なバスでメモリと位置す るすべてのCPUの1つの領域であるために定義されます。 システムブートの間にカー ネルは、CPUと NUMA ノードの連合を定義する構造を作成して、 NUMA メモリか らCPUへのレイアウトを決定します。 現在の Opteron システムでは、メモリ領域が位 置する物理的なバスは直接たった1つのCPUに接続しています。 最適なパフォーマンスを得るために、プログラムがそのプログラムによって利用され てメモリページにローカルなCPU上で走らなくてはなりません。 この章で記述された NUMA インタフェースはプログラムがそこからプログラムのページが割り当てられ 10-1 SUSE Linux Enterprise Real Time Linux User’s Guide るノードを指定することを可能にします。 プロセスのCPUアフィニティを設定するこ とに対して、メカニズムと結びつけられるとき、これらのインタフェースはプログラ ムが非常に決定論のメモリアクセス時間を得ることを可能にします。 NUMA サポートは Opteron プロセッサの iHawk システムでだけ利用可能です。 若 干のCPUがローカルなメモリを持っていないように、 Opteron システムの構成を設定 することは可能です。 この場合メモリがないCPUは NUMA ノードに割り当てられるでしょう、しかしこの CPUからのメモリアクセスのすべてが遠いメモリアクセスであるでしょう。 これはメ モリを持っている同じ NUMA ノードにあるCPUの上にメモリがないCPUとプロセス 両方上で走るプロセスのメモリパフォーマンスに影響を与えます。 これは決定論的な プログラム実行のために最適なコンフィグレーションではありません。 コンフィギュレーションの詳細についてはこの章で後にセクション「コンフィギュレ ーション」を参照してください。 どのようにメモリパフォーマンスを最適化して、そ して決定論のメモリアクセス時間を得るべきかについて、もっと多くのインフォメー ションのためにセクション「パフォーマンスガイドライン」に言及してください。 常 に同じ時間のプログラム実行時間を得ることためには、決定論的なメモリアクセスが 重要であることに注意を払ってください。 メモリポリシー NUMA サポートがメモリポリシーのコンセプトを実装します。 メモリポリシーは原 則ユーザータスク毎のタスク間に適用されます。 所定のタスクの中のバーチャルアド レス空間の範囲が同じくそれらのページのためにタスク規模のメモリポリシーに優先 されるそれら自身の別個のメモリポリシーを持っているかもしれません。 バーチャル アドレスエリアのためのメモリポリシーが fork/clone オペレーションによって生成さ れる子タスクに継承されます。 NUMA メモリポリシーは: MPOL_DEFAULT これは、メモリが利用可能であるなら、メモリページがローカルな メモリから現在のCPUまで割り当てられるデフォルトです。 タスクあるいはその子が 特定のメモリポリシーを指定しなかったときはいつでも、このポリシーが使われます。 あなたはタスクのメモリポリシーとして、あるいは異なったタスクのメモリ政策に専 念させられるタスクの中のバーチャルメモリエリアのために明示的に MPOL_DEFAULT ポリシーを設定することができます。 MPOL_BIND これはメモリアロケーションをノードマスクで指定されたノードだけ に制限する厳しいポリシーです。 ページは指定されたノードだけから割り当てられま す、そして、メモリが ノードマスク で割り当てられたノードで利用可能ではないと きでも、ページアロケーションは失敗します。 このポリシーは他のメモリポリシーよ りもっと多くのノードページが確実に割り当てられる機能を提供します. 10-2 SUSE Linux Enterprise Real Time Linux User’s Guide プロセスに対して将来的に割り当てられるすべてのメモリがローカルなメモリへであ ることを保証する唯一の方法は、CPUアフィニティと MPOL_BIND ポリシー両方を一 つのCPUにセットすることに注意してください。 MPOL_PREFERRED ポリシーは(一つの)優先ノードを割り当てセットします。 カ ーネルは最初にこのノードからページを割り当てようとして、そして、優先ノードの フリーメモリが少ないとき、他のノードを使うでしょう。 MPOL_INTERLEAVE ポリシーは、ノードマスク で指定したラウンドロビン方法 でノードへのアロケーションを行います。 これは反応時間の代わりにバンド幅を最適 化します。 効果的であるためには、記憶領域はかなり大きくあるべきです。ユーザー スペースページアロケーションのほかに、カーネルメモリアロケーションのリクエス トの多くが同じく現在実行しているタスクのタスク規模のメモリポリシーによって決 定されます。 しかしながら、すべてのカーネルページアロケーションが現在のタスク のメモリポリシーによってコントroleされるわけではありません。 例えば、DMAのた めにメモリを割り当てるたいていのデバイス・ドライバは、装置のI/Oバスが位置する ノードからメモリを割り当てるか、その代わりにそのI/Oバスまで最も近いノードから メモリを割り当てます。. すでに行なわれたページアロケーションはタスクのメモリポリシーに対する変更に 対して影響を受けていません。 例えば、2つのCPUに一対一で存在するローカルメモ リがあると想定してください。 タスクが 0x1 のCPUアフィニティと MPOL_DEFAULT のメモリポリシーでCPU0 の上にしばらくの間、実行したと仮定します、そしてそれは ノードマスク 値とその CPUアフィニティを 0x2 に変更し、同時にそのメモリポリシーを MPOL_BIND に変 えます。 しかし、そのタスクがCPU1の上で実行を始めても、そのメモリイメージはタスク にローカルではないアドレス空間の中のページで実行されています。 次のセクションはシステムサービス、ライブラリ機能と NUMA マネージメントのた めに利用可能なユーティリティーを記述します。 NUMA User Interface run(1) コマンドはタスク実行時にメモリポリシーを指定するか、あるいは変更するため に使うことができます。 shmconfig(1)は共有メモリエリアのために使用することができ、ライブラリ機能、システ ムサービスと他のユーティリティーとファイルは NUMA コント role のために利用できま す。この機能の細部が、下記の章で後述されています。 10-3 SUSE Linux Enterprise Real Time Linux User’s Guide run(1) コマンドを使用した場合の NUMA サポート run(1) コマンドのメモリポリシーオプションは、プロセスの NUMA メモリポリシーの表 示と変更を行うことが出来ます。 10 その概要は: run [OPTIONS] COMMAND [ARGS] メモリポリシーは、オプションの一つとして、以下の書式で利用できます。 --mempolicy=MEMPOLICY_SPECIFIER -M MEMPOLICY_SPECIFIER run コマンドのメモリポリシーオプションは、これから実行するプロセスあるいは、 スレッドだけに作用します。既存のプロセスあるいはスレッドを識別するPROCESS / THREAD_SPECIFIERでは、メモリポリシー選択が使われないことに注意してください。 MEMPOLICY_SPECIFIER は、次のことのたった1つを含み、省略することができます。 list はコンマで切り離されたリスト、あるいはCPUの範囲;例えば、「0,2-4,6」です。 “active”あるいは“boot”は、それぞれすべての有効なプロセッサあるいはブーツプロ セッサを指定するために使うことができます。任意のティルデ[~]がリストを否定し ますが、“active”は、否定することができません。 [~]list b[ind]=list listで指定されたCPUのローカルメモリを使ってMPOL_BINDメモリポリシーで プログラムを実行します。 b[ind] バイアスオプションで指定したCPUのローカルメモリを使ってMPOL_BINDメ モリポリシーでプログラムを実行します。バイアスオプションはこの選択で指 定されなくてはならないCPUを定義しその上でプログラムが走るはずです。 i[nterleave]=[~]list listで指定したCPUのローカルメモリを使って MPOL_INTERLEAVE メモリポ リシーでプログラムを実行します。 p[referred]=CPU 一つの指定されたCPUにローカルメモリを使うことをより好んで、 MPOL_PREFERRED メモリポリシーを使って指定されたプログラムを実行し ます。 d[efault] MPOL_DEFAULT メモリポリシーを使って指定されたプログラムを実行しま 10-4 SUSE Linux Enterprise Real Time Linux User’s Guide す。これはデフォルトメモリポリシーです。 n[odes] それぞれのCPUノード上の全体のメモリと現在フリーのメモリとともに、それ ぞれの NUMA ノードの状態を表示します。 他のどのようなオプションあるい はプログラムも、このrunでは指定できません。 v[iew] 現在のプロセスのメモリポリシー設定を示します。他のどのようなオプション あるいはプログラムも、このrunでは指定できません。 システムがローカルなメモリなしで1つ以上のCPUを含んでいるとき、これらのCPU はシステム初期化の時にラウンドロビンファッションでノードを割り当てます。 ノー ドに割り当てられるけれども、それらは実際にローカルなメモリを持っていません、 そして常に、それら自身の割り当てられたノードへのメモリアクセスを含めて、ロー カルでないメモリアクセスをするでしょう。このタイプのコンフィギュレーションで の、v[iew]のアウトプットは、NUMA ノードに関するCPUを示すコラムの下にローカ ルなメモリを含んでいない“NoMemCPUs” を表示するでしょう。 それぞれのCPUが、インストールされたメモリモジュールを持っている場合には、 NUMA を可能にされたカーネルを使うようにカーネル構成を設定することを奨励し ます。 run(1)コマンドのその他のオプションは、4章あるいは、man ページを参照してくださ い。 もし numactl(8)があなたのシステムで利用可能であるなら、それはrunコマンドと同様 にNUMAメモリポリシーを設定するために使うことができます。 10-5 SUSE Linux Enterprise Real Time Linux User’s Guide shmconfig(1)を使ったシェアードメモリエリアに対する NUMA サポート shmconfig(1)を使って新しいシェアードメモリエリアを割り当てられるか、あるいは、 既存のシェアードメモリエリアをNUMA ポリシー”mempolicy”オプションで修正する ことができます。 概要は: /usr/bin/shmconfig -M MEMPOLICY [-s SIZE] [-g GROUP] [-m MODE] [-u USER] [-o offset] [-S] [-T] {key | -t FNAME} “mempolicy”オプションは以下の書式をしています: --mempolicy=MEMPOLICY -M MEMPOLICY MEMPOLICY は、次のたった1つを含み、省略することができます。 LIST はコンマで切り離されたリスト、あるいはCPUの範囲;例えば、「0,2-4,6」です。 “active”あるいは“boot”は、それぞれすべての有効なプロセッサあるいはブーツプロ セッサを指定するために使うことができます。任意のティルデ[~]がリストを否定し ますが、“active”は、否定することができません。 それぞれのノードのCPU全体の利用可能なフリーメモリを見るために、run -M nodes を使用できます。 [~]LIST b[ind]=LIST LISTで指定されたCPUのローカルメモリを使ってMPOL_BINDメモリポリシー でプログラムを実行します。 b[ind] バイアスオプションで指定したCPUのローカルメモリを使ってMPOL_BINDメ モリポリシーでプログラムを実行します。バイアスオプションはこの選択で指 定されなくてはならないCPUを定義しその上でプログラムが走るはずです。 i[nterleave]=[~]LIST LISTで指定したCPUのローカルメモリを使って MPOL_INTERLEAVE メモリ ポリシーでプログラムを実行します。 p[referred]=CPU 一つの指定されたCPUにローカルメモリを使うことをより好んで、 MPOL_PREFERRED メモリポリシーを使って指定されたプログラムを実行し ます。 d[efault] MPOL_DEFAULT メモリポリシーを使って指定されたプログラムを実行しま す。これはデフォルトメモリポリシーです。 10-6 SUSE Linux Enterprise Real Time Linux User’s Guide v[iew] 指定したセグメントの現在のメモリポリシー設定を示します。 mempolicy オプションで使うことができる追加のオプションを以下に示します。 --size=SIZE -s SIZE バイトでセグメントの大きさを指定します。 --offset OFFSET -o OFFSET 既存の部分のスタートからバイトでオフセット値を指定します。この値はペ ージサイズの倍数に切り上げられます。 もし –s オプションが同時に指定さ れるなら、OFFSET+SIZE の合計はセグメントの全体の大きさかそれ以下でなく てはなりません。 --user=USER -u USER 共有メモリセグメントの所有者のログイン名を指定します --group=GROUP -g GROUP セグメントへのグループアクセスが可能であるグループの名前を指定します。 --mode=MODE -m MODE 共有メモリセグメントへのアクセスを決定しているパーミッションのセット を指定します。8進数でパーミッションを指定しなくてはなりません;デフ ォルトモードは0644です。 --strict -S もしセグメントレンジのページが現在適用されている指定されたメモリポリ シーに従わないなら、エラーを出力します。 --touch -T 指定された範囲のそれぞれのページに touch (read) を起こし、素早くメモリ ポリシーを実施します。 デフォルトで、アプリケーションがこれらのエリア にアクセスして、ページフォルトを発生させ実メモリを割り当てるように、 ポリシーが適用されます。 keyアーギュメントは共有メモリセグメントのユーザーが選んだ識別子を表します。 この識別子は整数あるいは既存のファイルに関係する標準的なパス名であり得ます。 10-7 SUSE Linux Enterprise Real Time Linux User’s Guide パス名が与えられるとき、ftok(key,0)がshmget(2)呼び出しのためにキーパラメー タとして使用されるでしょう。 --tmpfs=FNAME / -t FNAME キーの代わりに tmpfs ファイルシステムファイル名を指定するために使うことができ ます。この部分のファイル属性を設定、変更するために-u, -g と -mのオプションが使 えます。 Shmconfigの他のオプションは3章の「shmconfig コマンド」あるいは man page を参 照してください。 もし numactl(8)がシステムで利用可能なら、それは同様に NUMA メモリポリシー を設定するために使うことができます。 システムコール 以下のシステムコールが利用できます。 これらの呼び出しのいずれでも作成するとき は、numaif.hヘッダーファイルが含まなくてはなりません。詳細は man page を参照 してください。 set_mempolicy(2)は、タスク規模のメモリポリシーを現在のプロセスにセットします。 get_mempolicy(2)は、現在のプロセスあるいはメモリアドレスのメモリポリシーを受 けとります。 mbind(2)は、共有メモリを含んだアドレス空間の範囲に、ポリシーをセットします。 ライブラリ関数 ライブラリ、/usr/lib64/libnuma.so、は NUMA サポートへのシンプルなプログラミング インタフェースを提供します。 基本的な NUMA システムサービスコールには、種々の タイプの NUMA メモリポリシーとノードサポートルーチンと代替のインタフェースを含ん でいます。 詳細は numa(3) man page を参照してください。 情報ファイル NUMA がカーネルで使用可能であるとき、それぞれのノードがサブディレクトリ /sys/devices/system/node/node#でインフォメーションファイルのセットを持っ ています、そして # はノード番号(0,1, 2 etc.)です。 これらのファイルは下にリスト されます。 CPUmap 例えばこのノードでCPUの16進法のビットマップを示します。 > cat /sys/devices/system/node/node3/CPUmap numastat 10-8 SUSE Linux Enterprise Real Time Linux User’s Guide ディスプレイがノードのhit/missの統計値を出力します。次のセクションに 示されるフィールドの説明があります。 meminfo ノードのfree, used, high, low と all memory の合計を含めたメモリ統計値 を示します。 CPU# 例えば以下の例は、ノードと結び付けられるCPUデバイスファイルです。 $ ls -l /sys/devices/system/node/node3/CPU3 lrwxrwxrwx 1 root root 0 jan 21 03:01 CPU3 ->../../../../devices/system/CPU/CPU3 numastat を使っている NUMA Hit/Miss 統計値 numastat はすべてのノードの /sys/ devices/system/node/node#/numastat ファ イルからのインフォメーションを結合するスクリプトです: $ numastat node 3 node 2 node 1 node 0 numa_hit 43674 64884 79038 81643 numa_miss 0 0 0 0 numa_foreign 0 0 0 0 interleave_hit 7840 5885 4975 7015 local_node 37923 59861 75202 76404 other_node 5751 5023 3836 5239 numa_hit ノードで作られ、成功したメモリアロケーションの数。 numa_miss ノードで作ることができなかった、しかしその代わりに別のノードに割り当てられた、 メモリアロケーションの数。 numa_foreign ノードからメモリを割り当て損ねたが、その代わりにここに示すアロケーション数が このノードから割り当てた。 interleave_hit このノードでの作成が成功したインタリーブされたメモリアロケーションの数。 local_node ローカルなノードから作られたメモリアロケーションの数。 other_node ローカルでないノードに作られたメモリアロケーションの数。 10-9 SUSE Linux Enterprise Real Time Linux User’s Guide kdb サポート 以下の kdb コマンドはNUMA をサポートするために加えられ、修正されました。 カ ーネルが、 NUMA サポートで構成されるときだけ、この追加のサポートを使用でき る事に注意してください。 memmap [node_id] システムでのすべてのページのため、あるいはただ指定されたノードだけの ためのインフォメーションを出力します task 追加されたタスク構造体フィールドのmempolicy と il_next を出力します。 mempolicy 指定されたaddr のmempolicy 構造体の情報を出力します。 pgdat [node_id] 指定されたノードあるいは node_id が指定されないなら、ゾーン0の zonelists をデコードします。 vmp -v 追加されたバーチャルメモリエリアのための mempolicy インフォメーショ ンを出力します。 パフォーマンスガイドライン 特定の NUMA ノードへアプリケーションをバインドしてページアロケーションが行 われ、そしてそのCPUがシールドされている状態が、NUMA システムに関する最も効 率的な方法です。 タスクを動作するためのガイドラインと共有メモリエリアが後述されます。 タスク間の NUMA メモリポリシー 通常、MPOL_BINDポリシーがタイムクリティカルアプリケーションのために最も有用 なポリシーです。それはあなたにページアロケーションを決定論的にノード指定させ る唯一のポリシーです。もしメモリアロケーションが指定されたノードあるいは指定 されたノードのセットから割り当てることができないなら、プログラムは SIGKILL シグナルで終了させられるでしょう。 MPOL_BIND メモリポリシーとCPUシールドとバイアスを組み合わせることによって、 シールドCPUを作成することができます。そしてアプリケーションはそのアプリケ ーションのためのページがただシールドCPUの NUMA ノードから割り当てられ、 シールドCPUの上で実行することが出来ます。 既に存在する共有テキストページとコピーオンライトのデータページは、必ずしもロ ーカルではないことに注意を払ってください、コピーオンライトのデータページは、 書き込まれた途端に、データページがローカルになるでしょう。 10-10 SUSE Linux Enterprise Real Time Linux User’s Guide run(1)コマンドは MPOL_BIND メモリポリシーのシールドCPUの上でアプリケー ションを始めるために使うことができます。実行し始めた後mpadvise(3)と set_mempolicy(2)あるいは NUMA ライブラリファンクション・コールを行っても、 すでにアプリケーションのアドレス空間に存在しているページの NUMA メモリポリ シーは後の変更では影響を受けせん。その代わりにrunコマンドを使うことで、アプリ ケーションはできるだけ早くそのCPUアフィニティと NUMA メモリポリシーを設 定することができます。 次の例はメモリアロケーションがCPU2に位置する NUMA ノードからだけで割り 当てられるという状態で、 MPOL_BIND メモリポリシーでシールドCPUの上でアプ リケーションを始めるためにどのようにran(1)コマンドバイアスと mempolicy オプ ションを使うべきか示します: $ shield -a 2 $ run -b 2 -M b my-app シールドCPU とshield(1) コマンドの詳細は2章とshield(1) man ページを参照して ください。 共有メモリセグメント 一般的には、MPOL_BIND メモリポリシーが、共有メモリセグメントのために奨励さ れています。 共有セグメントの NUMA メモリポリシーは mbind(2)システムサービス コール、あるいは shmconfig(1)ユーティリティーで指定することができます。 もし共有メモリセグメントが複数のCPUから参照されるなら、メモリアクセスパフ ォーマンスを最大にするために共有メモリエリアの異なった部分のために異なった MPOL_BIND メモリポリシー属性を指定することが可能です。 例として、共有されたメモリセグメントの下半分に書き込む「低い」アプリケーショ ンと、同じ共有されたメモリセグメントの上半分に書き込む「高い」アプリケーショ ンを考えてください。 1. ”123”のキー値で共有メモリセグメントを作ります。セグメントの下半分をCPU2 の NUMA ノードでMPOL_BIND メモリポリシーを使い、セグメントの上半分をCP U3のNUMAノードで、MPOL_BIND メモリポリシーを使うように、ページアロケー ションします。 $ shmconfig -s 0x2000 123 $ shmconfig -s 0x1000 -M b=2 123 $ shmconfig -o 0x1000 -M b=3 123 2. CPU 2 とCPU3の両方をシールドします。 $ shield -a 1,2 3.CPU2のメモリポリシーが、MPOL_BINDのメモリアロケーションを行った状態で、 10-11 SUSE Linux Enterprise Real Time Linux User’s Guide CPU2上で 「低い」アプリケーションを実行し、CPU3のメモリポリシーが、MPOL_BINDのメモ リアロケーションを行った状態で、CPU3で「高い」アプリケーションを実行します。 $ run -b 2 -M b low $ run -b 3 -M b high コンフィグレーション Opteron プロセッサだけが NUMA アーキテクチャを持っています。 K8_NUMA カー ネルパラメータが NUMA カーネルサポートのために必要です。 カーネルコンフィギュレーションGUI のProcessor Type and Featuresオプションとプリ インストールされた SUSE Linux Enterprise Real Time x86_64 カーネルは、デフォルト で使用可能です. NUMA システムで、NUMA カーネルサポートをこうちくしていても、ブート時に numa=off指定されると、停止することができるブートオプションがあることに注意し てください。 これはそのノードに属しているすべてのCPUがすべて同じノードとし て一緒にシステムを構成するでしょう。 それは、ビルドされない NUMA サポートノ ードからサポートされないカーネルへ、どちらのケースにノードがないフラットなメ モリシステムがあるか、そして NUMA ユーザインタフェースが、呼ばれるとき、ど こでエラーを返すかに関して動作が異なります。 Opteron システムで K8_NUMA 使用可能なカーネルを使うとき、次のハードウェアが 推奨されます: z メモリモジュールがそれぞれのCPUのためにシステムにインストールされるこ と。 さもなければ、ローカルなメモリモジュールがないCPUは、すべてのメモ リにアクセス出来ること、それ間接的に他のメモリモジュールにアクセスしなく てはならないため、劣悪なシステムパフォーマンスのでしょう。 z BIOS によってインタリーブをサポートされたハードウェアサポートしているど んなメモリモジュールでも BIOS で停止されるべきです。 もしBIOSによる停止 が、使用できない場合には、 K8_NUMA 使用可能なカーネルの NUMA サポー トは、一つの NUMA ノードがシステムにすべてのCPUを含むという結果にな って、停止されるでしょう。 10-12 SUSE Linux Enterprise Real Time Linux User’s Guide 11 カーネルのコンフィグレーション及び構築 この章では、SUSE Linux Enterprise Real Time カーネルをどのようにしてコンフィグして構 築するのかについての情報を提供します。 イントロダクション SUSE Linux Enterprise Real Time カーネルは/boot ディレクトリ内に位置します。実際のカ ーネル・ファイル名はリリースからリリースにおいて変化しますが、一般的にそれらは以下の 形式を持ちます。 vmlinuz-kernerlversion-SLERT-x.x[-flavor] kernelversion Linux カ ー ネ ル ・ ソ ー ス ・ コ ー ド の 公 式 バ ー ジ ョ ン で 、 そ の 上 に SUSE Linux Enterprise Real Time カーネルは基づいています(0.8 のサフィックスを含みま す)。 x.x SUSE Linux Enterprise Real Time カーネル・リリースのバージョン番号です。 flavor 特定のカーネルが提供する追加的カーネルの機能を指定するオプション的キーワ ードです。 カーネルはシステムがブートされるたびにメモリ内へロードされます。それは、システムの基 本的機能を実行する本質的コードの核心です。システムが稼動中はいつもカーネルは物理メ モリ内にとどまります(それは多くのユーザ・プログラムのようにスワップ・イン及びスワップ・ア ウトされません)。 カーネルの正確なコンフィグレーションは以下のものに依存します。 ・ システムの稼働時間動作を定義するチューニング可能パラメータの大きな数。 ・ オプション的デバイス・ドライバ及びロード可能なモジュールの数。 カーネル・コンフィグレーションまたは再コンフィグレーションは、1 つまたはそれ以上のこれら のカーネル変数を再定義するプロセスで、そして新しい定義にしたがって新しいカーネルを生 成することです。 一般的に、多くのシステムに適切なチューニング可能パラメータ及びデバイス・ドライバと共に、 11-1 SUSE Linux Enterprise Real Time Linux User’s Guide 供給されるカーネルは生成されます。しかし、特定の目的のためにカーネル・パフォーマンス を最適化するためにチューニング可能パラメータのいくつかを変更したい場合、カーネルの 再コンフィグを選択します。 チューニング可能パラメータを変更した、またはハードウェア・コンフィグレーションを修正した 後、カーネルを再構築する、インストールする、そしてリブートする必要があります。 ccur-config を使用してのカーネルのコンフィグレーション SUSE Linux Enterprise Real Time 製品は 3 つの既構築カーネルを含みます。カーネルは それぞれそれらの“-flavor”サフィックスで区別されます。以下の flavor が定義されています。 generic(サフィックスが無い) 一般的カーネル。このカーネルは最適化されており、そして最良の全般的パフォー マンスを提供しますが、しかしそれは NightStarRT ツールを完全に利用するのに必 要な機能を欠いています。 trace trace カーネルです。それは一般的カーネルの全ての機能をサポートし、さらに NightTracRTe パフォーマンス分析ツールのカーネル・トレーシング機能でのサポー トを提供するので、このカーネルは多くのユーザに推奨されます。 debug デバッグ・カーネルです。このカーネルはトレース・カーネルの全ての機能をサポー トし、さらにカーネル・レベルでのデバッグのサポートを提供します。ドライバの開発 者またはシステム問題をデバッグしようとするユーザに、このカーネルは推奨され ます。 bigmem 4GBを越える一般的なカーネルと同じ特徴を持っている最適化されたカーネル。 trace_bigmem このカーネルは bigmem カーネルの特徴のすべてをサポートして、NightTrace RT パフォーマンス分析ツールのカーネル追跡のサポートを提供します。 debug_bigmem これは trace_bigmem カーネルの特徴のすべてをサポートして、カーネルのデバ ッグをサポートします。 11-2 SUSE Linux Enterprise Real Time Linux User’s Guide それぞれの既構築 SUSE Linux Enterprise Real Time カーネルは、カーネル・コンフィグレー ションの全ての詳細を取り込む結合するコンフィグレーション・ファイルを持ちます。これらのフ ァイルはカーネル・ソース・ツリーの configs ディレクトリ内に位置します。3 つの既構築カーネ ルにおいて、コンフィグレーション・ファイルは以下のように名付けられます。 i386(32 ビット)アーキテクチャ generic kernel dynamic.config trace kernel trace-dynamic.config debug kernel debug-dynamic.config bigmem kernel bigmem-dynamic.config trace_bigmem kernel trace_bigmem-dynamic.config debug_bigmem kernel debug_bigmem-dynamic.config x86_64(64 ビット)アーキテクチャ generic kernel dynamic-x86_64.config trace kernel trace-dynamic-x86_64.config debug kernel debug-dynamic-x86_64.config 3 つの既構築カーネルの 1 つに一致するカーネルをコンフィグしそして構築するためには、カ ーネル・ソース・ツリーの最上位を cd し、そして ccur-config (8)ツールを走らせなければなり ません。 注 ccur-config スクリプトはルートとして、そしてグラフィカル・モード内のシステムで(例: ラン・ レベル 5)、または有効な DISPLAY 変数セットで走らされなければなりません。 以下の例は、SUSE Linux Enterprise Real Time トレース・カーネルのコンフィグレーション に基づいている新しいカーネルの構築においてカーネル・ソース・ツリーをコンフィグしていま す。コンフィグレーション・ファイルの“.config”サフィックスは自動的にくっ付けられるので指 定する必要が無いことに注意します。 # cd /usr/src/linux-2.6.16.21-0.8-SLERT-10-8 #./ccur-config trace-dynamic configs ディレクトリ内に常駐する適切なカスタム config ファイルを指定することによって、 ccur-config はカスタマイズされているカーネルにおいても使用することができます。 -k name オプションは新しいフレーバーに名前をつけるために使います、そして -s オプショ 11-3 SUSE Linux Enterprise Real Time Linux User’s Guide ンは configs ディレクトリにコンフィギュレーション・ファイルをセーブします。 例えば: # /ccur-config -s -k test debug-dynamic. SUSE Linux Enterprise Real Time i386 debug-dynamic kernel をベースとして、フレーバ ー の 拡 張 子 と し て -test で カ ー ネ ル の 構 成 を 設 定 し 、 コ ン フ ィ グ レ ー シ ョ ン フ ァ イ ル を configs/test.config としてセーブします。 ccur-config の実行中に、グラフィカル・コンフィグレーション・インターフェイス(GUI)が提示 され、その中で SUSE Linux Enterprise Real Time カーネルの多くの異なる局面をカスタマ イズすることができます。カーネル・コンフィグレーション GUI の例についてはスクリーン 10-1 を見てください。 File メニューの Save 選択は、変更を保存しそしてプログラムを終了するために選択されなけ ればなりません。どのコンフィグレーション・パラメータも変更しなくとも、カーネルのコンフィグ レーション・ファイルを適切にアップデートするために Save を選択する必要がいずれにせよあ ります。 グラフィカル・コンフィグレーション・ウィンドウ経由で利用可能な設定及びコンフィグレーショ ン・オプションの徹底的なリストについてはこのドキュメントの範囲外ですが、しかしリアルタイ ム・パフォーマンスと関係する多くのチューニング可能なパラメータはこのマニュアル全般に わたって論じられており、また GlossalyB でリストされています。それに加えて、パラメータが 選択される時、そのパラメータについての情報は GUI の別のウィンドウ内に表示されます。 11-4 SUSE Linux Enterprise Real Time Linux User’s Guide 画面 10-1 カーネル・コンフィグレーション GUI カーネルの構築 どのカーネル・コンフィグレーションが使用されているのかに関係なく、結果としてのカーネル は、加えられている“-custom”サフィックスで続いているトップ・レベル Makefile 内で定義さ れているように、現在のカーネル・バージョン・ストリングで続く“vmlinuz”プリフィックスと共に 名付けられます。例として: vmlinuz-2.6.16.21-0.8-SLERT-10-8-custom ccur-config を稼動する前にトップ・レベル Makefile 内で REDHAWKFLAVOR 変数をエデ ィットすることによって、最後のサフィックスを変更することができます。同じカーネル・ソース・ ツリーから複数カーネルを構築する際、既存するカーネルに誤って上書きすることを避けるた めに、サフィックスを変更することが重要です。 注 既構築のカーネルは、予約されたサフィックスを持ちます。よって、サフィックスを“-trace”、 11-5 SUSE Linux Enterprise Real Time Linux User’s Guide “-debug”、または“ ”(空ストリング)に設定するべきではありません。 カーネルのドライバ・モジュールを構築する必要があるなら、ccur-config –c オプションを使 用します(この章の後の“ドライバ・モジュールの構築”のセクションを見てください)。 一度カーネル・コンフィグレーションが完了すれば、適切な make (1)コマンドを発信すること によってカーネルを構築することができます。トップ・レベル Makefile 内には多くのターゲット がありますが、以下のものは特に重要です。 make bzImage スタンドアロンのカーネルを構築する。 make modules カーネル・コンフィグレーション内で指定されているどのカーネル・モジュールも構築 する。 make modules_install 現在コンフィグされているカーネルと結合しているモジュール・ディレクトリの中へモ ジュールをインストールします。このディレクトリの名前は、トップ・レベル Makefile 内で定義されているカーネル・バージョン・ストリングに由来することに注意します。 例 と し て 、 も し も SUSE LINUX ENTERPRISE REAL TIMEFLAVOR が “ -custom ” と 定 義 さ れ て い る な ら 、 結 果 の モ ジ ュ ー ル ・ デ ィ レ ク ト リ は “ /lib/modules/kerne;version-SUSE Linux Enterprise Real Time-x.x-custom”になります。 make install 関連する System .map ファイルと共に/boot ディレクトリの中へカーネルをインスト ールします。 注 新しいカーネルを完全に構築しそしてインストールするためには、これらの Makefile ターゲッ トが整列して発信されなければなりません。 完全なカーネル・コンフィグレーション及び構築セッションの例については、図 11-1 を参照して ください。 11-6 SUSE Linux Enterprise Real Time Linux User’s Guide 図 11-1 完全なカーネル・コンフィグレーション及び構築セッションの例 # cd /usr/src/linux-2.6.16.21-0.8-SLERT-10-8 # ./ccur-config -k test debug-dynamic Configuring version: 2.6.16.21-0.8-SLERT-10-8-test Cleaning source tree... Starting graphical configuration tool... [ configure kernel parameters as desired ] Configuration complete. # make bzImage # make modules # make modules_install # make install [ edit /boot/grub/menu.lst to reference new kernel and reboot ]# make modules_install # make install [ edit /etc/grub.conf to reference new kernel and reboot ] ドライバ・モジュールの構築 既存のカーネルの 1 つまたはカスタム・カーネルいずれかでの使用のためにドライバ・モジュ ールを構築する必要がしばしばあります。 カーネルのドライバ・モジュールを構築するためには、以下の状態が満たされなければなりま せん。 ・ 望まれるカーネルが現在稼動しているカーネルでなければなりません。 ・ カーネル・ソース・ディレクトリは、ccur-config 経由で現在稼動しているカーネルに おいて適切にコンフィグされていなければなりません。 “カーネルの構築”のセクションで述べられている手順を使用してカスタム・カーネルが構築さ れたなら、カーネル・ソース・ディレクトリが既に適切にコンフィグされており、そして ccur_config の稼動は必要が無いことに注意します。 ccur-config への-c オプションはカーネル・ソース・ディレクトリが適切にコンフィグされている ことを確認するために使用することができます。このオプションは稼動しているカーネルを自 動的に検出し、そして稼動しているカーネルに適切に一致させるようにソース・ツリーをコンフ 11-7 SUSE Linux Enterprise Real Time Linux User’s Guide ィグします。 ドライバ・モジュールは稼動しているカーネルでの使用のために適切にコンパイルされます。 注 ccur_config への-c オプションは、カーネル・ソース・ツリーをコンフィグしてドライバ・ モジュールを構築するために意図されているのみで、新しいカーネルを構築する時に は使用されるべきではありません。 コンフィグレーション・パラメータを変更する必要が無い時に ccur_config への-n オプション も指定することができます。-n では、コンフィグレーション GUI は現れず、そしてコンフィグレー ション・カスタマイズは行われません. 前もって構築された SUSE Linux Enterprise Real Time カーネルのカーネルモジュールを 構築する例は、図11-2を見てください。 図 11-2 Pre-Build SUSE Linux Enterprise Real Time カーネルにおけるカーネル・モジ ュールの構築。 # cd /usr/src/linux-2.6.16.21-0.8-SLERT-10-8 # ./ccur-config -c [ Enable the desired driver modules in GUI] # make REDHAWKFLAVOR=-flavor modules [ See make output to locate newly built kernel module] 追加情報 Linuxカーネル・コンフィグレーション及び構築を理解しそして明確にするのに役立つ情報を 提供する利用可能なリソースが多くあります。第一歩として良いものは、インストールされて いるSUSE Linux Enterprise Real Timeカーネル・ソース・ツリーのトップ・レベル内に位置す るREADMEファイルを読むことです。さらに、以下の HOWTOドキュメントがThe Linux Documentation Project の ウ ェ ブ ・ http://www.tldp.org/HOWTO/Kernel-HOWTO.html経由で利用可能です。 11-8 サ イ ト SUSE Linux Enterprise Real Time Linux User’s Guide 12 プラグ可能な認証モジュール (PAM) この章では、ユーザの認証要求のためにアプリケーションが使用するケーパビリティのライブ ラリを通して得られる安全で適切な認証機構を提供する PAM ケーパビリティについて論じま す。 イントロダクション Pluggable Authentication Modules(プラグ可能な認証モジュール)を表す PAM は、認証プ ログラムを再コンパイルする必要が無く、システム管理者が認証ポリシーを設定することを可 能にする方法です。PAM では、コンフィグレーション・ファイルをエディットすることによって、ど のようにモジュールがプログラム内へプラグされるのかを制御します。 ほとんどのユーザはこのコンフィグレーション・ファイルに触れる必用が決してありません。認 証を要求するプログラムをインストールするために rpm (8)を使用する時、通常のパスワード 認証を行うために必要とされる変更をそれらは自動的に行います。しかし、独自のコンフィグ レーションをカスタマイズしたい場合、コンフィグレーション・ファイルを理解しなければなりま せん。 PAM モジュール PAM 標準が定義している 4 つの種類のモジュールがあります。それらは、以下の通りです。 auth おそらく要求する、及びパスワードのチェックのような実際的な認証を提供し、 そしてグループ・メンバーシップのような“信用証明”を設定します。 account 認証が許可されているかを確認するためにチェックします(アカウントが期限切 れしていなく、この日時にユーザがログインすることを許可されている、etc.)。 password パスワードを設定するために使用されます。 session ユーザが認証されてユーザがアカウントを使用するのを許可するのに一度使 用され、ユーザのホーム・ディレクトリをマウントすること、またはユーザのメー ルボックスを利用可能にします。 これらのモジュールはスタックされるので、複数モジュールが使用されます。例として、rlogin は通常少なくとも 2 つの認証方法を利用します。rhosts 認証が成功すれば、接続を許可する 12-1 SUSE Linux Enterprise Real Time Linux User’s Guide のに十分です。もしもそれが失敗したなら、標準的パスワード認証が成されます。 いつでも新しいモジュールを追加することができ、そして PAM 認識アプリケーションはそれら を使用するように生成されます。 サービス PAM を使用するそれぞれのプログラムはそれ独自の“サービス”名を定義します。login プロ グラムはサービス・タイプ login を定義し、ftpd はサービス・タイプ ftp を定義し、そして etc.で す。一般的に、サービス・タイプはサービスにアクセスするために使用されるプログラムの名 前で、(もしも違いがあるとすれば)サービスを提供するために使用されるプログラムではあり ません。 role・ベースのアクセス制御 SUSE Linux Enterprise Real Time における role・ベースのアクセス制御は、PAM を使用し て実行されます。role・ベースのアクセス制御機構の中では、capability.conf(5)ファイル内 で一連の role のセット・アップをします。role は有効な Linux ケーパビリティのセットとして定義 さ れ ま す 。 全 て の 有 効 な Linux ケ ー パ ビ リ テ ィ の 現 在 の セ ッ ト は 、 /usr/include/linux/capability.h カ ー ネ ル ・ ヘ ッ ダ ・ フ ァ イ ル 内 に あ る か 、 ま た は _cap_names[]ストリング配列を使用して見つけることができます。17 章でそれらはより詳細 に説明されています。 一度 role を定義すれば、role はビルディング・ブロックのように動作し、続く role のケーパビリ ティの 1 つとしてそれは使用されます。この方法で新しく定義された role は、以前に定義され た role のケーパビリティを継承します。このケーパビリティの例は以下で述べられています。 更なる情報については、capability.conf (5) man page を見てください。 一度 role を定義すれば、それは capability.conf (5)ファイル内のユーザまたはグループに 割り当てられます。ユーザは、現在のシステム上でログインと共にある有効なユーザに対応 する標準的 Linux ユーザ・ログイン名です。グループは、現在のシステム上で定義されている 有効なグループに対応する標準的 Linux グループ名です。 /etc/pam .d 内のファイルは、ユーザがシステム内へログインするために使用することができ るサービスに対応しています。これらのファイルは pam_capability セッション・ラインを含む ように修正されます(サービス・ファイルへ pam_capability セッションを追加する例は、以下 の“例”セクション内で説明されています)。例として、/etc/pam.d/login ファイルは、それが 12-2 SUSE Linux Enterprise Real Time Linux User’s Guide telnet 経由でログインをカバーすることから、良い候補です。もしもユーザが修正されていな いサービスを使用してシステム内へログインすれば、特別なケーパビリティ割り当ては行わ れません。 注: もしもケーパビリティが使用されれば、安全事前措置は su –1 nobody daemon のよう な起動がユーザ nobody においてリストされているケーパビリティのみを daemon に伝える ことを確実にし、そして起動ユーザからの追加的ケーパビリティを伝えないので、 /etc/pam.d/su ファイルは修正されるべきです。 /etc/pam.d 内のファイルへ pam_capability セッション・ラインを供給する時、以下のオプシ ョンを指定することができます。 conf=conf_file コンフィグレーション・ファイルの位置を指定します。もしもこのオプションが指定され ていなければ、デフォルトの位置は/etc/security/capability.conf になります。 debug syslog 経由でのデバッグ情報をログします。デバッグ情報は syslog authpriv クラ ス内でログされます。一般的に、このログ情報は/var/log/secure ファイル内に集 められます。 例 以下の例は/etc/pam .d/login へのセッション・ラインの追加を説明します。 注: i386 システム上の PAM ファイルへのパスは/lib/security です。 X86_64 システム上のパスは/lib64/security です。 1. /etc/security/capability .conf ファイル内で定義されている role を、telnet(1)経由 でシステムへログインするユーザに割り当てることを可能にし、/etc/pam.d/login へ 以下の行を追加します。 session required /lib/security/pam_capability.so 2. /etc/security/capability .conf ファイル内で定義されている role を、ssh(1)経由で システムへログインするユーザに割り当てることを可能にし、/etc/pam .d/sshd へ 以下の行を追加します。 session required /lib/security/pam_capability.so 12-3 SUSE Linux Enterprise Real Time Linux User’s Guide 3. /etc/security/capability .conf ファイル内で定義されている role を su(1)経由で代 わりのユーザに割り当てることを可能にし、そしてこれらの代わりのユーザが su(1) の起動元から不適切なケーパビリティを継承しないことを確実にし、/etc/pam.d/su へ以下の行を追加します。 session required /lib/security/pam_capability.so 4. ssh ユーザに/etc/security 内に位置するものと異なる capability .conf ファイルか らユーザの role 定義を取得させ、/etc/pam .d/sshd へ以下の行を追加します。 session required /lib/security/pam_capability.so conf=/root/ssh-capability.conf よって、/root/ssh-capability .conf ファイル内で定義されている role は ssh 経由 でログインしているユーザに適用されます。 ケーパビリティの定義 capability .conf ファイルは、定義されそしてユーザ及びグループへ割り当てられる role に ついての情報を提供します。ファイルには 3 つの種類のエントリがあります。role、ユーザ、そ してグループです。 role role は有効な Linux ケーパビリティが定義されたセットです。全ての有効な Linux ケーパビリティの現在のセットは、/usr/include/linux/capability.h カー ネル・ヘッダ・ファイル内にあるか、または cap_from_text(3) man page 内で 説明されている_cap_names[]ストリング配列を使用して見つけることができ ます。ケーパビリティについては 17 章内で完全な詳細で説明されています。さ らに、以下のケーパビリティキーワードがディフォルト定義されています。 all 全てのケーパビリティ(cap_setcap を除く) cap_fs_mask ファイル・システムと関係する全てのケーパビリティ none ケーパビリティが全く無い 名前が示唆するように、様々なシステム・ユーザ及びグループが行う必要があ る動作に基づいて異なる role が定義することが予期されます。 capability .conf ファイル内の role・エントリのフォーマットは: role 12-4 rolename capability_list SUSE Linux Enterprise Real Time Linux User’s Guide ケーパビリティリスト(capability list)内のエントリは以前に定義された role を 参照することができます。例として、ファイル内で basic と呼ばれる role を定義 することができ、そして続く role のケーパビリティリスト内のケーパビリティの 1 つとしてこの role を追加することができます。ケーパビリティリストは、ユーザ の継承可能なセット内でオンにされる空白またはカンマで区切られているケー パビリティのリストであることに注意します。 ユーザ ユーザは、現在のシステム上でのログインで有効なユーザに対応する、標準 的 Linux ユーザ・ログイン名です。現在のシステム上で有効なユーザに対応し ていないユーザ・エントリ(getpwnam (3)が確認します)は無視されます。 capability .conf ファイル内のユーザ・エントリのフォーマットは: user username rolename 特別なユーザ名“*”は、リストされているどのユーザにも一致しないユーザ、ま たはリストされているグループ内でメンバーシップを持つユーザに、デフォルト・ role を割り当てるのに使用することができます。 user * default_rolename グループ グループは、現在のシステム上で定義されている有効なグループに対応する 標準的 Linux グループ名です。現在のシステム上で有効なグループに対応し ないグループ・エントリ(getpwnam (3)が確認します)は無視されます。 capability.conf ファイル内のグループ・エントリのフォーマットは: group groupname rolename 例 1. 以下の例は、ルートにおおよそ等しい管理者 role(admin)をセット・アップします。 role admin all 2. 以下の例は、継承可能ケーパビリティセットへ sys_boot 及び sys_time を追加するデス クトップ・ユーザ・role をセット・アップします。 role 12-5 desktopuser cap_sys_boot ¥ SUSE Linux Enterprise Real Time Linux User’s Guide cap_sys_time 3. 以下の例は、以前に生成されたデスクトップ・ユーザ・role を使用してパワーユーザ・ユー ザ・role をセット・アップします。 role poweruser desktopuser¥ cap_sys_ptrace¥ cap_sys_nice¥ cap_net_admin 4. ユーザへ desktopuserrole を割り当てるために、capability .conf ファイルの USERS セクション内へ以下のものを入力します。 user joe desktopuser 5. グループへ poweruserrole を割り当てるために、capability .conf ファイルの GROUPS セクション内へ以下のものを入力します。 group hackers poweruser 実行の詳細 以下のアイテムは、PAM ケーパビリティの完全な実行における要求を取り扱います。 ・ Pam_capability は、exec ( )システムコールにわたってのケーパビリティを継承するため に稼動しているカーネルが修正することを要求します。カーネル・パッチでパッチされ、このモ ジュールで出荷されるカーネルは、カーネル・コンフィグレーション GUI 上の General Setup 下でアクセス可能な INHERIT_CAPS_ACROSS_EXEC コンフィグレーション・オプションを 使用して、ケーパビリティ継承を許可することができます(このガイドの“カーネルのコンフィグ レーション及び構築”を参照してください)。全ての SUSE Linux Enterprise Real Time カーネ ルにはデフォルトでこのオプションが許可されています。 ・ ssh で pam_capability ケーパビリティを使用するには、/etc/ssh/sshd_config ファイル には以下のオプション・セットがなければなりません。 UsePrivilegeSeparration no 12-6 SUSE Linux Enterprise Real Time Linux User’s Guide 13 デバイス・ドライバ この章では SUSE Linux Enterprise Real Time 下のユーザ・レベル及びカーネル・レベルの デバイス・ドライバに関係する事項を扱います。リアルタイム・パフォーマンス事項と同様にラ イティング・デバイス・ドライバを簡易化する、SUSE Linux Enterprise Real Time に追加され たケーパビリティについての情報もそれは含みます。Linux ベースのデバイス・ドライバをどの ように書くかの事前知識が前提とされます。 PCI-to-VME ブリッジ・デバイスへの SUSE Linux Enterprise Real Time のサポートについて の情報は、14 章“PCI-toVME サポート”内にあります。 デバイス・ドライバの種類の理解 SUSE Linux Enterprise Real Time 下の単純なユーザ・レベル・デバイス・ドライバを書くこと は可能です。ユーザ・レベル・ドライバは IO 空間へアクセスしてデバイス・レジスタをリードしそ してライトすることが可能で、そしてプログラムされている IO オペレーションを開始します。ス ケルトン・カーネル・ドライバの助けで、ユーザ・レベル・ドライバも割り込みの受理の際、アク ションを開始することができます。ユーザ・レベル・ドライバ内のシグナル・ハンドラーを割り込 みルーチンにくっ付けることを可能にする機能をサポートすることによって、これは成されます。 割り込みの取り扱い、及びユーザ・レベル・プロセスへの信号の送信のためのサンプル・カー ネル・ドライバ・テンプレートの位置については、この章の後の“カーネル・スケルトン・ドライ バ”のセクションを参照してください。 Linux 下で DMA IO オペレーションを行うユーザ・レベル・ドライバを書くことは実際的ではあり ません。ユーザ・レベルからの DMA オペレーションを妨げるいくつかの問題があります。例と して、ユーザ空間バッファの物理アドレスを確認するためにサポートされている方法は現在あ りません。カーネル・レベル・デバイス・ドライバは、IO オペレーションにおいて DMA を利用す るデバイスのために使用されるべきです。 ユーザ・レベル・デバイス・ドライバの開発 以下に続くセクションでは、SUSE Linux Enterprise Real Time 下でユーザ・レベル・デバイ ス・ドライバを書くことに影響する SUSE Linux Enterprise Real Time オペレーティング・シス テムの特質について説明します。 PCI リソースへのアクセス ブート・プロセス中、PCI バス上のデバイスは自動的にコンフィグされ、それらの割り込みが 13-1 SUSE Linux Enterprise Real Time Linux User’s Guide 割り当てられ、そしてデバイス・レジスタがメモリ・マップされている IO オペレーション経由でア クセス可能なメモリ領域内へとそれらのレジスタはマップされます。これらのメモリ領域はベー ス・アドレス・レジスタ(BAR)として知られています。1 つのデバイスは最大 6 つの BAR を持 つことができます。BAR の内容はデバイスにとても依存します。この情報については、デバイ スのマニュアルを調べます。 PCI デバイスのレジスタをマップするのに必要とされるコードを簡易化する、/proc/bus 内に 位置する PCI リソース・ファイル・システムを SUSE Linux Enterprise Real Time はサポート します。このファイル・システムは、mmap (2)を使用してプログラムのアドレス空間の中へマ ップすることができるメモリ領域を表す BAR ファイルを提供し、デバイスと結合している物理 アドレスを知る必用無く、デバイスへのアクセスを提供します。PCI BAR ファイル・システムも、 デバイスの PCI コンフィグ空間をリードしライトするのに使用することができる config-space ファイルを提供します。config-space ファイルの最初の 64 バイトは PCI 仕様によって定義さ れています。残りの 192 バイトはデバイスのベンダー特定です。 それぞれの PCI ハードウェア・デバイスはそれとベンダーID 及びデバイス ID を結合させてい ます。これらは固定されている値で、時間またはシステム間において変化しません。ブート時 の PCI デバイスの動的コンフィグレーションのため、ドメイン、バス、スロット、そして関数の数 は一度システムがブートされれば固定されたままになりますが、基礎となるハードウェアによ ってシステム間で変化し、ボードでさえ、それぞれのシステム内の同じ PCI バス・スロット内へ プラグされているように見えます。/proc/bus/pci 及び BAR ファイル・システム内のパスは、 カーネルが割り当てるドメイン、バス、スロット、そして関数の数に起因しており、そしてホス ト・システムの物理ハードウェア・レイアウトから影響されます。異なるスロット内へボードを物 理にプラグする、システムへデバイスを追加する、またはシステム BIOS への修正のような変 更は、特定のデバイスに割り当てられているバス及び/またはスロット数を変更します。 以下で説明されている PCI BAR スキャン・インターフェイスは、特定のデバイスと結合するバ ー・ファイルを見つける方法を提供します。これらのインターフェイス無しでは、これらの BAR ファイル・パスのハードウェア依存性によって、ユーザ・レベル・デバイス・ドライバのプログラ ミングをどこか不便にします。なぜなら、ドライバはその BAR ファイルへのアクセスを取得す るために適切なデバイスのスロット・アドレスの位置を見つけなければならないからです。 BAR ファイル・システム、固定されているベンダーID、そしてデバイス ID 値におけるライブラ リ・インターフェイスの使用によって、現在 PCI デバイスと結合している他の値を取得すること ができます。そのディレクトリ内のそれぞれの BAR ファイルについての情報と同様に、デバイ 13-2 SUSE Linux Enterprise Real Time Linux User’s Guide スにおける BAR ファイル・ディレクトリ・パスをこれらは含みます。それはさらに、ベンダー、デ バイス、クラス、サブクラス、IRQ 番号(もしも割り当てられていれば)、そしてドメイン、バス、 スロット、そしてそれぞれのデバイスに関連する関数の数における ID を返します。 PCI BAR スキャン・インターフェイス 以下に続くセクションでは、PCI BAR スキャン・インターフェイスを説明します。 ライブラリ関数は反復的です。システムが望まれるデバイス・タイプのインスタンス以上のも のを持つなら、これらのライブラリ関数は複数回呼ばれなければなりません。システム内の 全てのマッチング・デバイスのカウントを返す 1 つの関数が提供されています。他の関数は、 検索規準にマッチするデバイスにおいて反復的に情報を返します。/usr/include/pcibar .h 内で定義されている bar_context タイプ内で、デバイス情報は返されます。この構造は bar_scan_open への呼び出しで生成されます。複数スキャンは同時にアクティブになること ができ、それぞれユニークな bar_context を持ちます。 インターフェイスは以下のように手短に説明されます。 bar_scan_open PCI デバイスの新しいスキャンを開始します。 bar_scan_next 次のマッチング PCI デバイスを取得します。 bar_device_count アクティブ・スキャンに残っているマッチング・デバイスの数を返します。 bar_scan_rewind スキャンをリスタートします。 bar_scan_close アクティブ・スキャンを閉じ、そして結合しているメモリを開放します。 free_pci_device 位置が確認されたデバイスと結合する全ての割り当てられたメモリを開放 します。 これらのインターフェイスを使用するには、アプリケーションを libccur_rt ライブラリでリンクし なければならないことに注意します。 gcc [options] file -lcuur_rt PCI デ バ イ ス 情 報 を 調 べ る こ れ ら の 関 数 の 使 用 を 説 明 す る 例 は 、 /usr/share/doc/ccur/examples/pci_barscan .c として提供されています。 13-3 SUSE Linux Enterprise Real Time Linux User’s Guide bar_scan_open (3) この関数は PCI デバイスの検索において初期コンテキストを生成するのに使用されます。返 る bar_context は/usr/include/pcibar .h 内で定義される不透明なポインタ・タイプで、それ は反復インターフェイスにおいて状態データを示します。その値は次の呼び出しに続いて提 供されなければなりません。bar_scan_next、bar_device_count、bar_scan_rewind、及 び bar_scan_close です。 概要 #include <linux/pci_ids .h> #include <pcibar .h> bar_context bar_scan_open (int vendor_id , int device_id) ; 引数は以下のように定義されます。 vendor_id /usr/include/linux/pci_ids .h 内で定義されているベンダーID 値、または特 別値 ANY_VENDOR です。ANY_VENDOR はホスト・システム上の全てのデ バイスにおける全ての vendor_id 値に一致します。 device_id /usr/include/linux/pci_ids .h 内で定義されているデバイス ID 値、または特 別値 ANY_DEVICE です。ANY_DEVICE はホスト・システム上の全てのデバ イスにおける全ての device_id 値に一致します。 エラー状態については man page を参照してください。 bar_scan_next (3) この関数は次に一致する PCI デバイスが見つかった際に struct pci_device オブジェクトへの ポインタを返します。 概要 #include <linux/pci_ids .h> #include <pcibar .h> 13-4 SUSE Linux Enterprise Real Time Linux User’s Guide struct pci_device * bar_scan_next (bar_context ctx) ; 引数は以下のように定義されます。 ctx bar_scan_open が返すアクティブ bar_context です。 これ以上利用可能な一致するデバイスが無い場合、この関数は NIL_PCI_DEVICE を返し、 そして errno をゼロに設定します。エラー状態については man page を参照してください。 bar_device_count (3) この関数は、アクティブ・スキャン内に残っている処理されていないデバイスの数を返します。 bar_scan_open または bar_scan_rewind への呼び出し後に即呼び出された場合、これは 指定されている vendor_id 及び device_id において一致するデバイスの全体数です。この値 は bar_scan_next へのそれぞれの呼び出しで 1 減少されます。 概要 #include <linux/pci_ids .h> #include <pcibar .h> int bar_device_count (bar_context ctx) ; 引数は以下のように定義されます。 ctx bar_scan_open が返すアクティブな bar_context です。 成功した場合、bar_scan_next へ続く呼び出しによって返されるレポートされていないデバ イスの数の非マイナス・カウントを、この関数は返します。エラー状態については man page を見てください。 bar_scan_rewind (3) この関数は、bar_scan_open への最初の呼び出し後即にそれがあった状態へと指定され ている bar_context を再設定します。 概要 #include <linux/pci_ids .h> #include <pcibar .h> 13-5 SUSE Linux Enterprise Real Time Linux User’s Guide void bar_scan_rewind (bar_context ctx) ; 引数は以下のように定義されます。 ctx bar_scan_open が 返 す ア ク テ ィ ブ な bar_context で す 。 も し も 値 が NIL_BAR_CONTEXT である、または有効な bar_context オブジェクトを示さ ないなら、この呼び出しは無効です。 bar_scan_close (3) この関数は、示されている bar_context と結合する割り当てられている全てのメモリを開放し ます。値 NIL_BAR_CONTEXT は bar_cotext オブジェクトへ割り当てられ、そしてこの呼び 出し後に使用することはもはやありません。 概要 #include <linux/pci_ids .h> #include <pcibar .h> void bar_scan_close (bar_context ctx) ; 引数は以下のように定義されます。 ctx bar_scan_open が返すアクティブな bar_context です。 free_pci_device (3) この関数は、示されている struct pci_device オブジェクトと結合する割り当てられている全て のメモリを開放します。 概要 #include <linux/pci_ids .h> #include <pcibar .h> void free_pci_device (struct pci_device * dev) ; 引数は以下のように定義されます。 13-6 SUSE Linux Enterprise Real Time Linux User’s Guide dev bar_scan_next から取得される有効な struct pci_device カーネル・スケルトン・ドライバ デバイス・ドライバによって扱われなければならない割り込みをデバイスが発信する時、 Linux は割り込みへユーザ・レベル・ルーチンをくっ付ける方法を持たないため、ユーザ・レベ ルでデバイス・ドライバを完全に構築することは可能ではありません。しかし、デバイス割り込 みを扱い、そしてユーザ・レベル・ドライバを走らせているユーザ・レベル・アプリケーションへ のシグナルを発信する単純なカーネル・デバイス・ドライバを構築することは可能です。シグ ナルはプログラムの実行に非同期にデリバーされ、そしてコードのクリティカル・セクションの 間にシグナルはブロックされる---シグナルはユーザ・レベルの割り込みのように振舞います ---からです。 以下に続くスケルトン・カーネル・レベル・ドライバの例は、デバイス割り込みの発生に、及び シグナルをトリガーする割り込みサービス・ルーチンにおけるコードにどのようにシグナルをく っ付けるのかを示しています。このスケルトン・ドライバにおける完全なコードは、インストー ル さ れ た SUSE Linux Enterprise Real Time シ ス テ ム の デ ィ レ ク ト リ /usr/share/doc/ccur/examples/driver 内にあります。割り込みを扱い、そしてユーザ・レベ ル・プロセスへシグナルを送信する単純なカーネル・レベル・ドライバを書くテンプレートとして、 サンプル・ドライバ sample_mod を使用することができます。 サンプル・ドライバ機能性の理解 サンプル・ドライバはリアルタイム・クロック(rtc)0 を割り込みを生成するハードウェア・デバイ スとして使用します。rtc 0 はリアルタイム・クロック及び割り込みモジュール(RCIM)上の 4 つ のリアルタイム・クロックの 1 つです。クロックはディフォルト定義の精度で 0 へカウント・ダウ ンし、そして再び初めからやり直します。カウントが 0 に達するたびに、割り込みが生成されま す。リアルタイム・クロック 0 におけるセット・アップのいくつかは、モジュールの“init”ルーチン 内で行われ、そこではデバイス・レジスタはメモリ空間内へとマップされ、そしてドライバはこ れらのレジスタへアクセスします。モジュールの“init”ルーチンで示されているコードの最後の セクションは、割り込みルーチンを割り込みベクトルへとくっ付けるコードです。 ****************************************************************************** int sample_mod_init_module(void) { ... dev = pci_find_device(RCIM_VENDOR,RCIM_DEVICE,dev); //find rcim board if (dev == NULL) { //try another id 13-7 SUSE Linux Enterprise Real Time Linux User’s Guide dev = pci_find_device(RCIM_VENDOR,RCIM_DEVICE_ORIG,dev); } if (dev == NULL) { //no rcim board, just clean up and exit unregister_chrdev(major_num,”sample_mod”); return -ENODEV; } ... if ((bd_regs = ioremap_nocache(plx_mem_base, plx_mem_size)) == NULL) return -ENOMEM; ... if ((bd_rcim_regs = ioremap_nocache(rcim_mem_base, rcim_mem_size)) == NULL) return -ENOMEM; ... sample_mod_irq = dev->irq; res = request_irq(sample_mod_irq, rcim_intr, SA_SHIRQ, "sample_mod", &rtc_info); ************************************************************************************ rtc 0 デバイスの完全な初期化は、モジュールの“オープン”方法内で動作しています。この例 においては、デバイスは自動的にセット・アップされており、よって割り込みはデバイスによっ て生成されます。デバイスが開かれる時、rtc 0 と結合している割り込みは許可され、デバイ スは 1 マイクロ秒の精度で 10000 から 0 へとカウントするようにプログラムされ、そしてクロッ クがカウントを始めます。カウントが 0 に達する時、それは割り込みを生成します。 ***************************************************************************** int rcim_rtc_open(struct inode *inode, struct file *filep) { u_int32_t val; if (rtc_info.nopens > 0) { printk(KERN_ERR “You can only open the device once.¥n”); return -ENXIO; } rtc_info.nopens++; if (!rtc_info.flag) return -ENXIO; writel(0, &bd_rcim_regs->request); writel(ALL_INT_MASK, &bd_rcim_regs->clear); writel(RCIM_REG_RTC0, &bd_rcim_regs->arm); writel(RCIM_REG_RTC0, &bd_rcim_regs->enable); writel(RTC_TESTVAL, &bd_rcim_regs->rtc0_timer);//rtc data reg val = RCIM_RTC_1MICRO | RCIM_RTC_START|RCIM_RTC_REPEAT; writel(val, &bd_rcim_regs->rtc0_control); return 0; } ****************************************************************************** カーネル・レベル・ドライバが割り込みを受け取る時、ユーザ・レベル・ドライバはどのシグナ ルが送信されるべきかを指定しなければなりません。ユーザ・レベル・ドライバは ioctl ( )呼び 13-8 SUSE Linux Enterprise Real Time Linux User’s Guide 出しをつくり、それはカーネル・レベル・ドライバの ioctl 方法で扱われます。ユーザ・レベル・ド ライバがこの ioctl ( )関数を呼び出す時、それは、指定されているシグナルにおいてユーザ・ レベル・プロセスが既にシグナル・ハンドラーをセット・アップし、そしてユーザ・レベル・ドライ バがシグナルを受信する準備が今できていることをカーネル・レベル・ドライバへ示します。 呼び出しユーザ空間プロセスはそれがモジュールから受信したいシグナル数を指定します。 “現在の”構造を使用することによって、要求されているシグナル数と結合するプロセス ID を ドライバは記憶しています。“シグナル/プロセス id”ペアはモジュールの rtc_info 構造内に 記憶され、そして以下で述べられている“通知”メカニズムによって後に使用されます。 ************************************************************************** int rcim_rtc_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg) { if (!rtc_info.flag) return (-ENXIO); switch (cmd) { // Attach signal to the specified rtc interrupt case RCIM_ATTACH_SIGNAL: rtc_info.signal_num = (int)arg; rtc_info.signal_pid = current->tgid; break; default: return (-EINVAL); } return (0); } **************************************************************************** 実際の通知はモジュールの割り込みハンドラー内で実行されます。割り込みが rtc 0 から受 け取られる時、この割り込みサービス・ルーチンはそれを要求したプロセスへシグナルを送る かどうかを決定します。もしも rtc_info 構造内に登録されている“プロセス id/シグナル数”が あるなら、指定されているシグナルは関数 kill_proc ( )を使用して対応するプロセスへ送られ ます。 ********************************************************************************** int rcim_intr(int irq, void *dev_id, struct pt_regs *regs) { u_int32_t isr; 13-9 SUSE Linux Enterprise Real Time Linux User’s Guide isr = readl(&bd_rcim_regs->request); writel(0, &bd_rcim_regs->request); writel(ALL_INT_MASK, &bd_rcim_regs->clear); /* Use isr to determine whether the interrupt was generated by rtc 0 only if “rcim” module is not built into the kernel. If “rcim” is active, its interrupt handler would have cleared “request” register by the time we get here. */ // if (isr & RCIM_REG_RTC0) { // Send signal to user process if requested if (rtc_info.signal_num && rtc_info.signal_pid && (kill_proc(rtc_info.signal_pid, rtc_info.signal_num, 1) == -ESRCH)) { rtc_info.signal_pid = 0; } // } return IRQ_HANDLED; } ********************************************************************************** デバイスが閉じられる時、rtc 0 はシャットダウンされます。カウント値は 0 に再設定され、そし てクロックは停止されます。割り込み/シグナル付属はクリアされ、よってもしもさらなる割り 込みが受信されてもさらにシグナルが送信することはありません。 ********************************************************************************* int rcim_rtc_close(struct inode *inode,struct file *filep) { if (!rtc_info.flag) return (-ENXIO); rtc_info.nopens--; if(rtc_info.nopens == 0) { writel(~RCIM_RTC_START, &bd_rcim_regs->rtc0_control); writel(0, &bd_rcim_regs->rtc0_timer); rtc_info.signal_num = 0; rtc_info.signal_pid = 0; } return 0; } ********************************************************************************* ドライバの評価 サンプル・カーネル・モジュールを評価する最良の方法は RCIM ドライバ無しでカーネルを構 築し、そしてサンプル・ドライバをロードすることです。しかし、このモジュールはカーネル内へ 既に構築されている RCIM ドライバと共にまたは無しで動作するように設計されています。 RCIM カーネル・モジュールとサンプル・カーネル・モジュールは同じ割り込みラインを共有し 13-10 SUSE Linux Enterprise Real Time Linux User’s Guide ています。割り込みが発生する時、RCIM の割り込みハンドラーが最初に起動され、そして RCIM ボード上のハードウェア割り込みレジスタがクリアされます。そしてサンプル・モジュー ルの割り込みハンドラーが起動されます。 もしも両方のモジュールがロードされているなら、第 2 のハンドラーが割り込みレジスタがクリ アされていることを確認し、そしてもしも“割り込みソース”へのチェックが行われるなら、ハン ドラーは rtc 0 とは異なるデバイスから割り込みが来たものと認識します。この障害を乗り越え るまで、サンプル・モジュールの割り込みハンドラー内の以下の行が、RCIM とサンプル・モジ ュール両方がロードされる時にコメントされます。 // if (isr & RCIM_REG_RTC0) { . 続くコードは単純なユーザ・レベル・プログラムで、それは RCIM スケルトン・ドライバの割り込 みが発動する時はいつでもこのルーチンが呼び出されるように、どのようにユーザ・レベル・ ドライバがルーチンを取り付けるのかを示します。ルーチン“interrupt_handler”は RCIM の rtc 0 割り込みが発動する時に呼び出されるルーチンです。プログラムが走っているターミナ ルで Ctrl-C とタイプすることで、このプログラムは終了されます。このサンプル・コードも /usr/share/doc/ccur/examples/driver/usersample 内で利用可能であることに注意しま す。 サンプル・モジュールをロードし、そしてユーザ・サンプル・プログラムの稼動を成功させるた めに、RCIM ドライバを使用する全てのアプリケーションは中断されるべきです。 以下は usersample プログラムです。 #include <stdio.h> #include <fcntl.h> #include <signal.h> #include <errno.h> #include "sample_mod.h" static const char *devname = "/dev/sample_mod"; static int nr_interrupts = 0; static int quit = 0; void interrupt_handler (int signum) { nr_interrupts++; if ((nr_interrupts % 100) == 0) { printf ("."); fflush(stdout); 13-11 SUSE Linux Enterprise Real Time Linux User’s Guide } if ((nr_interrupts % 1000) == 0) printf (" %d interrupts¥n", nr_interrupts); } void ctrl_c_handler (int signum) { quit++; } int main() { int fd; struct sigaction intr_sig = { .sa_handler = interrupt_handler }; struct sigaction ctrl_c_sig = { .sa_handler = ctrl_c_handler }; sigaction (SIGUSR1, &intr_sig, NULL); sigaction (SIGINT, &ctrl_c_sig, NULL); if ((fd = open (devname, O_RDWR)) == -1 ) { perror ("open"); exit(1); } if (ioctl (fd, RCIM_ATTACH_SIGNAL, SIGUSR1) == -1) { perror ("ioctl"); exit(1); } printf ("waiting for signals...¥n"); while (! quit) pause(); printf ("¥nhandled %d interrupts¥n", nr_interrupts); close(fd); exit(0); } カーネル・レベル・デバイス・ドライバの開発 後に続くセクションでは、SUSE Linux Enterprise Real Time 下のカーネル・レベル・デバイ ス・ドライバのライティング及び評価に影響を与える SUSE Linux Enterprise Real Time オペ レーティング・システムの特徴を説明します。 ドライバ・モジュールの構築 既存のカーネルまたはカスタム・カーネルのいずれかでの使用におけるドライバ・モジュール の構築についてのインストラクションは、10 章“カーネルのコンフィグレーション及び構築”内 で提供されています。 13-12 SUSE Linux Enterprise Real Time Linux User’s Guide カーネル・バーチャル・アドレス空間 カーネル・サポート・ルーチン vmalloc ( )及び ioremap ( )の動的マッピングのために保管さ れているカーネル・バーチャル・アドレス空間の量がデバイスの要求を満たすのに十分では ない場合があります。ディフォルト値の 128MB は全てのシステムにおいて十分です。例外は、 ioremap ( )されるとても大きなオンボード・メモリを持つ IO ボードがあるものです。例は、そ れに 128MBメモリが取り付けられている時に iHawk システム上にインストールされているV MICリフレクティブメモリ・ボードです。 保管されているカーネル・バーチャル・アドレス空間の 128MBが十分ではない時、この値は チューニング可能な VMALLOC_RESERVE 経由で増大することができ、それはカーネル・コ ンフィグレーションGUI上の General Setup 下に位置します。 リアルタイム・パフォーマンス事項 カーネル・レベル・デバイス・ドライバはカーネル・モードで走り、そしてカーネル自身の拡張で す。よってデバイス・ドライバは、カーネル・コードがリアルタイム・パフォーマンスに影響を与 えるのと同じ形式でシステムのリアルタイム・パフォーマンスに影響を与える能力を持ちます。 以下に続くセクションでは、デバイス・ドライバ及びリアルタイムと関連するいくつかの事項の 高レベルな概要を提供します。 Linux で利用できる多くのオープン・ソース・デバイス・ドライバがありますが、これらのドライ バは、特にリアルタイム・システムにおける適正において、それらと結合する大きな領域のク オリティを持つことが注意されるべきです。 割り込みルーチン 割り込みルーチンは高プライオリティ・タスクの実行にプリエンプトすることができないため、 割り込みルーチンの継続時間はリアルタイム・システムにおいてとても重要です。長い割り込 みルーチンは、それに割り込みが割り当てられている CPU 上を走っているプロセスのプロセ スディスパッチレイテンシィに直接的に影響を与えます。用語プロセスディスパッチレイテンシ ィは、割り込みによって示される外的イベントの発生から外的イベントを待っているプロセス がユーザ・モードでその最初のインストラクションを実行するまでに経過した時間を示します。 どのように割り込みがプロセスディスパッチレイテンシィに影響を与えるのかに関する更なる 情報については、“リアルタイム・パフォーマンス”の章を見てください。 リアルタイム生産環境内でデバイス・ドライバを使用しているなら、割り込みレベルで行われ る動作の量を最小化するべきです。SUSE Linux Enterprise Real Time は、割り込みレベル 13-13 SUSE Linux Enterprise Real Time Linux User’s Guide では動作されるべきではない遅延している処理において、いくつかの異なるメカニズムをサポ ートします。これらのメカニズムによって、プログラム・レベルでのカーネル・デーモンのコンテ キスト内で動作される処理を割り込みルーチンがトリガーすることができます。これらのカー ネル・デーモンのプライオリティはコンフィグ可能であるため、遅延されている割り込み処理よ りもより高いプライオリティ・レベルで高プライオリティ・リアルタイム・プロセスを稼動すること が可能です。これによって、通常、割り込みレベルで稼動されるいくつかの動作よりも高いプ ライオリティをリアルタイム・プロセスが持つことが可能になります。このメカニズムを使用す れば、リアルタイム・タスクの実行はどの遅延されている割り込み動作によっても遅らせられ ることがありません。遅延する割り込みに関する更なる情報については“遅延されている割り 込み機能(ボトムハーフ)”を見てください。 一般的に、デバイスの割り込みルーチンはデバイスと相互作用して以下の種類のタスクを動 作することができます。 ・ 割り込みを承認する。 ・ ユーザへの続く移送のためにデバイスから受け取ったデータを保存する。 ・ 先のオペレーションの完了を待っているデバイス・オペレーションを開始する。 デバイスの割り込みルーチンは、以下の種類のタスクを動作するべきではありません。 ・ 1 つの内的バッファから他へとデータをコピーする。 ・ デバイスにおける内的バッファを割り当てる、または補給する。 ・ デバイスによって使用されている他のリソースを補給する。 これらの種類のタスクは、遅延されている割り込みメカニズムの 1 つを経由してプログラム・レ ベルで動作されるべきです。例として、デバイスにおけるバッファがプログラム・レベルで割り 当てられ、そしてドライバへは内的なフリー・リスト上で維持することができるようにデバイス・ ドライバを設計することができます。プロセスがリードまたはライト・オペレーションを動作する 時、ドライバはフリー・リストをチェックして、入ってくる割り込み往来において利用可能なバッ ファ数が十分であるかどうかを確認します。割り込みルーチンはこのようにして、実行時間に おいてとても高価なカーネル・バッファ割り当てルーチンへの呼び出しの生成を避けます。も しもデバイスがリソースを使い果たし、そして割り込みレベルでこれを認識するのみなら、割り 込みレベルにおいてではなく遅延されている割り込みルーチンの一部として、新しいリソース が割り当てられるべきです。 遅延されている割り込み機能 (ボトムハーフ) それによって機能の実行を遅延することができるいくつかの方法を Linux はサポートします。 機能を直接的に起動する代わりに、後の時間に機能が起動されるように“トリガー”を設定し 13-14 SUSE Linux Enterprise Real Time Linux User’s Guide ます。ボトムハーフと呼ばれるこれらのメカニズムは、そうでなければ割り込みレベルで成さ れていた処理を遅延するために Linux 下で割り込みルーチンによって使用されます。割り込 みレベルからこの処理を取り除くことによって、システムは上記のようなより良い割り込み応 答時間を得ることができます。 割り込みを遅延するための 3 つの選択があります。softirqs、tasklets、そして work キューで す。tasklet は softirqs 上に構築されるため、よってその動作は似ています。work キューは異 なって動作し、そしてカーネル・スレッド上に構築されます。どのボトムハーフを使用するかの 決定は重要です。表 13-1 は種類を要約し、それは下記のセクションで詳細に説明されていま す。 表 13-1 ボトムハーフの種類 ボトムハーフの種類 コンテキスト 順キュー Softirq 割り込み 無し Tasklet 割り込み 同じ taskket に対する Work キュー プロセス 無し(プロセス・コンテキストと してスケジュールされる) Softirqs 及び Tasklets 割り込み処理を遅延する 2 つのメカニズムは、遅延されるコードが内向的でなければならな いかどうかということにおいて、異なる要求を持ちます。遅延可能な機能のこれらの種類は softirq と tasklet です。softirq の単一のインスタンスが同時に複数の CPU 上で実行すること ができるため、softirq は完全に内向的です。tasklet は softirq の特別な種類として実行されま す。違いは、ある tasklet はそれ自身において常に順キューすることです。換言すれば、2 つ の CPU が同時に同じ tasklet コードを実行することはありません。tasklet はそれ自身におい て内向的である必用がないため、この性質により、デバイス・ドライバ内でより単純なコーディ ング・スタイルが可能になります。 標準 Linux では、割り込みハンドラーが割り込みからプログラム・レベルへと移行した後に即、 softirq 及び tasklet は通常、割り込みコンテキストから実行されます。時折、標準 Linux はカ ーネル・デーモンへ softirq と tasklet を遅延します。両方の方法によって、softirq と tasklet は割り込みが許可されて実行することが可能になります。しかし、それらは通常割り込みコン テキストから実行されるため、softirq と tasklet はスリープすることができません。 softirq と tasklet はカーネル・デーモンのコンテキスト内で実行されるのみであることを保証す 13-15 SUSE Linux Enterprise Real Time Linux User’s Guide るオプション(それはデフォルト)で、SUSE Linux Enterprise Real Time は向上されてきまし た。これらのカーネル・デーモンのプライオリティ及びスケジューリング・ポリシーは、カーネ ル・コンフィグレーション・パラメータ経由で設定することができます。これによって、高プライオ リティ・リアルタイム・タスクが遅延されている割り込み機能の動作をプリエンプトするようにシ ステムをコンフィグすることが可能です。 softirq と tasklet は両方 ksoftirqd デーモンによって稼動されています。論理 CPU1 つあたり に 1 つの ksoftirqd デーモンがあります。softirq と tasklet はその実行をトリガーした CPU 上で走ります。よって、もしもハード割り込みがその結合性を特定の CPU へ設定するなら、 対応する softirq または tasklet もその CPU 上で走ります。ksoftirqd のプライオリティはチュ ーニング可能な SOFTIRQ_PRI カーネルによって決定され、それはカーネル・コンフィグレー ション GUI 上の General Setup 下に位置します。デフォルトでは、このチューニングの値はゼ ロに設定されており、それは、ksoftirqd デーモンは最高リアルタイム・プライオリティよりも 1 つ低いプライオリティで SCHED_FIFO スケジューリング・ポリシー下で走ることを示します。 正値にこのチューニングを設定すると、全ての ksoftirqd デーモンに割り当てられるリアルタ イム・プライオリティ値が指定されます。 work キュー work キューは他の遅延されている実行メカニズムです。softirq や tasklet と異なり、標準 Linux は常にカーネル・デーモンのプロセス・コンテキスト内で work キューを処理し、よって、 work キュー内のコードはスリープすることができます。 work キューを処理するカーネル・デーモンは worker スレッドと呼ばれています。worker スレ ッドは常にスレッドの 1 組として、CPU につき 1 つ、それぞれのスレッドが単一の CPU へ連 結されて生成されます。work キュー上の work は CPU ごとに維持されており、そしてその CPU 上の worker スレッドによって処理されています。 カーネルは、ドライバが使用するデフォルトの work キューを提供します。デフォルトの work キューを処理する worker スレッドは events/CPU と呼ばれており、ここで CPU はスレッドが 連結されている CPU です。 オプション的に、ドライバはプライベートな work キューと worker スレッドを生成します。もしも キューイングされているされている work が CPU 集中的またはパフォーマンス・クリティカルな ら、これはドライバにとって有利になります。それはさらにデフォルト worker スレッド上の負荷 を軽くし、そしてデフォルトの work キュー上の残りの work の枯渇を防ぎます。 work が work キュー上に置かれている時、worker スレッドは CPU 上で実行します。よって、 13-16 SUSE Linux Enterprise Real Time Linux User’s Guide もしもハード割り込みがその結合性を特定の CPU へ設定しており、そして割り込みハンドラ ーキューが動作するなら、対応する worker スレッドもその CPU 上を走ります。worker スレッ ドは常に-10 の良い値で生成されていますが、それらのプライオリティは run (1)コマンドで修 正されます。 プライオリティの理解 リアルタイム・CPU が遅延されている割り込みデーモンよりも高いプライオリティで走ることが できるシステムをコンフィグする時、これらのリアルタイム・プロセスがデーモンによって提供 されているサービスに依存するかどうかを理解することは重要です。もしも高プライオリティ・ リアルタイム・タスクが遅延されている割り込みデーモンよりも高いレベルで連結されている CPU なら、デーモンを枯渇される可能性があり、よって、それはどの CPU 実行時間も受信し ません。もしもリアルタイム・プロセスも遅延されている割り込みデーモンに依存するなら、デ ッドロックが生じます。 マルチスレッディング事項 SUSE Linux Enterprise Real Time は単一のシステム内で複数の CPU をサポートするよう に構築されています。全てのカーネル・コードとデバイス・ドライバが、それらのデータ構造が 1 つ以上の CPU 上で同時に修正することを防ぐために書かれなければならないことを、これ は意味します。デバイス・ドライバを複数スレッドするプロセスはデータ構造へのアクセスのプ ロテクトを含み、そしてそれらへの全ての修正が順キューされます。一般的に、データ構造ア クセスのこのような種類をプロテクトするためにのスピン・ロックを使用することによって、 Linux 内でこれは達成されます。 スピン・ロックのロッキングはプリエンプション及び/または割り込みを禁止します。いずれに せよ、これらの機能が禁止されている CPU 上で実行するプロセスにおける最悪のケースの プロセスディスパッチレイテンシィは、どれほどそれらが禁止されていたかに直接的に影響さ れます。よって、プリエンプション及び/または割り込みが禁止される時間量に影響を与える、 スピン・ロックが保持されている時間の長さを最小にするためにデバイス・ドライバを書く時に、 それは重要になります。スピン・ロックのロッキングは潜在的にプリエンプションまたは割り込 みを禁止させることを覚えておきます(どのスピン・ロック・インターフェイスが使用されている かに依存します)。このトピックに関する更なる情報については、“リアルタイム・パフォーマン ス”の章を見てください。 ビッグ・カーネル・ロック(BKL)及び ioctl ビッグ・カーネル・ロック(BKL)は Linux カーネル内のスピン・ロックで、それはカーネル・ソー ス・コードのピースが粗くそして複数スレッドされている時に使用されます。Linux カーネルを 13-17 SUSE Linux Enterprise Real Time Linux User’s Guide 体系的に複数スレッドすることによって、BKL の多くの使用は取り除かれますが、Linux カー ネル内で BKL は依然として最も高度に競合されそして長く保持されるロックです。 デフォルトで、デバイス・ドライバと結合している ioctl (2)関数を呼び出す前に、Linux カーネ ルは BKL をロックします。もしもデバイス・ドライバが複数スレッドされているなら、ioctl を呼 び出す前に BKL をロックする必要はありません。SUSE Linux Enterprise Real Time はデバ イス・ドライバが ioctl を呼び出す前に BKL をロックしないように指定することを可能にします。 デバイスがリアルタイム機能をサポートするように使用される時、またはシールドされている CPU 上でデバイスの ioctl ルーチンの呼び出しをアプリケーションが行う時、デバイス・ドライ バが修正されており、BKL がロックされていないことがとても重要です。 そうでなければ、プロセスは BKL スピン・ロック上のスピニングを長期にわたって失速させ、 プログラム及び同じ CPU へ割り当てられている割り込みへのジッタを引き起こします。 デバイスの ioctl ルーチンへのエントリへ BKL がロックされないように指定するメカニズムは、 デバイス・ドライバ・ソース・コード内の file_operations 構造内で FOPS_IOCTL_NOBKL フラ ッグを設定することです。以下はどのようにして RCIM デバイスがこのフラッグを設定するの かの例です。 static struct file_operations rcim_fops = { owner: THIS_MODULE, open: rcim_master_open, release: rcim_master_release, ioctl: rcim_master_ioctl, mmap: rcim_master_mmap, flags: FOPS_IOCTL_NOBKL, }; この変更を行った後、デバイス・ドライバは再構築されなければなりません。静的ドライバにと ってこれはカーネル全体を再構築することを意味します。動的にロード可能なモジュールにお いては、そのモジュールが再構築されなければならないのみです。更なる情報については、 “カーネルのコンフィグレーション及び構築”を見てください。 パフォーマンス分析 グラフィカル分析ツールである NightTrace は、アプリケーション内、及びカーネル内の重要な イベントについての情報をグラフィカルに表示させることを可能にし、そしてアプリケーション の動作のパターン及び異常を識別するのに使用することができます。変化する状況のもとで 13-18 SUSE Linux Enterprise Real Time Linux User’s Guide コードをインタラクティブに分析する機能は、デバイス・ドライバのリアルタイム・パフォーマン スの微調整において、極めて貴重です。 ユーザ・レベル・コードでのトレース・ポイントへの供給、トレース・データの取込み、及び結果 の表示のプロセスは、NightTrace User’s Guide 出版番号 0890398 内で完全に説明されて います。ユーザ及びカーネル・トレース・イベントは分析のためにログしそして表示させること ができます。 SUSE Linux Enterprise Real Time トレース及びデバッグ・カーネル内に含まれるディフォル ト定義のカーネル・トレース・イベントをカーネル・トレーシングは利用します。ユーザ定義のイ ベントはディフォルト定義の CUSTOM トレース・イベントを使用してログすることができるか、 または動的に生成されます。全ては NightTraceRT によって分析のために表示されます。カ ーネル・トレース・イベントに関する詳細については章を参照してください。 13-19 SUSE Linux Enterprise Real Time Linux User’s Guide A プログラム例 – メッセージキュー POSIX 及び System V メッセージキュー機能の使用を説明するプログラム例をこの付録は含 みます。追加のプログラム例は、/usr/share/doc/ccur/examples 内にオンラインで提供さ れています。 POSIX メッセージキュー例 ここで与えられているプログラム例は C で書かれています。このプログラム内では、親プロセ スが POSIX メッセージキューを開き、そしてキューが空から非空へ移行する時にリアルタイ ム・シグナル経由でレジスタに知らされます。親は子を生み、そして子が空キューへメッセー ジを送るまで子の世話をします。子はメッセージを送信し、その記述子を閉じ、そして終了し ます。 親はリアルタイム・シグナルを受信し、そしてシグナル・ハンドラー内で siginfo_t 構造がデリバ ーするように sigev_value (si_value)を取込みます。親はさらに子の評価メッセージを受信 する前に、si_code (SI_MESGQ)のデリバリを調べます。親は、先に sigev_value によって 登録されているように si_value(それはユニオンです)のデリバリが正確であったことを確認し ます。シグナル・ハンドラーはさらに psignal を使用して受信されたリアルタイム・シグナル値 (SIGRTMAX)を表示します。Psignal 関数は SIGRTMAX をどのように名付けるのかを知ら ないので、それは未知のシグナルを呼び出し、値をプリントしそして終了します。 このプログラムを構築するには、以下のものを指定します。 gcc mq_notify_rtsig .c –Wall #include <sys/types.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/time.h> #include <unistd.h> #include <mqueue.h> #include <stdlib.h> #include <ctype.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <fcntl.h> #include <time.h> #include <sched.h> #include <signal.h> A-1 -g -l ccur_rt -o mq_notify_rtsig SUSE Linux Enterprise Real Time Linux User’s Guide #include <bits/siginfo.h> #define MSGSIZE 40 #define MAXMSGS 5 #define VAL 1234 void handlr(int signo, siginfo_t *info, void *ignored); int val, code; int main(int argc, char **argv) { struct sigaction act; struct sigevent notify; struct mq_attr attr; sigset_t set; char *mqname = "/mq_notify_rtsig"; char rcv_buf[MSGSIZE]; mqd_t mqdes1, mqdes2; pid_t pid, cpid; int status; memset(&attr, 0, sizeof( attr)); attr.mq_maxmsg = MAXMSGS; attr.mq_msgsize = MSGSIZE; mq_unlink(mqname); mqdes1 = mq_open(mqname, O_CREAT|O_RDWR, 0600, &attr); sigemptyset(&set); act.sa_flags = SA_SIGINFO; act.sa_mask = set; act.sa_sigaction = handlr; sigaction(SIGRTMAX, &act, 0); notify.sigev_notify = SIGEV_SIGNAL; notify.sigev_signo = SIGRTMAX; notify.sigev_value.sival_int = VAL; mq_notify(mqdes1, ¬ify); printf("¥nmq_notify_rtsig:¥tTesting notification sigev_value¥n¥n"); printf("mq_notify_rtsig:¥tsigev_value=%d¥n",¥ notify.sigev_value.sival_int); if( (pid = fork()) < 0) { printf("fork: Error¥n"); printf("mq_notify_rtsig: Test FAILED¥n"); exit(-1) ; } if(pid == 0) { /* child */ cpid = getpid() ; mqdes2 = mq_open(mqname, O_CREAT|O_RDWR, 0600, &attr); printf("child:¥t¥t¥tsending message to empty queue¥n"); mq_send(mqdes2, "child-test-message", MSGSIZE, 30); mq_close(mqdes2); exit(0); } else { /* parent */ A-2 SUSE Linux Enterprise Real Time Linux User’s Guide waitpid( cpid, &status, 0); /* keep child status from init */ printf("parent:¥t¥t¥twaiting for notification¥n"); while(code != SI_MESGQ) sleep(1); q_receive(mqdes1, rcv_buf, MSGSIZE, 0); printf("parent:¥t¥t¥tqueue transition - received %s¥n",rcv_buf); } printf("mq_notify_rtsig:¥tsi_code=%d¥n",code); printf("mq_notify_rtsig:¥tsi_value=%d¥n",val); if(code != -3 || val != VAL) { printf("¥nmq_notify_rtsig:¥tTest FAILED¥n¥n"); return(-1); } mq_close(mqdes1); mq_unlink(mqname); printf("¥nmq_notify_rtsig:¥tTest passed¥n¥n"); return(0); } void handlr(int signo, siginfo_t *info, void *ignored) { psignal(signo, "handlr:¥t¥t¥t"); val = info->si_value.sival_int; code = info->si_code; return; } System V メッセージキュー例 ここで与えられているプログラム例は C で書かれています。このプログラムでは、親プロセス はその作業のいくつかをロードするために子プロセスを生みます。親プロセスはさらにそれの ためのメッセージキューを生成し、そして使用するために子プロセスを生成します。 子プロセスがその作業を完了する時、それはメッセージキュー経由で親プロセスへ結果を送 信し、そして親にシグナルを送信します。親プロセスがシグナルを受信する時、それはメッセ ージキューからメッセージをリードします。 #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <signal.h> #include <errno.h> #define MSGSIZE 40/* maximum message size */ #define MSGTYPE 10/* message type to be sent and received */ /* Use a signal value between SIGRTMIN and SIGRTMAX */ #define SIGRT1(SIGRTMIN+1) /* The message buffer structure */ A-3 SUSE Linux Enterprise Real Time Linux User’s Guide struct my_msgbuf { long mtype; char mtext[MSGSIZE]; }; struct my_msgbuf msg_buffer; /* The message queue id */ int msqid; /* SA_SIGINFO signal handler */ void sighandler(int, siginfo_t *, void *); A-4 /* Set after SIGRT1 signal is received */ volatile int done = 0; pid_t parent_pid; pid_t child_pid; main() { int retval; sigset_t set; struct sigaction sa; /* Save off the parent PID for the child process to use. */ parent_pid = getpid(); /* Create a private message queue. */ msqid = msgget(IPC_PRIVATE, IPC_CREAT | 0600); if (msqid == -1) { perror(“msgget”); exit(-1); } /* Create a child process. */ child_pid = fork(); if (child_pid == (pid_t)-1) { /* The fork(2) call returned an error. */ perror(“fork”); /* Remove the message queue. */ (void) msgctl(msqid, IPC_RMID, (struct msqid_ds *)NULL); exit(-1); } if (child_pid == 0) { /* Child process */ /* Set the message type. */ msg_buffer.mtype = MSGTYPE; /* Perform some work for parent. */ sleep(1); A-4 SUSE Linux Enterprise Real Time Linux User’s Guide /* ... */ /* Copy a message into the message buffer structure. */ strcpy(msg_buffer.mtext, “Results of work”); /* Send the message to the parent using the message * queue that was inherited at fork(2) time. */ retval = msgsnd(msqid, (const void *)&msg_buffer, trlen(msg_buffer.mtext) + 1, 0); if (retval) { perror(“msgsnd(child)”); /* Remove the message queue. */ (void) msgctl(msqid, IPC_RMID, (struct msqid_ds *)NULL); exit(-1); } /* Send the parent a SIGRT signal. */ retval = kill(parent_pid, SIGRT1); if (retval) { perror(“kill SIGRT”); /* Remove the message queue. */ (void) msgctl(msqid, IPC_RMID, (struct msqid_ds *)NULL); exit(-1); } exit(0); } /* Parent */ /* Setup to catch the SIGRT signal. The child process * will send a SIGRT signal to the parent after sending * the parent the message. */ sigemptyset(&set); sa.sa_mask = set; sa.sa_sigaction = sighandler; sa.sa_flags = SA_SIGINFO; sigaction(SIGRT1, &sa, NULL); /* Do not attempt to receive a message from the child * process until the SIGRT signal arrives. Perform parent * workload while waiting for results. */ while (!done) { /* ... */ } /* Remove the message queue. (void) msgctl(msqid, IPC_RMID, (struct msqid_ds *)NULL); */ A-5 SUSE Linux Enterprise Real Time Linux User’s Guide /* All done. */ exit(0); } /* * This routine reacts to a SIGRT1 user-selected notification * signal by receiving the child process’ message. */ void sighandler(int sig, siginfo_t *sip, void *arg) { int retval; struct ucontext *ucp = (struct ucontext *)arg; /* Check that the sender of this signal was the child process. */ if (sip->si_pid != child_pid) { /* Ignore SIGRT from other processes. */ printf(“ERROR: signal received from pid %d¥n”, sip->si_pid); return; } /* Read the message that was sent to us. */ retval = msgrcv(msqid, (void*)&msg_buffer, MSGSIZE, MSGTYPE, IPC_NOWAIT); done++; if (retval == -1) { perror("mq_receive (parent)"); return; } if (msg_buffer.mtype != MSGTYPE) { printf(“ERROR: unexpected message type %d received.¥n”, msg_buffer.mtype); return; } printf(“message type %d received: %s¥n”, msg_buffer.mtype, msg_buffer.mtext); } A-6 SUSE Linux Enterprise Real Time Linux User’s Guide B Real Time カーネルチューニング 表 B-1 は SUSE Linux Enterprise Real Time のユニークな機能のリスト及びそれらをサポ ートするカーネル・コンフィグレーション・セッティングを含みます。リアルタイム・オプション、オ プション的パケージ・サポートのために開発した機能及びオープン・ソース・パッチから組み込 んだ機能を含みます。 それぞれの機能において、カーネル・コンフィグレーション GUI オプション及びチューニング可 能な名前が、必要に応じてセッティングをビューしそして修正するのを補助するために与えら れています。追加的に、それぞれの SUSE Linux Enterprise Real Time 既構築カーネル内 のそれぞれの機能におけるデフォルトのセッティングが提供されています。カーネルのコンフ ィグレーション及び構築に関するさらなる情報については、10 章を見てください。 個々の機能についての情報は様々なところで利用可能です。表 B-1 では、以下の参照が提 供されています。 ・ この SUSE Linux Enterprise Real Time User’s Guide 内に含まれる情報のページ番号 (アクティブ・ハイパーテキスト・リンク)が提供されています。 ・ 他の適切なドキュメントの名称及び出版番号。 情報を取得できる他のソースには以下のものがあります。 ・ パラメータが選択される時に表示するカーネル・コンフィグレーション GUI の別々のヘル プ・ウィンドウ内で提供されている情報。 B-1 ・ カーネル・ソース・ツリーの Documentation ディレクトリ内のテキスト・ファイル ・ インターネット上の Linux ドキュメンテーション・サイト SUSE Linux Enterprise Real Time Linux User’s Guide 表 B-1 Real Time カーネルのチューニング可能な機能 カーネル・コンフィグ 機能性 レーション GUI オプ SUSE Linux Enterprise チューニング可能名 ション Real Time カーネルデフォ ルト・セッティング ドキュメンテーショ ン参照 シールドされている CPU CPU シールド許可 CPU ダウン許可 SHIELD General Setup RCU プロセッシング 変数の再スケジューリ ング 高精度プロセス・アカ ウンティング 高解像度タイマー CPU_DOWNING 2章 Y / all RCU_ALTERNATIVE General Setup RESCHED_VAR General Setup HIRACCT General Setup HR_POSIX_TIMERS Processor Type and REQUIRE_TSC TSC 信頼性 REQUIRE_RELIABLE_T 2章 7章 Y / all Y / debug, trace N / generic Y / all Y / all i386 SLES Y / all SLES only 5章 7章 6章 7章 Features SC General Setup RWSEM_PRIO_INHERIT Y/all 5章 General Setup POSIX_MQUEUE Y/all 3章 General Setup POST_WAIT Y/all 5章 Y/all 12 章 プライオリティ継承 カーネル RW セマフォ POSIX メッセージキュ ー Post/Wait サポート Exec 時の継承 General Setup INHERIT_CAPS_ACROS S_EXEC メモリ・マッピング プ ロ セ ス 空 間 mmap/usermap サポ PROCMEM_MMAP Y/all PROCMEM_ANYONE Y/all PROCMEM_WRITE Y/all ート 他のプロセスのアドレ ス空間へのアクセス File Systems 9章 のファイル許可 他のプロセスのアドレ ス空間内へのライトの 許可 * Y = セットされている、N = セットされていない、M = カーネル・モジュールがロードされる時チューニングパラメータが許可さ れる B-2 SUSE Linux Enterprise Real Time Linux User’s Guide 表 B-1 Real Time カーネルのチューニング可能な機能(続き) カーネル・コンフィグ 機能性 レーション GUI オプシ SUSE チューニング可能名 ョン Linux Enterprise Real Time カーネルデフォ ルト・セッティング Processor Type and K8_NUMA Y/all (x86 only) Features SCHED_SMT N/all (x86_64 only) SOFTIRQ_PRI 90 / all NUMA サポート ドキュメンテーショ ン参照 10 章 割り込み処理 Softirq デ ー モ ン 優 先度 Softirq プリエンプシ General Setup LOCK ョンブロッキング 13 章 SOFTIRQ_PREEMPT_B Y / all カーネル仮想空間の 動的割り付け General Setup VMALLOC_RESERVE 128 / all i386 4096 / all x86_64 13 章 CPU 間割り込みの削減 VMALLOC_TLBFLUSH_ Y / all TLBフラッシュの削減 G章 REDUCTION VMALLOC_LARGE_RES 大きなサイズの vmallocs/ioremapsの General Setup ERVE 予約 大きなサイズの 46 / all i386 G章 1024 / all x86_64 VMALLOC_LARGE_THR 4 / all vmallocs/ioremaps G章 ESHOLD SIZE Preload vmalloc page tables at boot グラフィックページ予 約割り当て VMALLOC_PGTABLE_P Y / generic RELOAD (i386 only) PREALLOC_GRAPHICS 10240 / x86_64 _PAGES 0 / i386 Device Drivers G章 Device Drivers G章 その他のパフォーマンス問題 DETECT_SOFTLOCKU Softlockup の検出 Kernel Hacking N/ all 2章 P * Y = セットされている、N = セットされていない、M = カーネル・モジュールがロードされる時チューニングパラメータが許可さ れる B-3 SUSE Linux Enterprise Real Time Linux User’s Guide 表 B-1 Real Time カーネルのチューニング可能な機能(続き)) カーネル・コンフィグ 機能性 レーション GUI オプシ SUSE Linux Enterprise チューニング可能名 ョン Real Time カーネルデフォ ルト・セッティング ドキュメンテーショ ン参照 XFS ファイルシステム XFS許可 リアルタイムサブボリ File Systems ュームサポート カーネルプリエンプ Processor Type ション and Features Ptrace 拡張 General Setup XFS_FS M / all XFS_RT Y / all PREEMPT Y / all 1章 PTRACE_EXT Y / all 1章 8章 カーネルデバッグ(Kernel Debug) Y / all KGDB Kgdb を含む Additional compile arguments KDB expanded display Kernel Hacking KGDB_MORE N / trace, generic 1章 N / all Y / generic, trace REGPARM N / debug n/a (i386 only) * Y = セットされている、N = セットされていない、M = カーネル・モジュールがロードされる時チューニングパラメータが許可さ れる B-4 SUSE Linux Enterprise Real Time Linux User’s Guide 表 B-1 Real Time カーネルのチューニング可能な機能(続き)) カーネル・コンフィグ 機能性 レーション GUI オプシ SUSE Linux Enterprise チューニング可能名 ョン Real Time カーネルデフォ ルト・セッティング ドキュメンテーショ ン参照 カーネルトレーシング カーネルトレース許 TRACE 可 Enable BKL trace Y / trace, debug N / generic Kernel Tracing D章 TRACE_BKL N / all NVIDIA M / all events nVIDIA Graphics nVIDIA Kernel Support Support Hyper-threading Processor Type (i386 kernels only) and Features SNARE Audit Support Release Notes (0898206, 0898203) X86_HT Y / all SNARE_AUDIT N/ all 2章 Guide to General Setup SNARE for Linux * Y = セットされている、N = セットされていない、M = カーネル・モジュールがロードされる時チューニングパラメータが許可さ れる B-5 SUSE Linux Enterprise Real Time Linux User’s Guide C ケーパビリティ この付録では、SUSE Linux Enterprise Real Time に含まれるケーパビリティ及びそれぞれ のケーパビリティが提供する許可をキュー挙します。 概要 ケーパビリティは Linux 内の方法で、それは権限が伝統的にスーパーユーザと結合しており、 そして独立に許可及び禁止することができる個別のユニットに分割されます。無節操なユー ザはケーパビリティが提供するいくつかの許可を使用して Linux が提供するセキュリティ・メカ ニズムを打ち壊してしまうことがあります。よって、このケーパビリティは注意を払って使用さ れるべきです。ケーパビリティは/usr/include/linux/capability .h 内で定義されています。 Linux 内でどのようにケーパビリティが動作するかについてのさらなる情報については、 capability(7) man page を参照してください。ケーパビリティを利用する認証方法を提供する PAM ケーパビリティに関する情報については、13 章を参照してください。 ケーパビリティ このセクションでは、SUSE Linux Enterprise Real Time 下で定義されているそれぞれのケ ーパビリティが提供する許可について説明します。標準 Linux のケーパビリティから SUSE Linux Enterprise Real Time にユニークなケーパビリティまでも含めてここでは論じられま す。 CAP_CHOWN 現在の有効ユーザ ID、グループ ID、または補足的グループ ID の 1 つがファイル の UID/GID 属性に一致しない時に、このケーパビリティはユーザまたはグループ・ ファイル・オーナーシップの変更の制約を無効にします。 CAP_DAC_OVERRIDE 不変または末尾のみ(chattr (1)を見てください)とマークされているファイルが強制 するファイル・アクセス制約を除いて、もしもそのファイル・システムにおいて ACL サ ポートがカーネル内へコンフィグされていれば(さらなる詳細については acl (5)を見 てください)、オーナー/グループ/world リード/ライト実行ファイル・システム許可属性 及びアクセス・コント role・リスト(ACL)制約で通常強制されているどのファイル discretionary(任意の)アクセス・コント role(DAC)制約も、このケーパビリティは無 効にします。 リード及びライト・アクセス DAC 制約は常にこのケーパビリティで無効にされます。 C-1 SUSE Linux Enterprise Real Time Linux User’s Guide 少なくとも 1 つのオーナー/グループ/world 実行ビットが設定されている限り、DAC 制約の実行はそのケーパビリティで無効にされます。 fbsintrpt (3)及び fbsresume (3)コマンドを使用する時、このケーパビリティはさら に許可アクセス制約も無効にします。 CAP_DAC_READ_SEARCH もしもそのファイル・システムにおいて ACL サポートがカーネル内へコンフィグされ ていれば(更なる詳細については acl (5)を見てください)、オーナー/グループ /world リード/ライト実行ファイル・システム許可属性及びアクセス・コント role・リスト (ACL)制約で通常強制されているどのファイル discretionary(任意の)アクセス・コ ント role(DAC)制約も、このケーパビリティは無効にします。 このケーパビリティは常にファイル及びディレクトリへのリード・アクセス、そしてディ レクトリへの検索(実行)アクセスを可能にします。 fbsintrpt (3)及び fbsresume (3)コマンドを使用する時、このケーパビリティはさら に許可アクセス制約も無効にします。 CAP_FOWNER このケーパビリティは: ・ ファイル・オーナーID がユーザ ID に等しくなければならないファイル属性変更 に関する全ての Discretionary(任意の)アクセス・コント role(DAC)制約を無効 にします。 ・ fbs クリエータ・ユーザ ID とユーザ ID が呼び出し元の有効ユーザ ID に一致し ない時に、FBS_RMID 及び FBS_SET fbsctl (2)コマンドを有効にします。 このケーパビリティはデータ・アクセス・コント role(DAC)制約を無効にしません。 CAP_FSETID このケーパビリティは有効的グループ ID(または補足的グループ ID の 1 つ)がファ イル・グループ ID に、そのファイル上で S_ISGID ビットを設定する時に一致するべ き制約を無効にします。 CAP_IPC_LOCK このケーパビリティは mlock (2)及び mlockall (2)システム・サービス呼び出しを通 してのメモリのロッキングを可能にします。 それは更に shmctl (2) SHM_LOCK 及び SHM_UNLOCK コマンドを通しての共 有メモリ・セグメントのロッキング及びアンロッキングを可能にします. CAP_IPC_OWNER このケーパビリティは IPC 共有メモリ・セグメント、メッセージキュー、またはセマフォ C-2 SUSE Linux Enterprise Real Time Linux User’s Guide 配列と結合している IPC 許可設定を無効にします。IPC 許可はファイルと結合して いるリード/ライト・オーナー、グループ及び world 許可と同じ形式及び意味を持ちま す。許可実行は使用されていないことに注意します。現在の IPC リソースのオーナ ー及び許可をビューするのに ipcs (1)コマンドは使用されます。 CAP_KILL このケーパビリティは、シグナルを送信するプロセスのリアルなまたは有効的なユ ーザ ID がシグナルを受信するプロセスのリアルなまたは有効的なユーザ ID に一 致しなければならない制約を無効にします。 このケーパビリティはさらに、呼び出しプロセスが tty のオーナーであることまたは CAP_SYS_TTY_CONFIG ケーパビリティであることを要求する KDSIGACCEPT ioctl (2)呼び出し上の制約も無効にします。 CAP_LEASE このケーパビリティによって、プロセスのユーザ ID がファイル・システム・ユーザ ID 値に一致しない時でも、fcntl (2) F_SETLEASE コマンドでユーザがファイル上でリ ースを取り出すことができます。 CAP_LINUX_IMMUTABLE このケーパビリティは S_IMMUTABLE 及び S_APPEND ファイル属性の修正を可 能にします。これらのファイル属性の更なる情報については chattr (1) man page を見てください。 CAP_MKNOD このケーパビリティによって、ユーザは mknod (1)/mknod (2)の権限局面を利用 することが可能です。それはまた XFS_IOC_FSSETDM_BY_HANDLE xfs ファイ ル・システム ioctl (2)コマンドの使用を可能にします。 CAP_NET_ADMIN このケーパビリティは以下のネットワーク管理動作を可能にします。 ・ ソケット上のデバッグ及びプライオリティ・オプションの設定。 ・ IP ファイアーウォール、masquerading、及びアカウンティングの管理。 ・ インターフェイス・コンフィグレーション。 ・ マルチキャスティング。 ・ ネットワーク・デバイス・ハードウェア・レジスタのリーディング及びライティング。 ・ トンネルの追加/削除。 ・ ルーティング・テーブルの修正。 ・ TOS(サービスの種類)の設定。 ・ ATM 制御ソケットの起動。 CAP_NET_BIND_SERVICE このケーパビリティは、1024 以下で TCPUDP とストリーム・コント role 送信プロトコ C-3 SUSE Linux Enterprise Real Time Linux User’s Guide ル(SCTP)・ソケットの連結、及び 32 以下の ATM VCI への連結を可能にします。 このケーパビリティはさらに RPC クライアント・トランスポートを生成する時に保管さ れているポートの使用を引き起こします。 CAP_NET_BROADCAST このケーパビリティは現在使用されていません。 CAP_NET_RAW このケーパビリティは SOCK_RAW 及び SOCK_PACKET ソケットの生成、及び SO_BINDTODEVICE setsockopt (2)ソケット・オプションの使用を可能にします。 CAP_SETGID このケーパビリティは、setregid (2)、setgid (2)、setresgid (2)、setfsgid (2)、及 び setgroups (2)システム・サービスにおいて、非ルート・プロセスのグループ ID 値 に配置された制約を無効にします。 このケーパビリティはさらに、現在のプロセスの現在、有効的、または保存されてい るグループ ID に一致しないグループ ID 値を含むソケット・レベル信用証明制御メッ セージをプロセスが送信することを可能にします。(追加的に、信用証明制御メッセ ージ・プロセス ID はプロセスのスレッド・グループ ID に一致しなければならず、また はプロセスはさらに CAP_SYS_ADMIN ケーパビリティを持たなければならず、そし て信用証明制御メッセージ・ユーザ ID はプロセスの保存されている、有効的な、ま たは現在のユーザ ID に一致しなければならず、または CAP_SETUID ケーパビリ ティを持たなければなりません。) CAP_SETPCAP このケーパビリティはプロセスのどのプロセス ID(PID)にも許可されている設定内 でプロセスがどのケーパビリティをも転送することを可能にし、そしてプロセスの許 可されている設定内のどのケーパビリティをもどの PID からでも取り除くことを可能 にします。 CAP_SETUID このケーパビリティは、スーパーユーザのユーザ ID も含めてどのユーザ ID へも現 在のユーザ ID を設定することを可能にします。このケーパビリティの使用において は細心の注意が払われるべきです。 このケーパビリティはさらに、現在のプロセスの現在、有効的、または保存されてい るグループ ID に一致しないグループ ID 値を含むソケット・レベル信用証明制御メッ セージをプロセスが送信することを可能にします。(追加的に、信用証明制御メッセ ージ・プロセス ID はプロセスのスレッド・グループ ID にマッチしなければならず、ま たはプロセスはさらに CAP_SYS_ADMIN ケーパビリティを持たなければならず、 C-4 SUSE Linux Enterprise Real Time Linux User’s Guide そして信用証明制御メッセージ・ユーザ ID はプロセスの保存されている、有効的な、 または現在のユーザ ID に一致しなければならず、または CAP_SETUID ケーパビ リティを持たなければなりません。) このケーパビリティはさらに、このプロセスによって ptrace されるプロセスが、 ptrace されたプロセスが実行する実行可能な“実行上のセット・ユーザまたはグル ープ ID”のユーザまたはグループ ID を継承しない制限も無効にします。 CAP_SYS_ADMIN このケーパビリティは以下のシステム管理動作を提供します。 bdflush (2)の使用を可能にします。 オープン・ファイル制限を可能にします。 ディスク割り当ての評価及びコンフィグレーションを可能にします。 xfs ファイル・システム下で(もしも XFS_QUOTA が許可されていれば)ユーザ あたりまたはグループ・ベースあたりのディスク使用法の評価及びコンフィグレ ーションを可能にします。 umount ( )及び mount ( )を有効にします。 fork (2)/clone (2)間にプロセスの名前スペースのコピーを可能にします。 プロセスの有効ユーザ ID に一致するユーザ ID またはクリエータ・ユーザ ID 値を持たないメッセージキュー、セマフォ、及び共有メモリ・エリアにおける、 msgctl (2)、semctl (2)、そして IPC_SET 及び IPC_RMID コマンドを有効に します。 共有メモリ・エリアのユーザ ID またはクリエータ・ユーザ ID がプロセスの有効 ユーザ ID に一致しない共有メモリにおいて、shmctl (2) SHM_PHYSBIND コ マンドを有効にします。 非ルート・ユーザが CAP_SYS_RESOURCE ケーパビリティを持たない時に fork (2) / clone (2)呼び出し上のプロセスあたりのプロセスの最大数の制限 を無効にします。 プロセスが呼び起こされる時に呼び出しプロセスの有効ユーザ ID またはユー ザ ID 値として同じユーザ ID または保存されているユーザ ID を持たない、 pw_post (2)、pw_postv (2)、server_wakel (2)、及び server_wakevec (2)呼び出し上でのウェイクアップを可能にします。 RCIM_WRITE_EEPROM 及び RCIM_TESTIRQ ioctl (2) RCIM ドライバ・コ マンドの使用を可能にします。 システム・ダンプ ioctl (2)コマンドの使用、及び sysctl (2)カーネル・ダンプ・デ バイス変数の設定の使用を可能にします。 C-5 シリアル・ポートのコンフィグレーションを可能にします。 SUSE Linux Enterprise Real Time Linux User’s Guide sethostname (2)及び setdomainname (2)呼び出しを有効にします。 swapon (8)及び swapoff (8)呼び出しの使用を可能にします。 HP SA 5xxx 及び 6xxx コントローラにおけるディスク配置ドライバ内の、raw ( 生 の ) ボ リ ュ ー ム ・ ゼ ロ 及 び CCISS_SETINTINFO 及 び CCISS_SETNODENAME ioctl (2)コマンドのオープンを可能にします。 Mylex DAC960 PCI RAID コントローラ・ドライバ内の ioctl (2)コマンドを有効 にします。 Compaq SMART2 コントローラ・ディスク配列ドライバ内の raw(生の)ボリュー ム・ゼロのオープンを可能にします。 フロッピー・ルートのみ ioctl (2)コマンド(ビット 0x80 セットととのこれらのコマン ド)の、そしてさらに FDSETPRM 及び FDDEFPRM セット幾何コマンドの使用 を可能にします。 以下のブロック・デバイス ioctl (2)コマンドの使用を可能にします。BLKPG add/delete パーティション、BLKRRPART 再リード・パーティション、ブロック・ デバイスにおける BLKRASET セット前リード、BLKFRASET セット・ファイル・ システム前リード、BLKBSZSET セット論理ブロック・サイズ、BLKFLSBUF フ ラッシュ・バッファ・キャッシュ、BLKROSET セット・デバイス・リードのみ。 ループバック・ファイル・システム上の暗号化キーの設定を可能にします。 ネットワーク・ブロック・デバイス ioctl (2)コマンドを有効にします。 メモリ・タイプ領域レジスタ(MTRR)の修正を可能にします。 カーネル内で APM が許可されている時に、パワー管理における ioctl (2)コマ ンドの使用を可能にします。 BIOS セッティングにおけるいくつかの ioctl (2)コマンドの使用を可能にしま す。 VM86_REQUEST_IRQ vm86 (2)サポートの使用を可能にします。 CDROMRESET、CDROM_LOCKDOOR 及び CDROM_DEBUG ioctl (2) CDROM コマンドの使用を可能にします。 sbpcd CDROM ドライバ上の DDIOCSDBG DDI デバッグ ioctl (2)を有効にし ます。 ルートのみ Direct Rendering Manager (DRM) ioctl (2)コマンド、及び DRM mmap (2) DMA メモリ・コマンドの使用を可能にします。 Specialix RIO スマート・シリアル・カード・ドライバ内のルートのみ ioctl (2)コマ ンドの使用を可能にします。 I2C シリアル・バス上の VAIO EEProm ハードウェア・センサー・チップの最初 の 16 バイトのリーディングを可能にします。 C-6 /proc/ide/iden/config ファイル、IDE ドライブ・セッティングの修正、及び以下 SUSE Linux Enterprise Real Time Linux User’s Guide の IDE ioctl (2) コ マ ン ド へ の ラ イ ト を 可 能 に し ま す 。 HDIO_DRIVE_TASKFILE ( raw ( 生 の ) タ ス ク ・ フ ァ イ ル の 実 行 ) 、 HDIO_SET_NICE(ナイス・フラッグの設定)、HDIO_DRIVE_RESET(デバイ ス再設定の実行)、HDIO_GET_BUSSTATE(ハードウェア・インターフェイス のバス状態の取得)、HDIO_SET_BUSSTATE(ハードウェア・インターフェイ スのバス状態の設定)。 SNDRV_CTL_IOCTL_POWER サウンド ioctl (2)コマンドの使用を可能にし ます。 Live!及び Sound Blaster 512 のような様々な PCI ベースのサウンド・カードに おける様々なルートのみ ioctl (2)コマンドの使用を可能にします。 実験的ネットワーキング SIOCGIFDIVERT 及び SIOCSIFDIVERT フレーム Diverter ioctl (2)コマンドの使用を可能にします。 信用証明のユーザ ID が現在のプロセスでの有効な、保存されている、または 現在のユーザ ID 値に一致しない時、SCM_CREDENTIALS ソケット・レベル 制御メッセージの送信を可能にします。 md デバイス(複数デバイス – RAID 及び LVM)の管理を可能にします。 デジタル・ビデオ・ブロードキャスティング・インターフェイスの追加及び取り除き を可能にします。 もしも CAP_SYS_RAWIO ケーパビリティが許可されていなければ、Philips saa7134 ベ ー ス TV カ ー ド video4linux デ バ イ ス ・ ド ラ イ バ に お い て 、 VIDIOC_S_FBUF ioctl (2)コマンドを有効にします。 もしも CAP_SYS_RAWIO ケーパビリティが許可されていなければ、bttv 及び Zoran ビデオ・デバイス・ドライバ内の VIDIOCSFBUF 及び VIDIOC_S_FBUF IOct (2)コマンドの使用を可能にします。 もしも CAP_SYS_RAWIO ケーパビリティが許可されていなければ、planb ビ デオ・デバイス・ドライバ内の VIDIOCSFBUF ioctl (2)コマンドの使用を可能 にします。 stradis 4:2:2 mpeg デコーダ・ドライバ内の VIDIOCSFBUF ioctl (2)コマンド の使用を可能にします。 インテリジェント入力/出力 (I2O) ioctl (2)コマンドの使用を可能にします。 ISDN CAPI サポート・ドライバ内の manufacturer コマンドを有効にします。 PCI バス・コンフィグレーション空間の最大 256 バイト(非標準化部分)までのリ ー デ ィ ン グ を 可 能 に し 、 そ し て さ ら に pciconfig_read (2) 及 び pciconfig_write (2)システム・サービス呼び出しの使用を可能にします。 C-7 ルートのみ pcmcia ioctl (2)コマンドの使用を可能にします。 aacraid Adaptec RAID ドライバ内の FSACTL_SEND_RAW_SRB ioctl (2) SUSE Linux Enterprise Real Time Linux User’s Guide コマンドの使用を可能にします。 Qlogic ISP2x00 nvram へのリード及びライトを可能にします。 MegaRAID ioctl (2)コマンドへのアクセスを可能にします。 MTSETDRVBUFFER SCSI テープ・ドライバ ioctl (2)コマンドの使用を可能に します。 も し も SCSI_DEBUG が カ ー ネ ル 内 に 許 可 さ れ て い る な ら ( さ ら に CAP_SYS_RAWIO ケーパビリティを要求します)、/proc SCSI デバッグ・ファ イルへのライト・アクセスを可能にします。 SCSI_IOCTL_SEND_COMMAND ioctl (2) コ マ ン ド ( さ ら に CAP_SYS_RAWIO ケーパビリティを要求します)経由で恣意的な SCSI コマ ンドの送信を可能にします。 SCSI scatter-gather SG_SCSI_RESET ioctl (2) コ マ ン ド 、 /proc/sg/allow_dio、及び/proc/sg/def_reserved_size write (2)、(さらに CAP_SYS_ADMIN ケーパビリティを要求します)の使用を可能にします。 Quicknet Technologies Telephony カ ー ド ・ ド ラ イ バ に お け る 、 IXJCTL_TESTRAM 及び IXJCTL_HZ IOct (2)コマンドの使用を可能にしま す。 いくつかの autofs ルートのみ ioctls を有効にします。 ファイル・システム・オブジェクト(getfattr (1)、setfattr (1))の拡張されている 属性の取得及び設定を可能にします。 NetWare Core プロトコル(NCP)・ファイル・システムにおけるルートのみ ioct (2)コマンドを有効にします. 新しい smb ファイル・システム接続のセット・アップを可能にします。 ufd ファイル・システム(いくつかの CD-ROM 及び DVD 上で使用されていま す)上の UDF_RELOCATE_BLOCKS ioctl (2)コマンドを有効にします。 ランダム・デバイスの管理を可能にします。 raw(生の)キャラクタ・デバイス(/dev/raw/rawn)のブロック・デバイスへの連 結を可能にします。 カーネルの syslog(printk 動作)のコンフィグレーションを可能にします。 も し SBSVME が カ ー ネ ル で 使 用 可 能 で あ る な ら 、 /proc/driver/btp/unit#/vmemappings フ ァ イ ル へ の 書 き 込 み と 、 PCI か ら VMEbus へのマッピングを作って、そして削除することを可能にします。 /proc/driver/graphics-memory への書き込みが前もって割り当てられたグラ フィックスメモリプールの大きさを修正することを可能にします C-8 SUSE Linux Enterprise Real Time Linux User’s Guide CAP_SYS_BOOT このケーパビリティは reboot (2)システム・サービス呼び出しの使用を可能にしま す。 CAP_SYS_CHROOT このケーパビリティは chroot (2)システム・サービス呼び出しの使用を可能にしま す。 CAP_SYS_MODULE このケーパビリティは、sys_delete_module (2)、init_module (2)、rmmod (8)、 及び insmod (8)を使用して、カーネル・モジュールの挿入及び削除を可能にしま す。 このケーパビリティはさらにカーネルケーパビリティ連結セット値、cap_bset---そこ でこの値が sysctl (2)カーネル・キャップ連結パラメータ経由でアクセス可能になっ ている---の修正を可能にします。 CAP_SYS_NICE このケーパビリティは以下のことを可能にします。 ¾ 同じユーザ ID でのプロセス上のスケジューリング・プライオリティを高くし ます。 ¾ 異なるユーザ ID で他のプロセス上のプライオリティを設定します。 ¾ 同じユーザ ID を持つプロセスにおいて SCHED_FIFO 及び SCHED_RR スケジューリング・ポリシーを設定します。 ¾ 異なるユーザ ID でプロセスのスケジューリング・ポリシーを変更します。 ¾ sched_setaffinity (2)または/proc/pid/affinity ファイル経由の異なるユ ーザ ID でのプロセスにおける CPU バインドを変更します。 ¾ fbsconfigure (3)の使用を可能にします。 CAP_SYS_PACCT このケーパビリティは acct (2)システム・サービス呼び出しを通してのプロセス・アカ ウンティングのコンフィグレーションを可能にします。 CAP_SYS_PTRACE このケーパビリティは他のどのプロセスにもプロセスを ptrace (2)させます。 このケーパビリティはさらに CAP_SETUID 設定に関係無く、プロセスに実行可能な setuid を ptrace (2)させます。 CAP_SYS_RAWIO このケーパビリティは以下の raw(生の)IO 動作を可能にします。 ¾ shmctl (2) SHM_PHYSBIND コマンド ¾ resched_cntl (2) RESCHED_SET_VARIABLE コマンド ¾ PCI バス空間の mmap (2)及び PCI ベース・アドレス・レジスタへのアクセ ス ¾ C-9 /dev/port 及び/proc/kcore の open (2) SUSE Linux Enterprise Real Time Linux User’s Guide ¾ ioperm (2)及び iopl (2)システム・サービス呼び出しの使用 ¾ ファイル・システム ioctl (2) FIBMAP コマンド ¾ も し も MICROCODE が カ ー ネ ル 内 で 許 可 さ れ て い れ ば 、 /dev/CPU/microcode ファイルの open (2) ¾ HP SA 5xxx 及び 6xxx コントローラ ioctl (2)コマンドにおける以下のディ スク配列ドライバ: CCISS_PSSSTHRU、CCISS_BIG_PASSTHRU、 CCISS_DEREGDISK、CCISS_REGNEWD ¾ Compaq SMART2 コントローラにおけるディスク配列ドライバの open (2)、 及び IDAPASSTHRU ioctl (2)コマンド ¾ IDE コントローラのコンフィグレーション、及び以下の IDE ioctl (2)コマン ド : HDIO_DRIVE_TASKFILE 、 HDIO_DRIVE_TASK 、 HDIO_DRIVE_CMD 、 、 HDIO_SCAN_HWIF HDIO_UNREGISTER_HWIF ¾ フ ァ イ バ ー ・ チ ャ ン ネ ル ・ ホ ス ト ・ バ ス ・ ア ダ プ タ CPQFCTS_SCSI_PASSTHRU ioctl (2)コマンド ¾ も し も SCSI_DEBUG が カ ー ネ ル 内 で 許 可 さ れ て い れ ば (CAP_SYS_ADMIN も要求されます)、/proc SCSI デバッグ・ファイルへ のアクセスをライト ¾ SCSI_IOCTL_SEND_COMMAND ioctl コ (2) マ ン ド (CAP_SYS_ADMIN も要求されます)経由の恣意的な SCSI コマンドの 送信 ¾ SCSI scatter-gather SG_SCSI_RESET ioctl (2) コ マ ン ド 、 /proc/sg/allow_dio 、 及 び /proc/sg/def_reserved_size wirite (2) (CAP_SYS_ADMIN ケーパビリティも要求します)の使用 ¾ ATMSIGD_CTRL ioctl (2)コマンド ¾ もしも CAP_SYS_ADMIN ケーパビリティが許可されていなければ、bttv 及 び Zoran ビ デ オ ・ デ バ イ ス ・ ド ラ イ バ 内 の VIDIOCSFBUF 及 び VIDIOC_S_FBUF ioctl (2)コマンドの使用 ¾ もしも CAP_SYS_ADMIN ケーパビリティが許可されていなければ、 planb ビデオ・デバイス・ドライバ内の VIDIOCSFBUF ioctl (2)コマンドの 使用 ¾ baycom epp radio 及び HDLC パケット radio ネットワーク・デバイス・ドラ イ バ 内 の HDLCDRVCTL_SETMODEMPAR 及 び HDLCDRVCTL_CALIBRATE ioctl (2)コマンドの使用 ¾ AX.25 デバイス・ドライバにおける Z8530 ベースの HDLC カード内の SIOCSCCCFG 、 SIOCSCCINI 、 SIOCSCCSMEM 、 及 び C-10 SUSE Linux Enterprise Real Time Linux User’s Guide SIOCSCCCAL ioctl (2)コマンドの使用 ¾ AM radio モデム・デバイス・ドライバ内の SIOCYAMSCFG ioctl (2)コマ ンド ¾ SRP 及び COSA 同期シリアル・カード・デバイス・ドライバにおける、 COSAIOSTRT 、 COSAIODOWNLD 、 COSAIORMEM 、 及 び COSAIOBMSET ioctl (2)コマンド ¾ SiS フレーム・バッファ・デバイス・ドライバにおける、FBIO_ALLOC 及び FBIO_FREE ioctl (2)コマンド ¾ もしも CAP_SYS_ADMIN ケーパビリティが許可されていなければ、 Philips saa7134 ベース TV カード video4linux デバイス・ドライバにおけ る、VIDIOC_S_FBUF ioctl (2)コマンド CAP_SYS_RESOURCE このケーパビリティはユーザに以下のことを可能にします: ¾ ディスク割り当て制限を無効にします。 ¾ msgctl (2) IPC_SET コマンド上の IPC メッセージキューサイズ制限を無 効にします。 ¾ 非ルート・ユーザが CAP_SYS_ADMIN ケーパビリティを持たない時に、 fork (2)/clone (2)呼び出し上のプロセスあたりのプロセス数を無効にし ます。 ¾ setrlimit (2)システム・サービスでこのユーザのリソース制限を増大しま す。 ¾ リアルタイム・クロック(rtc)周期 IRQ レートを設定する、または 64Hz 以上 の周期における周期的 IRQ 割り込みを許可します。 ¾ コンソール・ターミナル・オープン/割り当ての数の制限を無効にします。 ¾ コンソール・キーボード keymap の数の制限を無効にします。 ¾ ufs、ext2、及び ext3 ファイル・システム上に追加的空間を割り当てる時、 保管されている空間の量の制限を無効にします。注: リソース無効をチ ェックする時、setfsuid (2)も使用して無効を有効にする時、ext2 ファイ ル・システムもファイル・システム・ユーザ ID を有効にします。 ¾ ext3 ファイル・システム上で、データ・ジャーナル・モードを修正します。 CAP_SYS_TIME このケーパビリティは以下のものを可能にします: ¾ clock_settime (2)、stime (2)、settimeofday (2)、及び adjtimex (2)経 由での時間の設定または調整。 ¾ /dev/rtc リアルタイム・クロック・デバイスにおける、RTC_SET_TIME 及 び RTC_EPOCH_SET ioctl (2)コマンドの使用 C-11 SUSE Linux Enterprise Real Time Linux User’s Guide CAP_SYS_TTY_CONFIG このケーパビリティは以下のものを可能にします: z vhangup (2)システム・サービスの使用 z ユーザがコンソール・ターミナルのオーナーではない場合も含める、全て のコンソール・ターミナル及びキーボード ioctl (2)コマンドの使用 ユ ー ザ が コ ン ソ ー ル ・ タ ー ミ ナ ル の オ ー ナ ー で あ る 時 も 、 KDKBDREP 、 KDSETKEYCODE、VT_LOCKSWITCH、及び VT_UNLOCKSWITCH コン ソール・ターミナル及びキーボード ioctl (2)コマンドはこのケーパビリティを要 求することに注意します。 C-12 SUSE Linux Enterprise Real Time Linux User’s Guide D カーネル・トレース・イベント この付録では、カーネル・モジュール内でカスタム・イベントを定義しそしてログするための方 法と同様に SUSE Linux Enterprise Real Time トレース及びデバッグ・カーネル内に含まれ るディフォルト定義のカーネル・トレース・イベントをキュー挙します。 どのようにしてユーザ・レベル・コード内でトレース・ポイントを供給し、トレース・データを取り 込み、そして結果を表示するのかに関する完全な説明については、NightTrace User’s Guide、出版番号 0890398 を参照してください。 ディフォルト定義カーネル・トレース・イベント 表 D-1 は、トレース及びデバッグ・カーネル内でディフォルト定義されている全てのカーネル・ トレース・イベントのリストを提供します。 表 D-1 ディフォルト定義のカーネル・トレース・イベント トレース・イベント の種類 System Call トレース・イベント名 説明 SYSCALL_ENTRY システムコールに入った。 (i386 システムのみ) システムコールから出た。 (i386 システムのみ) 32 ビット・システムコールに入った。 (X86_64 システムのみ) 32 ビット・システムコールから出た。(X86_64 システムの み) 64 ビット・システムコールに入った。(X86_64 システムの み) 64 ビット・システムコールから出た。(X86_64 システムの み) FBS システムコールが生成された。可能性のある種類には 以下のものが含まれる。 0 - fbsop 1 - fbsctl 2 - fbsget 3 - pmctl 4 - pmop 5 - fbswait 6 - fbstrig 7 - fbsavail 8 - fbsdir FBS 上でスケジュールされているプロセスがオーバランを 誘引した。 SYSCALL_EXIT SYSCALL32_ENTRY SYSCALL32_EXIT SYSCALL64_ENTRY SYSCALL64_EXIT FBS FBS_SYSCALL FBS_OVERRUN D-1 SUSE Linux Enterprise Real Time Linux User’s Guide 表 D-1 ディフォルト定義のカーネル・トレース・イベント(続き) トレース・イベントの種 トレース・イベント名 説明 TRAP_ENTRY トラップに入った 類 Traps Interrupts TRAP_EXIT トラップから出た。 IRQ_ENTRY IRQ ハンドラーに入った IRQ_EXIT IRQ から出た。 SMP_CALL_FUNCTION CPU 間割り込みで関数呼び出しが行われた REQUEST_IRQ 動的 IRQ 割り当てが生成された。 SOFT_IRQ_ENTRY softirq ハンドラーに入った。可能性のある種類には以下のものが 含まれる。 1- conventional bottom-half 2- real softirq 3- tasklet action 4- tasklet hi-action SOFT_IRQ_EXIT softirq ハンドラーから出た。 KERNEL_TIMER カーネル・タイマー割り込みルーチンが呼び出された。 Process SCHEDCHANGE スケジューラはコンテキスト・スイッチを生成した。 Management PROCESS プロセス管理機能が動作された。可能性のある種類には以下のも のが含まれる。 PROCESS_NAME 1- カーネル・スレッドが生成された 2- fork または clone 3- exit 4- wait 5- signal が送信された 6- wakeup このイベントはプロセス ID を fork、clone、または exec の前のプロ セス名と結合させる。 File System FILE_SYSTEM ファイル・システム機能が動作された。 可能性のある種類には以下のものが含まれる。 D-2 1- データ・バッファが開始するのを待つ 2- データ・バッファが終了するのを待つ 3- exec 4- open 5- close 6- read 7- write 8- seek 9- ioctl 10 - select 11 - poll SUSE Linux Enterprise Real Time Linux User’s Guide 表 D-1 ディフォルト定義のカーネル・トレース・イベント (続き) トレース・イベン トの種類 Timers トレース・イベント名 説明 TIMER Work Queues WORKQUEUE_THREAD タイマー機能が動作された。 可能性のある種類には以下のものが含まれる。 1 - タイマーの期限切れした 2 - set_timer()システムコール 3 - schedule_timeout()カーネル・ルーチン work キュースレッドが生成された。 work キューハンドラーが実行された。 メモリ管理機能が動作された。 可能性のある種類には以下のものが含まれる。 1 - ページ割り当て 2 - ページ開放 3 - ページのスワップ・イン 4 - ページのスワップ・アウト 5 - ページが開始するのを待つ 6 - ページが終了するのを待つ 追加のグラフィック連結ページが動的に割り当てられた。 ソケット機能が動作された。 可能性のある種類には以下のものが含まれる。 1 - 総称的ソケット・システムコール 2 - 生成されたソケット 3 - ソケット上へ送られたデータ 4 - ソケットからリードされたデータ System V IPC 機能が動作された。可能性のある種類には 以下のものが含まれる。 1 - 総称的 System V IPC 呼び出し 2 - 生成されたメッセージキュー 3 - 生成されたセマフォ 4 - 生成された共有メモリ・セグメント ネットワーク機能が動作された。可能性のある種類には以 下のものが含まれる。 1 - 受信されたパケット 2 - 送信されたパケット Linux ビッグ・カーネル・ロックがロックされた。 Linux ビッグ・カーネル・ロックがアンロックされた。 Linux ビッグ・カーネル・ロックが競合されている。 これはユーザ定義のイベント。 注: このイベントのロギング及び他のカスタム・カーネル・ト レース・イベントの動的な生成については、以下の“ユーザ 定義のカーネル・トレース・イベント”のセクションを参照す る。 WORKQUEUE_WORK Memory Management MEMORY GRAPHICS_PGALLOC Sockets SOCKET IPC IPC Networking NETWORK Big Kernel Lock (BKL) BKL_LOCK BKL_UNLOCK BKL_CONTEND Custom Event D-3 CUSTOM SUSE Linux Enterprise Real Time Linux User’s Guide 表 D-1 ディフォルト定義のカーネル・トレース・イベント(続き) トレース・イベント の種類 トレース・イベント名 説明 Kernel Trace BUFFER_START このイベントはトレース・バッファの始まりをマークする。 Management BUFFER_END このイベントはトレース・バッファの終わりをマークする。 PAUSE トレーシングは一時停止された。 RESUME トレーシングは再開された。 EVENT_MASK トレーシング・イベント・マスクは変更された。 EVENT_CREATED 新しいトレース・イベントが動的に生成された EVENT_DESTROYED 動的に生成されたトレース・イベントが破壊された。 ユーザ定義のカーネル・トレース・イベント どのユーザ定義の目的のためにも使用することができるディフォルト定義の“カスタム”カー ネル・トレース・イベントがあります。この CUSTOM カーネル・トレース・イベントの使用につい ては次のセクションで説明されます。他のユーザ定義のイベントは、以下の“動的カーネル・ト レーシング”のセクションで説明される呼び出しを使用することによって動的に生成することが できます。 ディフォルト定義の CUSTOM トレース・イベント TRACE_CUSTOM はディフォルト定義の CUSTOM trace event をログするのに使用されま す。呼び出し元は整数識別子(sub_id)を提供して CUSTOM イベントの複数使用を差異化し ます。呼び出し元はさらにイベントと共にログされるデータの恣意的なストリングも提供しま す。 概要 #include <linux/trace .h> void TRACE_CUSTOM (int sub_id, const void* ptr , int size) ; 引数は以下のように定義されます。 ユーザ供給の ID sub_id ptr イベントと共にログされる恣意的なデータへのポインタ size データのサイズ D-5 動的カーネル・トレーシング 上記で説明されたディフォルト定義の CUSTOM カーネル・トレース・イベントに加えて、ユー D-4 SUSE Linux Enterprise Real Time Linux User’s Guide ザ定義のカーネル・トレース・イベントを動的に生成することができます。分析のために全ては NightTrace によって表示されます。 動的カーネル・トレーシングのために、以下の呼び出しが使用されます。その説明は以下の 通りです。 z trace_create_event --- 使用されていないトレース・イベント ID を割り当て、そして それを与えられる名前と結合します。 z trace_destroy_event z TRACE_EVENT --- --- イベント ID の割り当てを取り消します。 動的イベントをログするのに使用される総称的トレース・ポイン ト関数です。 trace_create_event この呼び出しは使用されていないトレース・イベント ID を割り当て、そしてそれを与えられる名 前と結合します。 概要 #include <linux/trace .h> int trace_create_event (const char* name) ; 引数は以下のように定義されます。 name トレース・イベントにおいて、ユニークなユーザ定義の名前です。この名前は 31 文 字までに短縮されます。 イベント ID は返ります。最近使用されていなかった(生成され、そして破壊される)ID を返す 試みがなされます。EVENT_CREATED トレース・イベントはこの呼び出しでログされます。 失敗すると、以下の中の 1 つが返されます。 -ENOSPC 全ての動的イベント ID が使用中です。 -EINVAL 与えられている名前ポインタは NULL または NULL ストリングへのポイントです -EEXIST 与えられている名前はユニークではありません。 -ENOMEM メモリ割り当てエラーです。 trace_destroy_event この呼び出しは、create_trace_event で割り当てられているトレース・イベント ID の割り当て を取り消します。 概要 D-5 SUSE Linux Enterprise Real Time Linux User’s Guide #include <linux/trace .h> void trace_destroy_event (int id) ; 引数は以下のように定義されます。 id create_trace_event と共に割り当てられていたイベント ID です。 EVENT_DESTROYED トレース・イベントはこの呼び出しでログされます。 TRACE_EVENT 新しく生成された動的トレース・イベントにおいて、トレース・ポイントをログするのにこれは使 用されます。 概要 #include <linux/trace .h> void TRACE_EVENT (int id, const void* ptr, int size) ; 引数は以下のように定義されます。 id イベント ID です。 ptr イベントと共にログされる恣意的なデータへのポインタです。 size データのサイズです。 D-6 SUSE Linux Enterprise Real Time Linux User’s Guide E 32 ビット・コードから 64 ビット・コードへの変換 この付録では、 32 ビット・コードを X86_64 アーキテクチャ上の 64 ビット・プロセッシングへと 変換するために必要な情報を提供します。 イントロダクション SUSE Linux Enterprise Real Time は 64 ビット AMD OpteronCPU 上で、実行することがで きます。SUSE Linux Enterprise Real Time の Opteron バージョンは完全な 64 ビットオペレ ーティング・システムで、それは OpteronCPU 上をネイティブ・モードで 32 ビット及び 64 ビット・ アプリケーション両方を実行します。 Opteron プロセッサはほとんど EM64T ISA をサポートする最近のインテルプロセッサ(例 えばすべてのインテル Nocona プロセッサ)とまったく同じの AMD64 命令セットアーキテ クチャ(ISA)を利用します。 AMD64 と EM64T 両方が本当の64ビットの実行の能力があ って、そして集合的に「x86_64」アーキテクチャとして知られています。 x86_64 プロセッサの“long” 実行モードは「64ビット」と「互換性」の2つのサブモードを持っ ています。 既存の 32 ビット・アプリケーション・バイナリは再コンパイルの必要が無く互換性モードで走る ことができ、またはアプリケーションを再コンパイルして 64 ビット・モードで走らせることができ ます。 32 ビット・アプリケーションは、パフォーマンスを低下させる“エミュレーション・モード”無しにネ イティブで走ることができます。この理由のため、多くのアプリケーションは 64 ビットへ移植さ れる必用がありません。 x86_64 に最適化されたソフトウェアは大きなアドレス指定可能メモリ、及び科学計算、データ ベース・アクセス、シミュレーション、CAD ツール、etc.のような最も要求度の高いアプリケー ションが要する構造的高位化を利用することができます。もしもアプリケーションが 64 ビット 処理が与えるより大きなバーチャル及び物理アドレス空間から恩恵を受けるなら、このセクシ ョン内の情報はコードを変換するヘルプになります。 既存の 32 ビット・アプリケーションの 64 ビットへの移植は以下のエリアを含み、それは以下に 続くセクション内で詳細に論じられます。 ・ 32 ビット向けに書かれたソース・コードは 64 ビット・モードで実行するためにおそらく 修正を要します。 E-1 SUSE Linux Enterprise Real Time Linux User’s Guide ・ 32 ビット・オペレーションにおいてコンパイルされたバイナリは、64 ビット・モードで走 らせられる前に、64 ビット向けに再コンパイルされる必用があります。 ・ 構築プロセス(makefile、 project file、etc.)は実行可能 64 ビットを構築するために アップデートされる必要があり、そしてコンパイルのために移植性チェック・オプション を追加します。 ・ 64 ビット・デバイス・ドライバのみが 64 ビット・オペレーティング・システムで使用する ことができます。もしも要求されるドライバの 64 ビット・バージョンが無ければ、デバイ ス・ドライバをインストールするアプリケーションは正確に動作しません。SUSE Linux Enterprise Real Time で供給される全てのドライバは 64 ビット互換性があります。 追加として、以下のことが論じられます。 ・ アプリケーションで最大のパフォーマンスを取得するヒント。 ・ 32 ビットと 64 ビットとの間の SUSE Linux Enterprise Real Time 機能性の差異。 AMD64 Developer Resource Kitは、移植をするプログラマまたはOpteronCPUにおける アプリケーション及びドライバの開発において完全なリソースです。ADM64 DRKはドキュメン テーションを含む専門的情報、白紙、詳細なプレゼンテーション及び参照ガイドを含みます。 このキットは www.amd.comウェブサイトから入手可能です。 E-2 SUSE Linux Enterprise Real Time Linux User’s Guide 手順 64 ビットへの移植ためのコード修正に体系的に取り組むために、以下のガイドラインに従い ます。ヘッダ/インクルード・ファイル、リソース・ファイル、及び makefile を含む全てのソース・ ファイルが相応に見直されそして修正されるべきです。これらのステップに関する特性は後に 続くセクション内で提供されています。 ・ ADM64 アーキテクチャに特定のコードにおいて、#if defined___amd64___を使用 します。 ・ 内在関数またはネイティブ・アセンブリ・サブルーチンを使用するために、全てのイン ライン・アセンブリ・コードを変換します。 ・ 必用に応じ、既存のアセンブリ・コード内で呼び出し慣例を修正します。 ・ どのポインタ算術の使用も見直し、そして結果を確認します。 ・ ポインタ、整数、及び物理アドレスへの参照を見直し、そして変数サイズ・データ・タ イプを使用して、32 ビットと 64 ビット・アーキテクチャの相違を受け入れます。 ・ makefile を調べて実行可能な 64 ビットを構築し、そして移植性チェック・オプションを 追加します。 コーディング要求 データ・タイプ・サイズ 32 ビットと 64 ビットとの移植性での主な事項は、アドレスのサイズまたは int、long、etc.のサ イズへのその関係性についての仮定が無いことです。 表 E-1 は ADM64 システム上の SUSE Linux Enterprise Real Time 下での様々な ANSI デ ータのサイズを示しています。 表 E-1 データ・タイプのサイズ ANSI データ・タイプ char short int long long long intptr_t、 uintptr_t float double long double バイトでのサイズ 1 2 4 8 8 8 4 8 16 様々なデータ・タイプのサイズを取得するために、sizeof オペレータを使用することができま す。例として、もしも変数 int x があれば、sizeof (x)で x のサイズを取得することができます。 この使用法は構造または配列においても当てはまります。例として、名前 a_struct で構造タ イプの変数があれば、どれほどのメモリをそれが占めているかを確認するために sizeof (a_struct)を使用することができます。 E-3 SUSE Linux Enterprise Real Time Linux User’s Guide Long long は 64 ビットになります。よって、全ての直接的または潜在的割り当て、または long と int 値との間の比較を調べる必用があります。有効性を確実にするためにコンパイラが割り当て 及び long と整数との間の比較を受理することを可能にする全てのキャストを調べます。 BITS_PER_LONG macro の値を使用して、long のサイズを確認します。 もしも int と long が異なるサイズでとどまらなければならないなら(例として、既存する public API 定義のために)、64 ビット・アイテムは 32 ビット・アイテムの最大値を超過しないことを確 認する宣言を実行し、そしてもしもそれが起こるなら、そのケースを扱う例外コンディションを 生成します。 ポインタ ポインタは 64 ビットになります。よって、全ての直接的または潜在的割り当て、またはポイン タと int 値との間の比較も調べる必用があります。コンパイラが割り当て及びポインタと整数と の間の比較を受理することを可能にする全てのキャストを取り除きます。タイプを変数サイズ の(ポインタ・サイズに等しい)タイプへ変更します。表 E-2 は様々なサイズのデータ・タイプを 示します。 表 E-2 変数サイズ・データ・タイプ ANSI データ・タイプ 定義 intptr_t ポインタを保持する符号付整数タイプ uintptr_t ポインタを保持する符号無し整数タイプ ptrdiff_t 2 つのポインタ値の符号付相違を保持する符号付タイプ size_t それにポインタが参照することができるバイトの最大数を示す符号無し値 ssize_t それにポインタが参照することができるバイトの最大数を示す符号付値 配列 32 ビット・コード下では、配列のサイズを保持するために int と long を使用することができま す。64 ビット下では、配列は 4GB以上にすることができます。int または long の代わりに、移 植のために size_t データ・タイプを使用します。64 ビット・ターゲット向けにコンパイルされる 時は、それは 64 ビット符号付整数タイプになり、または 32 ビット・ターゲットでは、32 ビットで す。sizeof ( )と strlen ( )の両方からの返り値は size_t の両方のタイプになります。 E-4 SUSE Linux Enterprise Real Time Linux User’s Guide 宣言 表 E-2 内で示されているサイズ変形タイプの 1 つを使用するために 64 ビットに変更されなけ ればならない、変数、パラメータ、または関数/方法の返りタイプのどの宣言も変更する必要 があります。 明確なデータ・サイズ データ・サイズを明確にアドレスする必要がある時、表 E-3 内のデータ・タイプを使用します。 特にデータ・サイズをアドレスする ANSI データ・タイプはありません。これらのタイプは Linux に特定のものです。 表 E-3 固定されている正確データ・タイプ データ・タイプ 定義 int64_t 64 ビット符号付整数 uint64_t 64 ビット符号無し整数 int32_t 32 ビット符号付整数 uint32_t 32 ビット符号無し整数 int16_t 16 ビット符号付整数 uint16_t 16 ビット符号無し整数 int8_t 8 ビット符号付整数 uint8_t 8 ビット符号無し整数 定数 定数、特に 16 進または 2 進値は、32 進特定にありやすいものです。例として、64 ビットでの 32 ビット定数 0x80000000 は 64 ビットでは 0x0000000080000000 になります。どのように それが使用されているのかに依存して、結果は望ましくないものです。~オペレータとタイプ・ サフィックスを最大限に利用してこの問題を回避します。例として、0x80000000 定数は、代 わりに ~0x7ffffffful としての方がよりよいものです。 API 64 ビット API を使用するためにコードは変更される必要があります。コンパイラが明確な 32 ビット・データ・タイプとの競合の中で 64 ビットとして解釈するデータ・タイプをいくつかの API は使用します。 呼び出し手続き 関数呼び出し元及び呼び出され元によってどのように CPU・レジスタが使用されるかを呼び E-5 SUSE Linux Enterprise Real Time Linux User’s Guide 出しが手続きが取り決められています。C コードで相互動作する手でコードされたアセンブリ・ コードを移植する時、そしてイン・ライン・アセンブリ・ステートメントにおいてこれは適用されま す。X86_64 における Linux 呼び出し手続きは表 E-4 内で示されています。 表 E-4 呼び出し手続き レジスタ ステータス 使用 %rax Volatile 一時的レジスタ; 変数引数が、使用 されている SSE レジスタ数について の情報を渡す; 最初の返りレジスタ %rbx オプション的にベース・ポインタとして Non-volatile 使用され、呼び出されによって保存さ れなければならない %rdi, %rsi, %rdx, %rcx, %r8, %r9 Volatile %rsp Non-volatile Non-volatile %rbp 整数引数 1,2,3,4,5,6 を渡すのに使 用される スタック・ポインタ オプション的にフレーム・ポインタとし て使用され、呼び出されによって保存 されなければならない %r10 Volatile %r11 %r12-%r15 Volatile Non-volatile %xmm0-%xmm1 Volatile %xmm2-%xmm7 Volatile %xmm8-%xmm15 Volatile Volatile Volatile 一時的レジスタ; 関数の静的チェー ン・ポインタを渡すのに使用される 一時的レジスタ 呼び出されによって保存されなけれ ばならない 浮動小数点引数を渡し、返すのに使 用される 浮動小数点引数を渡すのに使用され る。 %mmx0-%mmx7 %st0 一時的レジスタ 一時的レジスタ 一時的レジスタ; long double 引数を 返すのに使用される %st1-%st7 %fs 一時的レジスタ Volatile Volatile スレッド特定データ・レジスタとしての システム使用のために保存される 条件的コンパイル 32 ビット対 64 ビット実行において条件的コードを供給する必要がある場合、表 E-5 内の macro を使用することができます。 表 E-5 条件的コンパイルのための macro E-6 Macro 定義 ___amd64___ コンパイラは AMD64 のためにコードを生成する __i386 コンパイラは x86 のためにコードを生成する SUSE Linux Enterprise Real Time Linux User’s Guide その他 様々な他の事項が、符号拡張、メモリ割り当てサイズ、シフト・カウント、及び配列オフセットか ら生まれます。整数オーバフローの解釈についての仮定を作るどのコードにも特に注意しま す。 コンパイル 既存の makefile は、x86_64 CPU 上で実行可能な、少しまたは修正の無いネイティブ 64 ビ ットを構築します。 以下の gcc スイッチは移植の事項をキャッチするのに使用することができます。詳細につい ては、 gcc (1) man page を参照してください。 -Werror -Wall -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wuninitialized -ansi -pedantic -Wbad-function-cast -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decl 評価/デバッグ 64 ビット・コードにおける標準的 SUSE Linux Enterprise Real Time 評価及びデバッグ・テク ニックに従います。 パフォーマンス事項 このセクション内での情報は、どのようにして 64 ビット・アプリケーションから最良のパフォー マンスを得るのかについて論じています。 メモリ整列及び構造パディング 整列事項は例外を生みませが、パフォーマンス・ヒットを引き起こします。いくつかのクロック・ サイクルを犠牲にして非整列は稼動中に扱われます。下手に整列されたオペランドのパフォ ーマンス副作用は大きなものです。 構造内のデータは自然境界線上に整列され、それは無駄な空間のために非効率的なコード を生みます。自然配列とは、2 バイト・オブジェクトは 2 バイト境界線上に記憶され、4 バイト・ E-7 SUSE Linux Enterprise Real Time Linux User’s Guide オブジェクトは 4 バイト境界線上に、etc.を意味します。 例として、64 ビット・コードを生成する時に以下の構造定義が 24 バイトを消費します。 typedef struct _s { int x ; int *p ; int z ; } s , *ps ; ポインタ p は 8 バイト境界線上に整列され、それは x メンバの後のパディングの 4 バイトの追 加を引き起こします。さらに、z メンバの後にパディングの追加の 4 バイトがあり、それは構造 を偶数の 8 バイト境界線へとパッドします。 構造の中で最大のものから最小のものへとメンバを配置することによって、最も効率的な構 造パッキングが得られます。以下の宣言はさらに効率的です。それは 16 バイトのみを取り、 そしてどのパディングも要求しません。 typedef struct _s } int *p ; int x ; int z ; }s; 潜在的パディングのために、構造内でフィールドの定オフセットを見つける最も安全な方法は、 offsetof ( ) macro を使用することです。それは stddef .h 内で定義されています。 E-8 SUSE Linux Enterprise Real Time Linux User’s Guide F シールドされている CPU 上のカーネル・レベル・デーモン Linux カーネルはシステム機能を動作するために多くのカーネル・デーモンを使用します。こ れらのデーモンのいくつかは、システム内の個々の CPU 上で複製されます。プロセスからの CPU のシールディングはこれらの“CPU あたり”デーモンを取り除きません。 以下のデーモンは、プロセス・シールドされている CPU 上で重大なジッター問題を生みます。 幸運なことに、システムを注意深くコンフィグし使用することによってこれらのデーモンを回避 することができます。 kmodule CPU これらのデーモンはカーネル・モジュールがアンロードされるたびに生成されそ して実行されます。 システム上をリアルタイム・アプリケーションが走っている間は、カーネル・モジ ュールがアンロードされないことが極めて推奨されます。 migration/CPU これらは特定の CPU からタスクを移動させて取るためのタスク移動デーモン です。その CPU 上を走っているプロセスがその CPU から移動されて取られる ことが強制されなければ、これらのデーモンはプロセス・シールドされている CPU 上を走ります。以下のインターフェイスのどれかが使用される時、強制移 動が起こります。 /proc/pid/affinity sched_setaffinity (2) /proc/shield/procs cpucntl (2) delete_module (2) シールドされている CPU 上を走っているアプリケーションはこれらのインターフ ェイスを、バックグランド・プロセス・ジッターが許容される時にのみ使用するべ きです。 強制移動はさらに様々なカーネル・インターフェイスによっても成され、それは CPU_FREQ 及び NUMA カーネル・コンフィグレーションで許可することができ ます。全ての SUSE Linux Enterprise Real Time カーネル・コンフィグレーショ F-1 SUSE Linux Enterprise Real Time Linux User’s Guide ン内でデフォルトでこれらのオプションは禁止されています。 kswapdnode これらはページ・スワップ・アウト・デーモンで、それはスワップ・デバイスへペー ジをスワップ・アウトしメモリ稼動が低い時にページを再要求します。 カーネルが NUMA コンフィグレーション・オプションが許可されて構築される時、これらのデー モンがいくつかあり、それぞれが単一 CPU へバイアスされています。NUMA が禁止される時、 どの特定の CPU へもバイアスされていないシステム・ワイド・デーモンが 1 つあります。全て の SUSE Linux Enterprise Real Time カーネル・コンフィグレーションではデフォルトで NUMA は禁止されています。NUMA が禁止されている時、これらのデーモンは CPU あたり ではなく、よって、プロセスからシールドされている CPU 上で kswapd は走らず、そしてシー ルドされていない CPU 上の問題であるだけです。 kapmd これは Advanced Power Management (APM)デーモンで、それはパワー管 理要求を処理します。それは常に CPU 0 にバイアスされています。APM はカ ーネル・ブート・パラメータ“amp=off”で禁止され、または APM カーネル・コンフ ィグレーション・オプションを禁止することによって完全に消されます。全ての SUSE Linux Enterprise Real Time カーネル・コンフィグレーション内で APM はデフォルトで禁止されています。このデーモンは CPU あたりのデーモンでは ないので、プロセスからシールドされている CPU 上ではそれは走らず、よって シールドされていない CPU 上のみの問題です。 以下のデーモンはプロセス・シールドされている CPU 上で実行します。しかし、その CPU へ バイアスされているプロセスまたは割り込みのために必用な機能を動作し、そしてこれらのデ ーモンはシールドされている CPU へバイアスしているプロセスまたは割り込みによって開始 されたアクションの結果として起動されたのみなので、これらのデーモンは決定性上へのそ れらの影響においてはより問題度が低いとみなされます。 ksoftirqd/CPU これらは特定の CPU において softirq ルーチンを実行する softirq デーモンで す。もしもその CPU へバイアスされているデバイス・ドライバ割り込みハンドラ ーがタスクレット経由で直接的にまたは間接的に softirq を使用すれば、これら のデーモンのの 1 つはプロセス・シールドされている CPU 上を走ります。 softirq は、ローカル・タイマー、SCSI、そしてネットワーキング割り込みハンドラ F-2 SUSE Linux Enterprise Real Time Linux User’s Guide ーによって直接的に使用されます。タスクレットは多くのデバイス・ドライバによ って使用されます。 ksoftirqd のプライオリティは、カーネル・コンフィグレーション GUI 上の General Setup 下に位置する SOFTIRQ_PRI チューニング可能カーネルによ って決定されます。デフォルトではこのチューニング可能値はゼロに設定され ており、それは ksoftirqd デーモンが、最高リアルタイム・プライオリティより 1 つ低いプライオリティの SCHED_FIFO スケジューリング・ポリシー下で走るこ とを示します。このチューニング可能を正値へ設定すると、全ての ksoftirqd デーモンへ割り当てられるリアルタイム・プライオリティ値を指定することになり ます。 events/CPU これらは特定の CPU 上でプロセスによって開始される様々なカーネル・サービ スのために作業を行うデフォルトの作業キュースレッドです。それらは同じ CPU へバイアスされたデバイス・ドライバ割り込みルーチンによって遅延され た作業も行います。これらのデーモンは-10 の良い値で実行します。 aio/CPU これらは特定の CPU 上のプロセスによる io_submit (2)システムコールで開 始された非同期 IO 要求を完了する作業キュースレッドです。これらのデーモン は-10 の良い値で実行します。 reiserfs/CPU これらは Reiser File System によって使用される作業キュースレッドです。こ れらのデーモンは-10 の良い値で実行します。 xfsdatad/CPU xfslogd/CPU これらは IRIX Journaling ファイル・システム(XFS)によって使用されている作 業キュースレッドです。これらのデーモンは-10 の良い値で実行します。 cio/CPU kblockd/CPU wanpipe_wq/CPU これらは様々なデバイス・ドライバによって使用されている作業キュースレッド F-3 SUSE Linux Enterprise Real Time Linux User’s Guide です。これらのスレッドは特定の CPU 上のプロセスによって開始される様々な カーネル・サービスのために作業を行います。それらは同じ CPU へバイアスさ れたデバイス・ドライバ割り込みルーチンによって遅延された作業も行います。 これらのデーモンは-10 の良い値で実行します。 どの第 3 パーティ・ドライバもプライベート作業キュー、及びシールドされている CPU へバイア スされているプロセスまたは割り込みハンドラーによって誘引された作業キュースレッドを生 成することに注意します。これらのデーモンは常に name/CPU と名付けられ、そして-10 の良 い値で実行します。 F-4 SUSE Linux Enterprise Real Time Linux User’s Guide G シールドされている CPU 上の CPU 間割り込み この付録ではシールドされている CPU 上の CPU 間割り込みの影響について論じます。 概要 1 つまたはそれ以上のシールドされている CPU でコンフィグされている SUSE Linux Enterprise Real Time プラットフォーム上では、他の CPU 上の動作が、割り込みのシールド されている CPU への送信を引き起こします。これらの CPU 間割り込みは、それ自身のデー タ・キャッシュをフラッシュする、またはそれ自身の Translation Look-aside Buffer(TLB)・キ ャッシュをフラッシュするのようないくつかの CPU あたりに特定のタスクを扱うことを他の CPU へ強制する方法として使用されます。 CPU 間割り込みはシールドされている CPU において認知されるジッタ-を潜在的に引き起こ すため、これらの割り込みの発生を引き起こす動作、及びどのようにしてシステムをコンフィ グすればこれらの割り込みのいくつかを無くすことができるのかを論じることは有益です。 メモリ・タイプ領域レジスタ(MTRR)割り込み Intel P6 ファミリー・CPU(Pentium Pro、Pentium II、及び以降)上では、メモリ・タイプ領域レ ジスタ(MTRR)はメモリ領域への CPU のアクセスを制御するのに使用することができます。 PCI または AGP バス上にビデオ(VGA)・カードがある時に、これは最も有益です。ライト組合 せの許可によって、PCI/AGP バス上でバーストする前にバス・ライト・トランスファをより大き なトランスファ内へ組み合わせることが可能です。これはイメージ・ライト・オペレーションのパ フォーマンスを 2.5 倍またはそれ以上増大します。 MTTR は有益なパフォーマンス恩恵を提供しますが、新しい MTTR 領域がセット・アップされ るかまたは取り除かれた場合はいつでも、それぞれの CPU にそれらの CPU あたりの MTTR レジスタを相応に修正させるために、CPU 間割り当てが全ての他の CPU へ送られます。こ の特定の割り込みを処理するのに要する時間はとても長いものです。なぜなら、システム内 の全ての CPU はそれらがそれらそれぞれの MTTR レジスタを修正する前に最初に sync-up/handshake をしなければならず、そしてそれらがそれらそれぞれの割り込みルーチ ンを出る前にまた再び handshake しなければならないからです。このクラスの CPU 間割り込 みは、割り込みあたりに最大 3 ミリ秒まで計測されていた決定性に強烈な影響を与えます。 システム・ブート後 X サーバが最初に起動される時、MTTR 領域はセット・アップされ、そして これらの MTTR CPU 間割り込みの1つがシステム内の全ての他の CPU へ送られます。同 G-1 SUSE Linux Enterprise Real Time Linux User’s Guide 様に、X サーバが終了する時この MTTR 領域は取り除かれ、そしてシステム内の全ての他 の CPU はまた他の MTTR 割り込みを受けます。 MTTR 関連の CPU 間割り込みがシールドされている CPU 上のタイム・クリティカル・アプリ ケーション実行の間に起こらないようにするために使用することができる 3 つの方法がありま す。 1. カーネルを再コンフィグして MTTR カーネル・コンフィグレーション・オプションを禁止させ ます。カーネル・コンフィグレーション GUI を使用する時、このオプションは Processor Type and Features セクション下に位置し、そして“MTTR(メモリ・タイプ領域レジスタ)サ ポート”として参照されます。この場合、この機能のためのカーネル・サポートはもはや存 在しないので、MTTRCPU 間割り込みはありません。この選択はグラフィック IO オペレ ーションにおいて潜在的に厳しいペナルティを持つことに注意します。 2. シールドされている CPU 上でタイム・クリティカルなアプリケーションを走らせる前に X サ ーバを起動し、そしてタイム・クリティカルな動作が完了するまで X サーバを稼動し続け ます。この場合、MTTR 割り込みはまだ起こりますが、タイム・クリティカル動作間では起 こりません。 3. CPU 間割り込みが起こらないように MTTR 領域を事前コンフィグすることができます。X サーバによって使用される MTTR の事前コンフィグレーションにおいて、以下の手順を 使用します。 a. システムがブートされ、しかし X サーバが起動する前に、現在の MTTR セッティング を調べます。 cat /proc/mtrr reg00: base=0x00000000 ( 0MB), size=1024MB: write-back, count=1 reg01: base=0xe8000000 (3712MB), size= 128MB: write-combining, count=1 注:X サーバが起動する前に MTTR セッティングを調べるために、init 状態 1 または 3 である必要があります。 b. X サーバが起動した後、MTTR レジスタ・セッティングを再び調べます。 cat /proc/mtrr reg00: base=0x00000000 ( 0MB), size=1024MB: write-back, count=1 reg01: base=0xe8000000 (3712MB), size= 128MB: write-combining, count=2 reg02: base=0xf0000000 (3840MB), size= 128MB: write-combining, count=1 G-2 SUSE Linux Enterprise Real Time Linux User’s Guide c. この例では、新しい X サーバ・エントリは最後のエントリ“reg02”です。もしもシステム にマルチプル・グラフィック・カードがあるか、または 1 つ以上の新しいエントリを示すなら、 これらの追加のエントリも追加の rc .local スクリプト・エントリで取り入れられるべきで す。 d. そして X サーバ MTTR エントリへアカウントするために/etc/rc .d/rc .local スクリプト に追加の行をを加えます。この例では、アカウントするただ 1 つの X サーバ・エントリがあ るだけです。 echo “base=0xf0000000 size=0x8000000 type=write-combining” > /proc/mtrr e. システム上でハードウェア・コンフィグレーションが修正される時はいつでも /etc//re .d/rc .local ファイル内の MTTR エントリがまだ正確であるのかをチェックするの は良いことです。単純に X サーバを起動し、そして以下を使用して: cat /proc/mtrr MTTR 出力を調べ、そして先の MTTR セッティングからのどの相違もチェックします。 グラフィック割り込み グラフィックスアプリケーションを走らせる間は、多くのプロセッサ間割り込みが発生します。 これらは以下の様な操作です: ビデオRAMアクセス - PCI あるいは PCI 、PCI Express AGP のNVIDIA グラフィックスカ ードを含んだシステムでXサーバーが始動させられるときはいつでも、ビデオ RAM エリアが アクセスされ、2つの TLB フラッシュプロセッサ間割り込みが発生します。 AGP バインディング - AGP システムで、 NVIDIA ドライバのようなカーネルグラフィック スドライバがカーネルメモリバッファを割り当てて、そして次にそのバッファに AGP メモリバ インディングを作成するでしょう。 これらのバインディングが加えられるか、あるいはグラフィ ックス実行の間に取り去られるときはいつでも、2つのプロセッサ間割り込みが最初に、それ らのデータキャッシュをクリアして、そして次にそれらのカーネル TLB 置き換えをクリアする ために他のCPUに送られます。 プロセッサ間割り込みのこのクラスは割り込み毎に、50か ら250マイクロセカンドと計測されるためかなりひどい影響に見舞われます。 これらのバインディングは、以下の場合に発生します: z Xサーバーを開始するか、あるいは終了する場合。 z グラフィックスアプリケーションが走っているとき。 z Ctrl Alt F # キーボードのシーケンスでグラフィックススクリーンに戻って非グラフィック スの tty へ汎化するとき。 DMA バッファアロケーション - DMA バッファの使用のために物理的なページを割り当て て、そしてリリースするとき、ジッターが NVIDIA ドライバによって起こされます。 G-3 SUSE Linux Enterprise Real Time Linux User’s Guide これらのタイプのプロセッサ間割り込みは削除されるか、あるいは、 cacheinhibitedな ページのプールが前もって割り当てられれば、減少させられます。 AGP メモリバイ ンドとしてグラフィックスバッファアロケーションがリクエストされるとき、必要な ページはページのフリーリストから取られます。これらのページが使われるとき、こ れらのページがすでに cache-inhibited なら、追加のフラッシュオペレーションを発行 する必要がありません。アロケーションあるいはバインディングが取り去られるとき、 ページはページフリーリスト のcache-inhibit-clean の後ろに置かれます。 もしリクエ ストされるとき、前もって割り当てられたページのプールが空であったなら、ページ が動的に割り当てられるでしょう、そしてプロセッサ間割り込みが標準的な方法で出 されるでしょう。 そのために、利用可能なページのプールが決して空にならないよう に、十分なページを前もって割り当てることが最も最適です。 このサポートを可能にするために、 PREALLOC_GRAPHICS_PAGES カーネルパラメ ータは前もって割り当てられたページの正のプール数を持っていなくてはなりません。 10240の値がすべての前もって定められた SUSE Linux Enterprise Real Time カーネル でデフォルトで設定されます。 もし0(ゼロ)の値がカーネルパラメータに設定され るなら、この機能は使用不能になります。 PREALLOC_GRAPHICS_PAGES オプショ ンはカーネルコンフィギュレーション GUI の Device Drivers -> Character Devices 細 別の下に位置しています。 このオプションはAGP ハードウェアであるいは NVIDIA PCI/PCI Express カード1つ以上がサポートされます。この機能が使用可能であるとい う状態で、ビデオ RAM エリアがアクセスされるとき、通常起こる TLB フラッシュ プロセッサ間割り込みは、システムブートアップのみにおいて一つの TLB フラッシ ュクロスプロセッサ割り込みに減らされることに注意してください。 The /proc/driver/graphics-memory file can be examined while running graphics 値を調整するべきであるかどうか決定するために、いつでも実際に使用中のグラフィ ックスメモリページの最大の量を観察することができます。これは、グラフィックス アプリケーションを走らせる間に、 /proc/driver/graphics-memory ファイルを調べる ことで実現されます.。例えば: $ cat /proc/driver/graphics-memory Pre-allocated graphics memory: Total allocated graphics memory: Graphics memory in use: Maximum graphics memory used: 10240 pages 10240 pages 42 pages 42 pages あなたはプールのページ数を増やすか、あるいは減少させるために、 /proc/driver/graphics-memoryファイルに書き込む事が出来ます。 この方法は、カーネ ルコンフィギュレーションパラメータを変える前に、あなたに種々の値であなたのシ ステムをテストすることを許します。 次の例は5120にプールで前もって割り当て られたページの数を減少させます: $ echo 5120 > /proc/driver/graphics-memory ユーザーはこのファイルに書き込む CAP_SYS_ADMIN 権限を持っていなくてはなり G-4 SUSE Linux Enterprise Real Time Linux User’s Guide ません。 ファイルに書き込まれたページ値が、「使用中のグラフィックスメモリ」フ ィールドの現在値と等しいか大き区無くてはならないことに注意しなくてなりませ ん。。 もし現在割り当てられたページの数が下げられる必要があるなら、Xサーバー を終了してください。 非現実的に大きい値を指定することはページアロケーション故障をもたらすでしょう、 そしてアロケーションは保証外であるでしょう。 ファイルに書き込んだ後で、ページ アロケーション変更が成功していたことを確かめるためにファイルを読んでください。 NVIDIA ドライバがロードされるか、あるいはアンロードされるとき、ページ Attribute テーブル(軽いひとたたき)クロスプロセッサ割り込みがそれぞれのCPUに送られ ることに注意を払ってください。 複雑な jitter を最小にするために、タイムクリティ カルアプリケーションの実行中にNVIDIA モジュールをロードするか、あるいはアン ロードするのを避けてください。 タイムクリティカルアプリケーションを走らせる前 に、あなたは NVIDIA ドライバを前もってロードするか、あるいはシステムの間に次 のコマンドでブートしなければなりません: $ modprobe nvidia カーネル TLB フラッシュ割り込み カーネル・バーチャル空間変換の様々なタイプが加えられるまたは取り除かれる時に、カー ネル TLB フラッシュ・CPU 間割り込みが起こります。カーネル変換のいくつかのタイプにおい ては、新しい変換が生成される時に割り込みは送られます。他のタイプにおいては、変換が 取り除かれる時に割り込みは送られます。このクラスの CPU 間割り込みは、割り込みあたり 10 マイクロ秒以下に計測されている最小の影響を持ちます。 vmalloc 及び ioremap カーネル TLB フラッシュ・CPU 間割り込みが起こる回数を減少する修 正が SUSE Linux Enterprise Real Time 内で生成されました。修正されたアルゴリズムは、 最後に割り当てられたバーチャル・アドレスの終端で利用可能なカーネル・バーチャル空間に おいて新しいサーチを始めます。サーチがバーチャル空間エリアの始まりを包む時のみに TLB フラッシュは起こります。フラッシュされる前に開放されようとしているエリアを再割り当て することから防ぐための措置が生成されています。 カーネル・バーチャル空間を繰返し割り当てそして開放すると、時間経過においてバーチャ ル・エリアを欠片にします。さらに連続した割り当て空間を提供しそしてフラグメンテーションを 減少するために、バーチャル・エリアは概念的に 2 つの部分に分けられます。より小さい割り 当てが生成されるエリア、そしてより大きな割り当てが生成されるエリアです。これら 2 つのセ クションの制御は 2 つのカーネル・コンフィグレーション・パラメータを通して提供されます。こ れら 2 つの別々のエリアへの割り当ては個別に扱われます。これらのセクションの 1 つの終 端に達する時、割り当てはそのセクションの初めを包み込みます。どちらかのセクションが包 G-5 SUSE Linux Enterprise Real Time Linux User’s Guide み込む時、両方のセクションはそれが起こるシステム・ワイド TLB フラッシュの利点を利用す るために包み込みます。 以下のカーネル・コンフィグレーション・パラメータはこの機能性を許可しそして制御します。そ れらは、カーネル・コンフィグレーション GUI の General Setup オプション下でアクセス可能で す。 VMALLOC_TLBFLUSH_REDUCTION vmalloc TLB フラッシュの縮小におけるアルゴリズムを許可します。 VMALLOC_SMALL_RESERVE メガバイトで空間量が大きな割り当てにおいて取って置かれるように定義 します。デフォルトとして指定されている値は全体の vmalloc バーチャル 空間エリア(VMALLOC_RESERVE)のデフォルト・サイズのおおよそ半 分です。 もしもさらに連続した空間が必要とされ、そしてこの値が i386 システム上 で 大 き く 増 大 さ れ る 必 要 が あ れ ば 、 可 能 で あ れ ば VMALLOC_RESSERVE における値も増大されます。(x86_64 プラットフ ォームは固定されている 512GB vmalloc バーチャル空間サイズを持ち、 そして VMALLOC_RESERVE パラメータは使用されていないことに注意 します。)もしも大きな連続した vmalloc 要求が必要とされなければ、より 小さい値の指定は vmalloc 生成のカーネル TLB フラッシュ割り込みの数 を僅かに縮小します。 VMALLOC_LARGE_THREASHOLD_SIZE 大きな vmalloc バーチャル・エリア内で割り当てが生成される時を決定する サイズを、メガバイトで定義します。 全体の及び使用された vmalloc 割り当て、小さい及び大きなエリア別々にそ して大きな閾値においてフリーな(chunk)最大の連続 vmalloc エリアを含む 現在の値をビューするのに、/proc/vmalloc-reserve-info ファイルをリード することができます。/proc/meminfo からの出力は、全体の(小さいもの及 び大きいもの)バーチャル空間エリア及び 2 つの小さい/大きい chunk 値の より大きいものにおける全体の及び使用された量を表示します。 G-6 SUSE Linux Enterprise Real Time Linux User’s Guide VMALLOC_PGTABLE_PRELOAD ブート時の Preloads vmalloc ページテーブルvmalloc スペースが参照され るとき、カーネルページフォルトを削除します。 i386 generic kernels に 適用されています;デフォルトで実行されます。 /proc/vmalloc-reserve-info ファイルは、使用したvmalloc割り当て、分離された小さい領域、 大きい領域、フリー(チャンク)の最大、連続的な vmalloc エリアと大きなスレッショル ド値と合計の、最新の値を見るために読むことができます。 もしもこの機能が禁止されれば、以下の動作タイプはかなりのこれら TLB フラッシュ割り込み を引き起こし、よってシールドされている CPU 上でタイム・クリティカルなアプリケーションを実 行している間、回避されるか制限されるべきです。 1. グラフィック・アプリケーションをスタートし、そして停止します。 2. X サーバをスタートし、そして停止します。 3. Ctrl Alt F# キーボード・シーケンスでグラフィック・ターミナル画面と他の非グラフィッ ク・ターミナルの間を切り換えます。 4. Ctrl Alt –または Ctrl Alt +キーボード・シーケンスで画面解像度を変更します。 ユーザ・アドレス空間 TLB フラッシュ割り込み シールドされている CPU 上で実行されるようにバイアスされているプロセス及びそれらのアド レス空間を他の CPU 上で実行するプロセスと共有するプロセスは、ユーザ空間 TLB フラッシ ュ・CPU 間割り込みを受け取ります。共有メモリ・エリアを利用するが、しかし同じ CPU 上の プロセスとのみそれらのアドレス空間を共有するプロセスは、どの共有メモリ動作によっても どの CPU 間割り込みも維持しません。 pthread ライブラリ及び Ada アプリケーションを使用する複数スレッド・アプリケーションは、プ ログラマが明確に共有メモリを生成する呼び出しを生成したわけではなくとも、共有メモリ・ア プリケーションの例です。これらのタイプのプログラムでは、pthread ライブラリ及び Ada 稼動 時間はユーザのための共有メモリ領域を生成します。よって、同じスレッド・グループまたは 同じ Ada プログラムからのスレッドがシステム内で別々の CPU 上で実行する時、これらのア プリケーションはこのタイプの CPU 間割り込みに従属します。 同じアドレス空間を共有している他のプロセスが異なる CPU 上で実行しており、そしてそのア ドレス空間の属性への修正を引き起こしている時、ユーザ・アドレス TLB フラッシュ・CPU 間 割り込みは生成されます。ページ・フォルト、ページ・スワッピング、mprotect ( )呼び出し、共 有メモリ領域の生成または破壊を引き起こすメモリ参照のような動作は、このタイプの CPU 間割り込みを引き起こすアドレス空間属性修正の例です。CPU 間割り込みのこのクラスは、 割り込みあたり 10 マイクロ秒以下で計測されている最小の影響を持ちます。メモリが大量に 共有される時、影響はさらに厳しくなります。 G-7 SUSE Linux Enterprise Real Time Linux User’s Guide CPU 間割り込みのこれらのタイプを消すために、シールドされている CPU 上で実行している タイム・クリティカルプロセスが、それらのアプリケーションのタイム・クリティカル部分間、共有 メモリ領域に影響を与えるオペレーションを回避するように、そのようにユーザはそれらのア プリケーションを使用しそしてライトするように推奨されます。これはメモリ内でページをロック することによって達成され、mprotect ( )経由でメモリ・プロテクションをバイアスする、及び新 しい共有メモリ領域を生成する、または既存の共有メモリ領域を破壊することによってではあ りません。 G-8 SUSE Linux Enterprise Real Time Linux User’s Guide H シリアルコンソールセットアップ 1 この付録は SUSE Linux Enterprise Real Time の下でシリアルコンソールの構成を設定するため に必要なステップを提供します。 もしあなたが USB キーボードでシステムで kdb カーネルデバッガを使うことを望むなら、シ リアルコンソールが必要とされることに注意を払ってください。 1.次のカーネルオプションを含むためにGRUBブートコマンドラインを修正してくだ さい: console=tty#,baud# tty# は、使用するシリアルポートの番号で、baud# は、通信速度です。 一般的な使用方法は、以下のようになります: console=ttyS0,115200 2. /etc/inittab ファイルを以下のように変更します: S0:2345:respawn:/sbin/agetty 115200 ttyS0 vt100 baud# と tty# は、ボート時のブート時の値と同じでなくてはなりません。 ステップ1で最終のキーワードはほとんど常に vt100 です、しかし、もし必要である なら、カスタマイズされることができる最終のタイプを指定します。 詳細は agetty (8) man ページ を見てください。 それは一般に終わりに加えられますが、このラインはファイルのどこにでも加えられ ることができます。 システムがマルチユーザのモードで起動した後、このラインの目的はシリアルコンソ ールにログインを得ることです。 3.もしルートでのログインがシリアルコンソール(一般にそれが望まれます)で求め られるなら、あなたは /etc/securetty ファイルを変えるか、あるいは削除しなくてはな りません。 もっと多くの詳細については securetty (5) man ページ を見てくださ い。 4.適当なデータターミナル装置をシリアルポートに接続して、そしてそれが選ばれた ボーレートにおいて通信するように設定してください。 場合によってはヌルモデムケ ーブルが必要とされるかもしれません。 高価でない LinuxPCは、データターミナル装置の優れた選択です。 もっと多くのシリアルコミュニケーションセッションを起こすことについての情報は minicom (1) man ページ を見てください。 同様の目的で、WindowsPCを使うことができます、しかしそれの説明はこのドキュメ ンテーションの範囲を越えています。 H-1 SUSE Linux Enterprise Real Time Linux User’s Guide 14I ブートコマンドラインパラメータ テーブル I-1 は、SUSE Linux Enterprise Real Time にユニークに作用する GRUB ブー トコマンドラインパラメータをリストします。 それは Linux の下で利用可能なすべ てのブートコマンドラインパラメータを含みません。 そのリストは、あなたのカーネ ルソースディレクトリDocumentation/kernel-parameters.txtあるいはinfo grub をタイプし てください。 ブートパラメータがカーネルに作り上げられる機能性を定義します。 ブートコマンド は、カーネルが起動するとき、自動的な包含のために /etc/grub.conf に加えられるか、 あるいは、カーネルをほうり出すとき、GRUBコマンドラインで指定されることができ ます。 個別の特徴についてのインフォメーションは種々の場所で利用可能です。 Table I-1 で、 次のリファレンスが規定されます: z この SUSE Linux Enterprise Real Time ユーザーズガイドに含められたインフォメ ーションが提供されるページ数(アクティブなハイパーテキスト・リンク) z インフォメーションが得られるかもしれない他のソースが含む他の適切な書類の 名前と出版番号: z カーネルソースツリーのドキュメンテーションディレクトリの下のファイル z インターネット上の Linux ドキュメンテーションサイト: Table I-1ブートコマンドラインパラメータ パラメータ gdb n/a kdb =on kgdb_serial オプション 目的 kgdb スタブを許可して、ブーツプロセスのブレークポイント にを早く処理することを強制します。 これは gdb にカーネ ル始動の大部分をデバッグするために使用されることを許し ます。 kdb カーネルデバッガへのエントリーを可能にします =off kdb へのエントリーを停止します。 =early カーネルを kdb の早いブーツプロセスに入らせます =off kgdb との構成を設定されたシリアルポートを削除します。 =baudrate,port,irq ドキュメントリファレンス 1章 /kernel-source/ Documentation/i386 /kgdb 1章 /kernel-source/ Documentation/kdb 12章 シリアルポートのボーレート、ポートと irq を上書きします。 例: kgdb_serial=115200 kgdb_serial=38400,3f8,4 kgdboe I-1 =[tgt-port]@<tgt-ip >/[dev],[host-port] @<hostip>/[hostmacaddr] イーサネットの上に kgdb を使うことに対して、目標とホスト システムを定義します。 tgt-port UDPターゲットポート(defaults to 6443) tgt-ip IPターゲットアドレス(interface address) dev ネットワークインターフェース名(eth0) host-port ホストUDP ポート (6442) (本当に使用しなくても) host-ip IP address for HOST machine host-macaddr ethernet MAC address for HOST (ff:ff:ff:ff:ff:ff) 12章 /kernel-source/ Documentation/i386 /kgdb/kgdbeth.txt SUSE Linux Enterprise Real Time Linux User’s Guide Table I-1ブートコマンドラインパラメータ(続き) パラメータ nmi_watchd og オプション =0 =1 =2 =-1 noirqbalanc e n/a numa =off rcim =rcimoptions time_base =rcim 目的 NMI 監視役機能を止めます。 SUSE Linux Enterprise Real Time non-debug カーネルに 関するデフォルト設定。 それぞれのCPUがそれ自身の NMI タイミングを行ないま す。 カーネルで APIC サポートを必要とします。 外部 NMI タイマーの使用; 発生した割り込み信号はすべ てのCPUにブロードキャストされます。 i386 debug kernel. のデフォールト設定 x86_64のみ1と2をカーネルが選択します. x86_64 debug kernelのデフォールト設定 もしカーネルのチューン可能な IRQBALANCE がカーネル で使用可能であるなら、 IRQ をバランスをとることを止める ために使うことができます。 デフォルトは許可です(シールド CPUのために推奨されます)。 enabled/off ではなくCPU 間の割り込みロードバランスをとることに対する IRQ affinities の周期的な調整を妨げます. カーネル turnable K8_NUMA がカーネルで使用可能であ るという状態で、 x86_64 システムで NUMA サポートを停 止します。 これは一つの NUMA ノードで、そのノードに属 しているすべてのCPUと一緒にシステムを作るでしょう。 こ れは NUMA サポートがノードがないフラットなメモリシステ ムがあるカーネルに作り上げられるようにしないことと異なり ます、そして、呼ばれるとき、 NUMA ユーザインタフェース がエラーを返します。 コンフィギュレーションオプションを定義するために 割り込み特性と連想のような、 RCIM 、タイミングソースと RCIM のマスターホスト名。 RCIM をタイマーソースとして使用します。デフォールト ドキュメントリファレンス 1章 /kernel-source/ Documentation/ nmi_watchdog.txt 2章 10章 RCIM User’s Guide (0898007) RCIM User’s Guide (0898007) =hpet HPRTをタイマーソースとして使用します =pm PMをタイマーソースとして使用します vmalloc =none =nn[KMG] vmalloc_sm =nn[KNG] RCIM タイマー同期化コードを停止します。 全体の vmalloc アロケーションエリアの大きさ。 この値を 増やすことは、 vmalloc_sm が小さい vmalloc エリアを増 加させるために使用されないなら、大きな vmalloc エリアを 増やします。 これらの2つのブーツパラメータは一緒にある いは独立して使われるかもしれません。 K、MあるいはGは大きさユニットを指定するために使うこと ができます:それぞれキロバイト、メガバイトあるいはギガバ イトを表します。 小さい vmalloc アロケーションエリアのバイトでの大きさ。 上記の vmalloc を見てください。 I-2 付録G 付録G SUSE Linux Enterprise Real Time Linux User’s Guide 用語解説 この用語解説では、SUSE Linux Enterprise Real Time 内で使用されている用語を定義しま す。イタリックである用語もここで定義されます。 結合 (affinity) その上で実行することを許されているプロセス、または割り込み、及び CPU 間の結合。それ らのバインドマスク内に含まれていない CPU 上で実行することを禁じられています。バインド マスク内で 1 つ以上の CPU が含まれているなら、ロードまたは他の事項に基づいてカーネル は自由にプロセスまたは割り込みを移動することができますが、バインドマスク内の他の CPU においてのみです。デフォルト状態はシステム内の全ての CPU 上で実行する結合です が、しかし、仕様は mpadvise (3)、sched_setaffinity (2)、shield (1)、及び/proc ファイル・ システムを通して生成されます。シールドされている CPU で結合を使用することは、アプリケ ーション・コード内でより良い決定性を提供します。 非同期セーフ シグナル・ハンドラー内からライブラリ・ルーチンが安全に呼び出される時。いくつかの非同期 セーフ・コードを実行しているスレッドは、もしもそれがシグナルによって割り込みされれば、 deadlock しません。これは、ロックを取得する前にシグナルをブロックすることによって達成さ れます。 アトミック オペレーションのセット内の全てが同時に動作され、そしてそれら全てが同時に動作される際 のみ。 認証 セキュリティ目的のためのユーザ名、パスワード、プロセス、またはコンピュータ・システムの アイデンティティの確証です。PMA は SUSE Linux Enterprise Real Time 上で認証方法を提 供します. メッセージ・オペレーションのブロッキング もしもメッセージの送信または受信の試みが不成功なら実行を中断します。 セマフォ・オペレーションのブロッキング セマフォ値を評価している間に実行を中断します。 Glossaly-1 SUSE Linux Enterprise Real Time Linux User’s Guide ブレイク・ポイント プログラム内の位置で、そこでは実行は停止されそして CPU の制御はデバッガへと移りま す。 ビジー待ち ハードウェア・サポートの評価及びセット・オペレーションを使用してロックを取得する 相互排 他の方法です。もしも現在ロック状態にあるビジー待ちロックを取得しようとプロセスが試み れば、現在ロックを保持しているプロセスがそれを解除して、そして評価とセット・オペレーショ ンが成功するまで、ロッキング・プロセスは評価及びセット・オペレーションを再トライし続けま す。スピン・ロックとしても知られています。 機能 独立に許可及び禁止することができる独立のユニット内へと伝統的にスーパーユーザと結合 さ れ る 権 限 の 区 分 。 現 在 の 全 て の 有 効 な Linux 機 能 の セ ッ ト は /usr/include/linux/capability .h 内で見つけることができ、そして 17 章内で詳細にされてい ます。PAM を通して、ルートのみに通常許されている権限を要求するアプリケーションを走ら せるように非ルート・ユーザをコンフィグすることができます。 状態同期化 アプリケーション定義の状態が満たされるまで、プロセスの進行を遅らせる、スリープ/ウェイ クアップ/タイマー・メカニズムを利用します。SUSE Linux Enterprise Real Time では、この目 的のために postwait (2)及び server_block (2)/server_wake (2)システムコールが提供さ れています。 コンテキスト・スイッチ マルチ・タスク・オペレーティングシステムが 1 つのプロセスの稼動を停止し、そして他の稼動 を開始する時。 クリティカルセクション ソフトウェアの正確なオペレーションを保証するために、連続でそして割り込みが無く実行さ れなければならないインストラクションのシーケンス。 デッドロック 2 つまたはそれ以上のプロセスが、それら両方が一方が何かのソースをリリースするのを待 っているために進行しない状況の数。 Glossaly-2 SUSE Linux Enterprise Real Time Linux User’s Guide 遅延されている割り込み扱い 割り込みレベルで行われていた処理を遅らせる割り込みルーチンでの方法。SUSE Linux Enterprise Real Time は softirq、tasklet、及び work queue をサポートし、それらはカーネ ル・デーモンのコンテキスト内で実行します。これらのデーモンのプライオリティ及びスケジュ ーリング・ポリシーは、高プライオリティ・リアルタイム・タスクが遅延されている割り込み機能 の動作をプリエンプトすることができるようにコンフィグすることができます。 決定性 一定の時間量内で特定のコード・パス(連続で実行されるインストラクションのセット)を実行 できるコンピュータ・システムの能力。コード・パスにおける実行時間が 1 つのインスタンスか ら他のものにおいて変化する量が、システム内の決定性の度合いを示します。ユーザアプリ ケーションのタイム・クリティカル部分を実行するのに要される時間量とカーネル内のシステ ム・コードを実行するのに要される時間量の両方に、決定性は適用されます。 決定的システム その中で決定性に影響を与える要素を制御することが可能なシステム。決定性の最大化に おいて SUSE Linux Enterprise Real Time 下で利用可能なテクニックには、シールドされて いる CPU、固定されているプライオリティ・スケジューリング・ポリシー、遅延されている割り込 み扱い、ロード・バランシング、及びハイパー・スレッディングのユニット制御が含まれます。 デバイス・ドライバ コンピュータ・ハードウェア・コンポーネント、または周辺機器と直接的にコミュニケートし、オ ペレーティング・システムによる使用を可能にするソフトウェア。デバイス・モジュール、または ドライバとも呼ばれます。 直接 IO データにおけるカーネルのバッファリングをバイパスする IO のアンバッファの形式。直接 IO では、ファイル・システムはディスクとユーザ供給のバッファの間を直接的にデータをトランス ファします。 任意のアクセス制御 ユーザ名、パスワード、またはファイル・アクセス許可に基づいたメカニズムで、それらはユー ザの判断に任された信用証明の有効性をチェックします。これは、IP アドレスのようなユーザ が制御を持たないアイテム上に基づく義務的制御とは異なります Glossaly-3 SUSE Linux Enterprise Real Time Linux User’s Guide 実行時間 タスクを完了するのに要される時間量。SUSE Linux Enterprise Real Time 内の高精度プロ セス・アカウンティング機能を使用して、それぞれのプロセスにおける実行時間計測は、シス テム、ユーザ、割り込みされているシステム、及び高精度タイムスタンプカウンタ(TSC)で計 測された割り込みユーザ時間に分解されます。 FBS Frequency-Based Scheduler (FBS)を見てください。 固定されているプライオリティ・スケジューリング・ポリシー ユーザにプロセスあたりベースで静的プライオリティの設定を可能にするスケジューリング・ ポリシー。固定されているプライオリティ・スケジューリング・ポリシーの 1 つを使用するプロセ スのプライオリティをスケジューラは決して修正しません。最高の固定されているプライオリテ ィ・プロセスは常に、もしも他のプロセスが稼動可能であっても CPU をそれが稼動可能にな れば即に取得します。2 つの固定されているプライオリティ・スケジューリング・ポリシーがあり ます。SCHED_FIFO と SCHED_RR です。 フレーバ 単一エンティティの変種です。SUSE Linux Enterprise Real Time には既構築のカーネルの 3 つのフレーバがあり、それぞれは異なる特性及びコンフィグレーションを含みます。カスタマ イズされたカーネルは他のフレーバを構成します。フレーバ指定はトップ・レベルの Makefile 内で定義され、そしてカーネルが構築される時にカーネル名にサフィックスとして加えます。 例: <kernelname>-trace。 Frequency-Based Scheduler (FBS) 様々なソースに基づいて指定されている周期でプロセスを開始するのに使用されるタスク同 期化メカニズムです。ソースには、リアルタイム・クロックが提供する高精度クロック、及び割 り込みモジュール(RCIM)、外部割り込みソース、またはサイクルの完了が含まれます。そし てプライオリティ・ベースのスケジューラを使用してプロセスはスケジュールされます。 Performance Monitor (PM)と結合して使用される時、特定のアプリケーションにおける様々 なタスクへ CPU を割り当てる最良の方法を決定するために FBS を使用することができます。 NightSim ツールは FBS 及びパフォーマンス・モニターへのグラフィカル・インターフェイスで す。 Glossaly-4 SUSE Linux Enterprise Real Time Linux User’s Guide GRUB GRand Unified Bootloader (大統一ブートローダ)。複数オペレーティング・システム(及 びそれらの変種)をロードしそして管理する小さなソフトウェア・ユーティリティ。GRUB は SUSE Linux Enterprise Real Time のデフォルトのブートローダです。 ハイパー・スレッディング Intel Pentium XeonCPU の機能で、それは単一の物理 CPU がソフトウェア・アプリケーショ ンの複数スレッドを同時に走らせることを可能にします。1 つのセットの CPU 実行リソースを 共有しつつ、それぞれの CPU は 2 つのアーキテクチャ状態のセットを持ちます。それぞれの アーキテクチャ状態は、システム内で 2 倍の論理 CPU になった論理 CPU として考えること ができます。ハイパー・スレッディングが許可されている 1 つの CPU・システムは 2 つの論理 CPU を持ち、割り込み及びバックグランド・プロセスからそれらの 1 つをシールドすることを可 能にします。SUSE Linux Enterprise Real Time ではハイパー・スレッディングはデフォルトで 許可されています。 info ページ Info ページはコマンドまたはファイルについての詳細な情報を与えます。その姉妹である man page には短くそして info ページよりもより少ない説明を提供する傾向があります。Info ページは徘徊可能なメニュー・システムにより相互作用的です。Info ページは info (1)コマン ドを使用してアクセスすることができます。 プロセス間通信(IPC) 1 つのプロセスを他のプロセスと通信可能にする機能です。ネットワークを通して接続されて いる同じまたは異なるコンピュータ上をプロセスが走ることができます。IPC は 1 つのアプリケ ーションが他のアプリケーションを制御することを許可し、そして様々なアプリケーションが互 いに干渉すること無く同じデータを共有することができます。IPC 方法は pipe、メッセージキュ ー、セマフォ、共有メモリ、及びソケットを含みます。 プロセス間同期化 共同プロセスにリソースの同じセットへのアクセスに対応させることを可能にするメカニズム です。SUSE Linux Enterprise Real Time は以下のものを含む様々なプロセス間同期化ツー ルを供給します。再スケジューリング変数、ビジー待ち及びスリープ待ち相互排他メカニズム、 そして状態同期化ツール。 ジッター 周期的アクションの到着時または出発時における変種のサイズ。コード・セグメントの実行ま Glossaly-5 SUSE Linux Enterprise Real Time Linux User’s Guide たは割り込みへの応答のいずれかにおいて計測される最悪ケース時間が一般的ケースより も大きく異なる時、アプリケーションのパフォーマンスはジッターを経験していると言われます。 アクション全てが正確な周期内にとどまっている限り、ジッターは通常問題を起こしません。し かしジッターが可能な限り最小であることをリアルタイム・タスクは一般的に要求します。 ファイル・システムのジャーナル そこでディスク・トランザクションがディスクのエリアへ逐次的にライトされるファイル・システム は、ファイル・システム内のそれらの最終位置へライトされる前、ジャーナルまたはログと呼 ばれます。もしもジャーナル・エントリが行われる前にクラッシュが起これば、オリジナル・デー タはまだディスク上にあり、新しい変更のみが失われます。システムがリブートする時、ジャー ナル・エントリは再生され、そして割り込みされていたアップデートが完了され、リカバリ時間 を大きく単純化します。SUSE Linux Enterprise Real Time 内でのファイル・システムのジャ ーナルは ext3、xfs 及び reiserfs を含みます。 カーネル その上でさらに高度な機能が依存している基本的機能を動作するオペレーティング・システ ムのクリティカル・ピースです。Linux は Linus Torvalds 及び要の開発者のグループによって 開発されたカーネルに基づいています。Novell によってディストリビューションされる Linux カ ーネルを修正して、 クリティカル・リアルタイム処理 における高機能を提供します。SUSE Linux Enterprise Real Time は以下のフレーバと共に generic, debug, trace, bigmem, debug_bigmem と trace_bigmem.の既構築のカーネルを供給します。フレーバは一般的、 デバッグ及びトレースです。それらは/boot ディレクトリ内の vmlinuz-<kernelversion>SLERT-<revision.level>-<flavor>と名付けられているファイルとして常駐します。 カーネル・コンフィグレーション GUI カーネルのコンフィグレーションにおける選択が生成されるグラフィカル・インターフェイス。 SUSE Linux Enterprise Real Time では、ccur-config スクリプトを走らせると、どこで選択 を生成することができるのかを GUI に表示します。 ロード・バランス 全ての CPU にわたってロードをバランスする、いくつかの CPU からの動的プロセス。 man page コマンドまたはファイルについて説明する、短くそして簡明なオンライン・ドキュメント。シェル・ プロンプトで man とタイプして続けてスペースそして、リードしたい用語をタイプすれば、man page は表示されます。SUSE Linux Enterprise Real Time での man page は、Concurrent Glossaly-6 SUSE Linux Enterprise Real Time Linux User’s Guide が開発した機能性の説明と同様に、SUSE で提供されているものも含みます。 メモリ・オブジェクト 結合されているメモリを共有することを可能にする、1 つまたはそれ以上のプロセスのアドレ ス空間へマップすることができる記憶の名付けられた領域。メモリ・オブジェクトは POSIX 共 有・メモリ・オブジェクト、一般的ファイル、そしていくつかのデバイスを含みますが、全てのフ ァイル・システム・オブジェクトを含むのではありません(例として、ターミナル、及びネットワー ク・デバイス)。それらのアドレス空間の部分をオブジェクト上へマップすることによって、プロ セスはメモリ・オブジェクト内のデータへ直接的にアクセスすることができ、それは カーネルと アプリケーションとの間のデータのコピーを無くします。 メッセージキュー 1 つまたはそれ以上のプロセスが 1 つまたはそれ以上のリーディング・プロセスによってリー ドされるメッセージをライトすることを可能にする プロセス間通信( IPC ) メカニズムです。 SUSE Linux Enterprise Real Time は、POSIX 及び System V メッセージキュー機能へのサ ポートを含みます. モジュール システム・レベルの機能を動作するルーチンのコレクション。要されれば、モジュールは稼動 しているカーネルからロードしそしてアンロードされます。 相互排他 共有リソースへのアクセスを順キューすることによって、一時に クリティカルセクションで、共 同プロセスのセットの 1 つのみが実行することができることを確実にするメカニズム。3 つのタ イプのメカニズムが一般的に相互排他を提供するのに使用されます。ビジー待ちを含むもの、 スリープ待ちを含むもの、そしてその 2 つの組合せです。 NightProbe Concurret によって開発され、1つまたはそれ以上の実行プログラム内でプログラム・データ のリアルタイム・レコーディング、ビューイング、そして修正を可能にするグラフィカル・ユー ザ・インターフェイス(GUI)です。シミュレーション、データ取得、及びシステム制御を含むアプ リケーションの開発及びオペレーション間にそれは使用することができます。 NightSim RT Frequency-Based Scheduler (FBS)及びパフォーマンス・モニター(PM)器機へのグラフィカ ル・ユーザ・インターフェイス(GUI)。 Glossaly-7 SUSE Linux Enterprise Real Time Linux User’s Guide NightStar RT ツール リアルタイム・アプリケーションの動作時間様式のスケジューリング、モニターリング、デバッ グ、そして分析におけるグラフィカル・インターフェイスを提供する、Concurret が供給する開 発ツールのコレクションです。ツールセットには、NightSim 周期的スケジューラ、NightProbe データ・モニター、NightTrace イベント・アナライザー、そして NightView デバッガが含まれま す。 NightTrace RT 複数プロセス及び/またはマルチ CPU・ユーザ・アプリケーション及びオペレーティング・シス テム動作の動的な様式を分析するのに使用される、Concurret が開発したグラフィカル・ツー ルです。NightTrace ツールセットは、インタラクティブ・デバッグ及びパフォーマンス分析ツー ル、トレース・データ・コレクション・デーモン、そしてアプリケーション・プログラミング・インター フェイス(API)から構成されます。 NightView RT C、C++、及び Fortran で書かれたリアルタイム・アプリケーションにおいて Concurrent が設 計した多目的、グラフィカル・ソース・レベルのデバッグ及びモニターリング・ツールです。 NightView は、ローカル・システム上、または最小限の侵入で異なるターゲット上のマルチ CPU 上を走っている複数リアルタイム・プロセスをモニターし、デバッグし、そしてパッチする ことができます。 非ブロッキング・メッセージ・オペレーション もしもメッセージの送信または受信の試みが不成功なら実行の中断をしません。 非ブロッキング信号オペレーション セマフォ値を評価中、実行の中断をしません。 PAM プラグ可能な認証モジュール。このような機能において個別に個々のプログラムを再コンパ イルする必用無しに、システム管理者にアクセス及び認証ポリシーの設定を可能にする方法 です。この方法のもとでは、ルートのみに通常許される権限を要するアプリケーションを走ら せるように非ルート・ユーザをコンフィグすることができます。 Glossaly-8 SUSE Linux Enterprise Real Time Linux User’s Guide PCI (Peripheral (周辺)Component Interface)。CPU 及び、ビデオ・カード、サウンド・カード、ネ ットワーク・インターフェイス・カード、そしてモデムのような周辺機器の間に高スピード・デー タ・パスを提供する周辺バスです。PCI は“プラグ及び起動”機能を提供し、33MHz で稼動し、 そして 32 ビット及び 64 ビット・データ・パスをサポートします。 パフォーマンス・モニター(PM) FBS 上でスケジュールされているプロセスによって CPU の使用のモニターを可能にする機 能。取得された値は、向上されたロード・バランシング、及び処理効率において、CPU 間でど のようにプロセスを再分配するのかを決定する補助をします。NightSim はパフォーマンス・モ ニターへのグラフィカル・インターフェイスです。 プラグ可能な認証モジュール(PAM) PAM を見てください。 POSIX ユーザ空間機能における標準と共に、UNIX 系カーネル・インターフェイスにおける意味論及 びインターフェイスを指定する標準。要の POSIX 定義があり、それは全ての POSIX 準拠の オペレーティング・システムによって、及び例として POSIX メッセージキューのような特定の 機能におけるいくつかのオプション的標準によってサポートされなければなりません。 プリエンプション CPU 上を走っていたプロセスがより高いプライオリティでのプロセスによって置き換えられる 時のことです。SUSE Linux Enterprise Real Time 内に含まれているカーネル・プリエンプシ ョンは、カーネル空間内で動作していても、より低いプライオリティ・プロセスのプリエンプトを 可能にし、向上されたシステム応答の結果を生みます。プロセス・プリエンプションは再スケ ジューリング変数の使用を通して制御することができます。 プライオリティ継承 プライオリティ反転を回避するために要されて、1 つのプロセスのプライオリティと共に他へ一 時的に渡すメカニズムです。 プライオリティ反転 より高いプライオリティ・プロセスがより低いプライオリティ・プロセスの実行待ちを強制される Glossaly-9 SUSE Linux Enterprise Real Time Linux User’s Guide 時です。 権限 それを通してユーザまたはプロセスが敏感なオペレーションを動作する、またはシステム制 約を無効にすることを許されるメカニズムです。スーパーユーザは全ての(ルート)権限を持 ちます。機能を通して、個々のユーザ及びプロセスにおいて権限は許可または禁止すること ができます. プロセス 実行されているプログラムのインスタンスです。それぞれのプロセスはユニークな PID を持ち、 それはカーネルのプロセス・テーブル内のそのプロセスのエントリです。 プロセスディスパッチレイテンシィ 割り込みによって示される外的イベントの発生から、外的イベントを待っているプロセスがそ の最初のインストラクションをユーザ・モードで実行するまでに経過する時間です。 RCIM リアルタイム・クロックと割り込みモジュール。複数 CPU アプリケーション内の完全に決定的 なイベント同期化において Concurrent が設計した複数機能 PCI カードです。RCIM は同期 化されているクロック、4 つのプログラム可能なリアルタイム・クロック、そして 4 つの入力、及 び 4 つの出力外部割り込み行を含みます。RCIM チェーンを使用して内的接続されているシ ステムにわたって割り込みは共有(分配)することができます。 リアルタイム 現実世界のイベントへ応答し、そして与えられているデッドライン内でそのイベントを扱うのに 要される処理を完了します。現実世界のイベントへ応答するのに要される計算は、デッドライ ン、または結果が不正確であるとみなされる前に完了しなければなりません。SUSE Linux Enterprise Real Time は真のリアルタイム・オペレーティング・システム(RTOS)です。なぜな ら、それは指定されている時間制約内である程度の機能を保証するからです。 再スケジューリング変数 アプリケーションによってプロセスあたりベースで割り当てられているデータ構造で、それは 再スケジューリングへの単一プロセスの脆弱性を制御します。 RPM RPM パッケージ・マネージャ。コンピュータ・ソフトウェア・パッケージのインストール、アンイン Glossaly-10 SUSE Linux Enterprise Real Time Linux User’s Guide ストール、確認、問合せ、そしてアップデートにおいて使用されるツール、データベース、そし てライブラリの管理システム。完全な情報については、rpm (8) man page を見てください。 セマフォ その値が 1 プロセス以上で評価されそして設定されるメモリ内の位置。既にロックされている セマフォをロックしようと試みるプロセスはブロックされるかまたはスリープへと置かれるので、 セマフォはスリープ待ち相互排他の形式です。SUSE Linux Enterprise Real Time は最速の パフォーマンスを達成するための単純なインターフェイスを与える POSIX カウンティング・セ マフォ、及び多くの追加機能を与える System V セマフォを提供します(例として、セマフォ上 にいくつ待っているものがあるかを見つける機能、またはセマフォのセット上で動作する機 能)。 共有メモリ 1 つ以上のプロセスのバーチャル・アドレス・マップを通してアクセス可能なメモリ。一般的な オペレーティング・システム・サービスを使用してのリーディング及びライティングよりも速く、 共有メモリを使用してプロセスがデータをやり取りすることができます。POSIX と同様に System V から生まれる標準化共有メモリ・インターフェイスを SUSE Linux Enterprise Real Time は含みます。 シールドされている CPU 割り込み及びシステム・デーモンと結合している予期できない処理から保護されている高プラ イオリティ・タスクの稼動を担っている CPU。SUSE Linux Enterprise Real Time システム内 のそれぞれの CPU は個別にバックグランド・プロセス、割り込み及び/またはローカル・タイマ ー割り込みからシールドすることができます。 シールドされている CPU モデル それによってタスク及び割り込みが、ある程度重要なリアルタイム機能への高度なサービス を保証する形式で CPU へ割り当てられているモデル。特に、ほとんどの割り込み及び低プラ イオリティ・タスクが他の CPU へ連結されている中で、高プライオリティ・タスクは 1 つまたは それ以上のシールドされている CPU へ連結されています。 シールドされている CPU シールドされている CPU を見てください。 Glossaly-11 SUSE Linux Enterprise Real Time Linux User’s Guide スリープ待ち プロセスを、もしもそれが現在ロックされている状態のロックを取得しようと試みているなら、 スリープへと置く、セマフォのような相互排他の方法です。 SMP 対称並列処理。1 つのオペレーティング・システムに管理される 2 つまたはそれ以上の CPU を使用する計算の方法で、しばしば同じメモリを共有し、そして入力/出力デバイスへの同等 のアクセスを持ちます。システム内のいくつかのまたは全ての CPU 上をアプリケーション・プ ログラムが走ります。 softirq それによって関数の実行を次の利用可能な“安全ポイント”まで遅らせることができる方法。 関数を起動する代わりに、次の安全ポイントでの起動を引き起こす“トリガー”が代わりに使 用されます。安全ポイントは、カーネルがハードウェアまたはソフトウェア割り込みをサービス しておらず、そしてブロックされている割り込みで稼動していない時間です。 スピン・ロック リソースにおいて相互排他を確実にするビジー待ち方法。スピン・ロック上で待っているタスク は、スピン・ロックが利用可能になるまでビジー・ループ内にとどまります。 System V Linux 及び System V システムを含む多くの UNIX 系システムによってサポートされているプ ロセス間通信(IPC)オブジェクトにおける標準。System V IPC オブジェクトには 3 つの種類 があります。System V メッセージキュー、セマフォ・セット、そして共有メモリ・セグメントです。 tasklet ユーザ空間への返りで、またはハードウェア割り込みの後で、ソフトウェア割り込みが受信さ れる時に走っているソフトウェア割り込みルーチン。tasklet は複数 CPU 上で同時に走りませ んが、しかし動的に割り当て可能です。 トレース・イベント アプリケーションのソース・コード内、またはデバッグ及びパフォーマンス分析において NightTrace ツールによって調べられるカーネル内で意味のあるポイント(トレース・ポイント) においてログされている情報。 Glossaly-12 SUSE Linux Enterprise Real Time Linux User’s Guide work キュー softirq 及び tasklet に加えて、実行を遅らせる方法。しかしこれらの方法と異なり、Linux はカ ーネル・デーモンのプロセス・コンテキスト内で work キューを処理し、よってスリープすること が可能です。 Glossaly-13