Standard Forms

リアルタイム OS を総合的に評価する
Two-way Request Latency Test Program の設計（POSIX-OS の性能評価）

Rev

Date

Description

Issue
Rev

Date

Date

0

Issue

Title

Check

App

AuthorCheck

App

Description

Issue
Rev

AuthorDescription

Professional Service
POSIX-OS の 性 能 評 価

AuthorT.Oshima
No

Check

App
Revision
Page

1Standard Forms

始めに本 稿 で は 、リ ア ル タ イ ム OS を 総 合 的 に 評 価 す る Two-way Request Latency Test Program の設計について述べる。

目的
本 プ ロ グ ラ ム の 目 的 は 、 リ ア ル タ イ ム OS の 断 片 的 な 性 能 で は な く 、 実 使 用 環 境 に 則 し た 性
能評価であり、断片的な性能を数値化するものではない。
従 来 、 リ ア ル タ イ ム OS を 評 価 す る 数 値 と し て 、 メ ー カ ー が 公 表 し て い る も の に 、 応 答 速 度(Response Time)が 存 在 す る 。
この応答速度も、メーカーにより様々な箇所の値が存在し、その解釈も異なっている。

Figure 0: Elapsed Time
1.
2.
3.
4.
5.

割込みコントローラが割り込みを通知し、ＣＰＵが割り込み例外を通知する。
割込みルーチンが実行され、割り込みを待っているプロセス（ターゲットプロセス）が呼び起こす。
現在実行しているプロセスは中断し、そして、ターゲットプロセスを実行するために、コンテキストスイッチが行なわれる。
割り込みを待ってブロックされていたターゲットプロセスは、カーネル空間からユーザ空間にコンテキストスイッチされる。
ターゲットプロセスはユーザ空間で実行される。

（ 図 は 、 Concurrent Computer 社 が 公 表 し て い る Application Response Time）
しかし、エンドユーザが必要とする応答時間は、イベントが発生しそのイベントの発生をア
プリケーションプログラムが認知するまでの時間であり、個別の時間を評価することは、エンドユーザにとって意味は小さいと考える。
Title

POSIX-OS の 性 能 評 価No

Revision
Page

2Standard Forms
こ こ で は 、 AEGIS で 使 用 さ れ た ベ ン チ マ ー ク 試 験 (1)(2) を 参 考 に 、 リ ア ル タ イ ム OS の 評 価 プ ロ
グラムの設計を行うことを考える。

参考文献(1),(2)のベンチマーク試験の分析
参 考 文 献 (1)の ベ ン チ マ ー ク 試 験 で は 、下 記 の ６ つ の 項 目 を 個 別 の ベ ン チ マ ー ク プ ロ グ ラ ム として実施している。
BenchmarkDescription

Aspect tested

Parameters

Timer Jitter

Create a periodic thread andmeasure the deviation between
desired and actual expiration

Measures the responsetime of the operating

Timer period:(1,10,100 ms)

systemResponse

Execute a fixed processing load
and measure its execution time

Determine if a thread can
respond in a

Type of processing:(add,copy,whetstone)

over a number of runs

deterministic fashion

BintimeCall a time of day clock andmeasure interval between calls

Measures the maximum
kernel blocking time

None

Sync

Measure the latency of thread tothread or process to processsynchronization

Measures the context
switching time between
threads and processes

Type of semaphore:(POSIX named/unnamed
semaphore, pthread mutex,
lynx semaphore); process
to process or thread to

Messagepassing

Measure the latency of sending
data form thread to thread orfrom process to process

Measures the possible
throughput of data
between processes andData buffer size; process toprocess or thread to thread

RT Signals

Measure the latency of real-time
signals between two processes

threadthreads
Measures the latency of
POSIX real-time signals

None

参 考 文 献 (2)の ベ ン チ マ ー ク 試 験 で は 、下 図 に 示 す よ う に 、IP を 使 用 し た エ ン ド － エ ン ド の ベ
ンチマークプログラムとして実施している。

何れのベンチマーク試験の項目も、今後の防衛関係のプログラム開発に必要な項目で有ることに異論はないと考える。
し か し 、 こ の AEGIS ベ ン チ マ ー ク 試 験 と 同 様 な 試 験 プ ロ グ ラ ム を 行 い 、 評 価 す る た め に は
相 応 の 知 識 と 環 境 を 用 意 す る コ ス ト が 要 求 さ れ る た め 、本 設 計 で は 、こ れ ら の 試 験 を 簡 易 的 な 、単一プログラムとして開発することを考える。
Title

POSIX-OS の 性 能 評 価No

Revision
Page

3Standard Forms
参 考 文 献 (1)に 示 さ れ た 最 初 の ３ 本 の ベ ン チ マ ー ク（ Timer Jitter、Response と Bintime）は 、
オ ペ レ ー テ ィ ン グ シ ス テ ム の 決 定 論 (Determinism)の 計 測 に 使 用 す る 。
リ ア ル タ イ ム シ ス テ ム に お い て 、最 も 重 要 な 性 能 は 、決 定 論 (Determinism)で あ り 、同 じ 処 理
であれば、常に同じ処理時間を保証する性能のことである。
残りの３本のベンチマークはオペレーティングシステムの同期、メッセージパッシングとリアルタイム・シグナルをテストしている。
リアルタイムシステムは、最小化された同期と通信待ち時間は非常に重要で、リアルタイム
処理の待ち時間が最小化され、全体のオーバーヘッドが、小さいことが重要である。
Timer Jitter テ ス ト
参 考 文 献 (1)の Timer Jitter テ ス ト の 構 造 を 下 図 に 示 す 。
試験は、インターバルタイマを作り、その繰り返し時間の時刻をタイムスタンプで記録する。
ジッターは、望ましい時限完了時間の偏差と定義される。
こ の タ イ ム ス タ ン プ に は 、 高 い 精 度 時 刻 機 構 を 与 え る POSIX clock_gettime() 関 数 を 使 う 。

Figure 3: Timer Jitter
こ の 機 能 は 、POSIX 準 拠 の す べ て の リ ア ル タ イ ム OS に 備 わ っ て い る 機 能 で あ る た め 、繰 り
返し時間を高速にすることで、現行機種のベンチマーク試験にそのまま流用できると考えられる 。 (参 考 文 献 は 1990 年 代 の 計 算 機 で あ る た め 2010 年 の 速 度 に 合 わ な い 。 )もし、タイマーがハードウェアによって実現される精度の高いものであれば、このジッターのヒストグラムは、正の値と負の値が正規に分布し、それがソフトウェアによって実現される
精度の良くないものであれば、おそらく正の値にシフトしているはずである。
clock_gettime()は 、POSIX の 定 義 で あ る が 、シ ス テ ム コ ー ル で あ る た め コ ン テ キ ス ト ス イ ッ
チ を 伴 い 、オ ー バ ー ヘ ッ ド が 存 在 す る 。し か し 現 在 の x86 プ ロ セ ッ サ で は 、CPU に 与 え ら れ た
ク ロ ッ ク を カ ウ ン ト す る 命 令 tscrd が 存 在 し 、 ボ ー ド に 実 装 さ れ た ク ロ ッ ク チ ッ プ に 左 右 さ れる事のない、より正確な測定が可能である。
こ の tscrd を 使 用 し た 場 合 に は 、 OS の オ ー バ ー ヘ ッ ド は 存 在 し な い 。 ま た 、 linux に お い ては 異 な る CPU 間 で 各 ク ロ ッ ク を 同 期 さ せ る 機 構 を 標 準 で 持 っ て い る た め 、 ベ ン チ マ ー ク テ ス
トには最適である。
Response テ ス ト
２ 番 目 の 決 定 性 ベ ン チ マ ー ク（ Response）は 、１ ０ ミ リ 秒 固 定 ブ ロ ッ ク の 実 際 の 実 行 時 間 を
測 っ て い る 。 参 考 文 献 (1)に お け る ベ ン チ マ ー ク 試 験 で は 、加 算 ,コ ピ ー , 合 成 ウ エ ッ ト ス ト ー
ンベンチマークの３種を行っている。
このベンチマークで、問題にしている処理の実行時間変動は、主に以下の理由で発生する。
 主記憶のページングの遅れ キャッシュのミスヒット
 数値演算におけるパイプラインストール現象
 優先度プロセス切り替えに伴う、コンテキストスイッチ時間の副作用
 システムクロックによるサービスのオーバーヘッドとその副作用
し た が っ て 、処 理 時 間 と キ ャ ッ シ ュ の ミ ス ヒ ッ ト を 多 発 さ せ る fft プ ロ グ ラ ム を 使 用 す る こ とにより、この影響を調べることが出来ると考える。
Title

POSIX-OS の 性 能 評 価No

Revision
Page

4Standard Forms
Bintime テ ス ト
最大のカーネルブロッキング時間の測定。
参 考 文 献 (1)の ベ ン チ マ ー ク プ ロ グ ラ ム は 、 高 優 先 順 位 リ ア ル タ イ ム ス レ ッ ド が 繰 り 返 し Timeof Day シ ス テ ム コ ー ル を 行 い 、そ れ ぞ れ の 呼 び 出 し に よ っ て 必 要 と さ れ る 時 間 を 計 算 し て い る 。
それぞれの呼び出しによって必要とされる時間は、カーネルでブロックされ、システムコー
ルを行なう度に成り立つ。
システムコールは常にループによって行われ、絶え間が無いため、ベンチマークによって報告 さ れ た 最 大 時 間 と 平 均 待 ち 時 間 の 間 の 偏 差 は 、カ ー ネ ル で ブ ロ ッ ク さ れ た 最 大 時 間 を 与 え る 。
Sync テ ス ト
参 考 文 献 (1)で 行 わ れ て い る 、 ３ つ の 異 な っ た 同 期 テ ス ト を 下 図 に 示 す 。
Test1 は 、 単 一 タ ス ク で （ Ｓ ） を 行 い 、 そ し て 次 に セ マ フ ォ （ Ｗ ） を 待 つ 。
このテストはセマフォシステムコールの待ち時間を測る。
Test2 は 、 ２ つ の ス レ ッ ド 間 で 単 一 の セ マ フ ォ の 通 知 時 間 を 計 測 す る 。
異なったタスクはスレッドあるいはプロセスでのいずれかである。
Test2 で 得 ら れ た roundtrip 時 間 の 半 分 か ら 、Test1 の 時 間 を 引 き 算 す る こ と に よ っ て 、コ ン テ
キスト切替え時間を決定するために使うことができる。
最 後 の テ ス ト は 、オ ペ レ ー テ ィ ン グ・シ ス テ ム が 優 先 性 反 転 (プ ラ イ オ リ テ ィ イ ン バ ー ジ ョ ン )を扱う能力を評価する。

低レベル優先度タスクが（Ａ）高優先度タスクが、後に必要するリソースを獲得するとき、プライオリティインバージョンが発生する。
図では、高優先度タスクが、リソースにアクセスする事を阻止され、そして、独立した中間の 優 先 度 タ ス ク が CPU を 独 占 し て い る た め 、 低 優 先 度 タ ス ク が リ ソ ー ス を 解 放 す る こ と が 無期限に遅れている。
この問題を解決する１つの典型的な方法は、低レベル優先度タスクが実行できるように、高優先度タスクの優先度を継承することを可能にし、情報資源Ｒをリリースする事である。
なお、このプライオリティインバージョンは、対応機能を持っていない場合にデッドロックを発生させる。

Title

POSIX-OS の 性 能 評 価No

RevisionPage

5Standard Forms
Message passing テ ス ト
Message passing テ ス ト は 、同 じ プ ロ セ ス あ る い は 異 な っ た プ ロ セ ス 間 で 、POSIX メ ッ セ ー
ジキューを使って、データの待ち時間とスループットを計測する。
RT Signal テ ス ト
RT Signal テ ス ト は 、 POSIX リ ア ル タ イ ム キ ュ ー の 待 ち 時 間 を 測 定 す る 。
ORB テ ス ト
Figure 4 は 、 参 考 文 献 (2)の ベ ン チ マ ー ク テ ス ト が ど の よ う に 、 C0 か ら Cn ク ラ イ ア ン ト を 使うか示す。
最 高 優 先 ク ラ イ ア ン ト 、す な わ ち C0 は 、デ フ ォ ル ト OS リ ア ル タ イ ム 優 先 度 P0 で 実 行 され 、 ２ ０ ヘ ル ツ で 処 理 を 実 行 し 、 毎 秒 ２ ０ 回 の CORBA two way コ ー ル を 呼 び 出 す 。
残 り の ク ラ イ ア ン ト C1～ Cn は 、異 な っ た よ り 少 な い OS ス レ ッ ド プ ラ イ オ リ テ ィ P1～ Pn
を 持 っ て い て 、１ ０ ヘ ル ツ の 処 理 を 実 行 し 、毎 秒 １ ０ 回 の CORBA two way コ ー ル を 呼 び 出 す 。

Figure 4:ORB Client/Server(C/S) Request Utilization Benchmark Configuration

Title

POSIX-OS の 性 能 評 価No

RevisionPage

6Standard Forms

ベース試験プログラム
コンカレントで、現在用意されている、試験プログラムは、いくつか存在するが、本稿に対して有用なプログラムは、以下のものがあると考えられる。
項目
プログラム名Timer Jitter
timer.c, tswitch.c
Response
fft.c
Bintimetimer.cSync
sem.c, tswitch.c
Message passing mq.c
RT Signals
sigq.cFigure 5 :ベ ー ス と な る 試 験 プ ロ グ ラ ムtimer.c1000Hz の POSIX タ イ マ ー を 生 成 し 、そ の 統 計 的 な 最 小 値 、平 均 値 、最 大 値 を 表 示 す る とと も に 、 nanosleep()関 数 の 精 度 を 試 験 す る 。
POSIX 仕 様 の リ ア ル タ イ ム カ ウ ン タ clock_gettime()を 使 用 し 、 μ 秒 精 度 の 計 測 を 行 う 。
参 考 文 献 (1)で 行 わ れ て い る Timer Jitter テ ス ト と Bintime テ ス ト に 相 当 す る 。
tswitch.c
1000Hz POSIX タ イ マ ー を 生 成 し 、 そ の 統 計 的 な 最 小 値 、 平 均 値 、 最 大 値 を 表 示 す る と とも に 、 ２ つ の p ス レ ッ ド の mutex 起 動 時 間 を 試 験 す る 。
POSIX 仕 様 の リ ア ル タ イ ム カ ウ ン タ clock_gettime()を 使 用 し 、 μ 秒 精 度 の 計 測 を 行 う 。
参 考 文 献 (1)で 行 わ れ て い る Timer Jitter テ ス ト と Bintime テ ス ト に 加 え Sync テ ス ト の Test2に相当する。
sem.c
POSIX セ マ フ ォ の サ ン プ ル プ ロ グ ラ ム 。
参 考 文 献 (1)で 行 わ れ て い る Sync テ ス ト の Test1 に 相 当 す る 。
mq.c
POSIX メ ッ セ ー ジ キ ュ ー の サ ン プ ル プ ロ グ ラ ム 。
参 考 文 献 (1)で 行 わ れ て い る Message passing テ ス ト に 相 当 す る 。
sigq.cPOSIX リ ア ル タ イ ム シ グ ナ ル の サ ン プ ル プ ロ グ ラ ム 。
参 考 文 献 (1)で 行 わ れ て い る RT signal テ ス ト に 相 当 す る 。

Title

POSIX-OS の 性 能 評 価No

Revision
Page

7Standard Forms
実行例１
同 一 ハ ー ド ウ ェ ア (デ ジ タ ル ロ ジ ッ ク )上 に て 上 流 ベ ン ダ ー お よ び RedHawk で そ れ ぞ れ タ イ
マ ー ハ ン ド ラ ー の 起 動 間 隔 を 測 定 す る プ ロ グ ラ ム を 約 10 秒 間 実 行 し 、 リ ア ル タ イ ム 性 能 を
評 価 し た 結 果 。 (優 先 度 を 変 更 す る た め 、 root ア カ ウ ン ト に て 実 行 )Upstream Vender 5.4 kernel 2.6.18-164 (SMP パ ッ チ 適 用 )RedHawk 5.4 Kernel 2.6.31.6 (SMP / PREEMT / CCUR 独 自 パ ッ チ 適 用 )RedHat5.4 Timer Jitter
100000

最 小 774.3μ秒
平 均 1334.9μ秒
最 大 3000.9μ秒
ジッター2226.6μ秒

10000

回数

1000

100

10

1
0

1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000 16000 17000 18000 19000
μ秒

RedHawk5.4 Timer Jitter
100000

最 小 996.5μ秒
平 均 999.9μ秒
最 大 1000.5μ秒
ジッター
4μ秒

10000

回数

1000

100

10

1
0

1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000 16000 17000 18000 19000
μ秒

Figure 6 :実 行 例 １

Title

POSIX-OS の 性 能 評 価No

Revision
Page

8Standard Forms
実行例２
同 一 ハ ー ド ウ ェ ア (パ ナ ソ ニ ッ ク )上 に て Ubuntu お よ び RedHawk で そ れ ぞ れ タ イ マ
ー ハ ン ド ラ ー の 起 動 間 隔 を 測 定 す る プ ロ グ ラ ム を 約 30 分 間 実 行 し 、 リ ア ル タ イ ム
性 能 を 評 価 し た 結 果 。 (優 先 度 を 変 更 す る た め 、 root ア カ ウ ン ト に て 実 行 )Ubuntsu 9.04 Kernel 2.6.29.6 (SMP / PREEMT / PREEMT_RT パ ッ チ 適 用 )RedHawk 5.4 Kernel 2.6.31.6 (SMP / PREEMT / CCUR 独 自 パ ッ チ 適 用 )Figure 7: 実 行 例 ２
こ の 様 に 、 RedHawk、 標 準 kernel.org と PREEEMPT_RT パ ッ チ を 適 用 し た OS と の 性 能
差 を 読 み 取 る こ と が 出 来 る た め 1000Hz の タ イ マ ー 試 験 に お い て 、 ヒ ス ト グ ラ ム と 、 標 準 偏差は有用であることが確認された。

Title

POSIX-OS の 性 能 評 価No

RevisionPage

9Standard Forms
Two-way Request Latency Test Program の 設 計 と 評 価
AEGIS に 必 要 と さ れ た リ ア ル タ イ ム OS の 性 能 を 総 合 的 に 評 価 す る 際 に 重 要 な 点 と し て 、ORB 試 験 に 示 さ れ る よ う に 、 TCP/IP の 応 答 性 能 が あ り 、 そ の 決 定 性 に は ジ ッ タ ー を 評 価 し ている点がある。
本 稿 で 設 計 す る Two-way Request Latency Test Program (以 下 TRLTP)は 、 こ の 点 を 踏 ま え 、
以下のように設計を行う。

CPU 4-(n-1)

Low
Priority

SCHED_RR

Low
Priority

CPU 3
SCHED_FIFOHigh Priority
sigwaitinfo();t0

Low
Priority

SCHED_RR

High
Prioritysend();High
Priorityrecv();High
Priorityt3

Packet Send

POSIX Timer
Interrupt

Packet Recv

Low Priority

CPU 2
t1

High
Priorityrecv();

Schedule process
is none.

SCHED_FIFO
CPU 1

High
Priority
nanosleep();

t2

High
Prioritysend();

100 micro seconds

Main process MAX Priority fork() & waitpid();

CPU 0

図１

TRLTP プ ロ グ ラ ム の 構 成プログラムは、4 つのプロセスを生成し、以下の動作を行う。
●main プ ロ セ ス 起 動 プ ロ セ ス
server,client,idle プ ロ セ ス を 起 動 し 、 各 プ ロ セ ス の 終 了 を 待 つ 。
1. SCHED_FIFO の MAX 優 先 度●client プ ロ セ ス ： 本 プ ロ グ ラ ム の 主 プ ロ セ ス
1. 1000Hz の POSIX タ イ マ ー を 生 成 し 、 そ の ジ ッ タ ー を 計 測 す る 。 (t0)
2. 1000Hz の POSIX タ イ マ ー に 同 期 し て 、 server プ ロ セ ス に 、 TCP/IP に よ っ て ８ バ イ トの ヌ ル デ ー タ を 送 信 し 、 server プ ロ セ ス か ら の 応 答 を 待 ち 、 そ の 時 点 で の タ イ ム ス タ ン
プ 計 測 (t3)を 行 う 。
3. SCHED_FIFO の MAX 優 先 度 － １●server プ ロ セ ス ： client プ ロ セ ス か ら の 依 頼 を 受 け て 実 行 さ れ る 高 優 先 度 補 助 プ ロ セ ス 。
1. client プ ロ セ ス か ら の 受 信 を select で 待 つ 。
Title

POSIX-OS の 性 能 評 価No

Revision
Page

10Standard Forms
2.
3.
4.
5.
6.

select か ら の 復 帰 後 受 信 を 行 い 、 そ の 時 点 で の タ イ ム ス タ ン プ 計 測 (t1)を 行 う 。
100μ 秒 の POSIX nanosleep()を 行 う 。
nanosleep()か ら の 復 帰 後 、 そ の 時 点 で の タ イ ム ス タ ン プ 計 測 (t2)を 行 う 。
t1,t2 の タ イ ム ス タ ン プ を デ ー タ と し て 、 client プ ロ セ ス に 送 信 す る 。
SCHED_FIFO の MAX 優 先 度 － ２●idle プ ロ セ ス
client プ ロ セ ス か ら の 依 頼 を 受 け て 実 行 さ れ る 低 優 先 度 補 助 プ ロ セ ス 。
プログラムオプションで、実行を繰り返すたび、プロセスが増えて行く。
1. client プ ロ セ ス か ら の POSIX リ ア ル タ イ ム シ グ ナ ル を 待 つ 。
2. フ ァ イ ル を オ ー プ ン し 、65536 ポ イ ン ト の 倍 精 度 fft 計 算 を 行 い 、結 果 を フ ァ イ ル に 書 き出し、消去する。
3. ２ の 処 理 を 指 示 が あ る ま で 繰 り 返 す 。
4. SCHED_RR の MIN 優 先 度
プ ロ グ ラ ム で は 、 以 下 の 値 の 統 計 デ ー タ を 、 最 小 (μ 秒 ) 平 均 (μ 秒 ) 最 大 (μ 秒 ) 偏 差 と し て 出
力 し 、 オ プ シ ョ ン -l フ ァ イ ル 名 で 指 示 し た 場 合 、 そ の ヒ ス ト グ ラ ム デ ー タ と 併 せ て フ ァ イ ル に記録する。
た だ し 、イ ン タ ー バ ル タ イ マ ー 時 間 と nanosleep の 時 間 の 偏 差 の 計 算 に は 、平 均 を 中 心 値 とはせずに、目標値を使用する。
POSIX Timer Interval Time
Send Timenanosleep(100 Micro Sec)
Receive Time
Response Time
Total Jittert0[n-1]と t0[n]間 の 値
t0[n]と t1[n]間 の 値
t1[n]と t2[n]間 の 値
t2[n]と t3[n]間 の 値
t0[n]と t3[n]間 の 値
t0[n]と t3[n]間 の 値 か ら t1[n]と t2[n]を 減 算 し 、
t1[n]と t2[n]の 差 か ら 100μ 秒 を 減 算 し た 絶 対 値 を 加 え る 。
同 様 の 操 作 で 、 t0[n-1]と t0[n]間 の 絶 対 値 を 加 算 し た 値
これは、偏差を求める際に、平均からの差ではなく、目標値との差を表現するための処置である。

な お 、プ ロ グ ラ ム は す べ て 、POSIX-API を 使 用 し 、OS に 依 存 し た 命 令 を 使 用 し て い な い が 、CPU 割 り 当 て の み 、 Linux 共 通 の 非 POSIX-API を 使 用 し て い る 。
（ 注 ： POSIX-API に は CPU 割 り 当 て の 定 義 が な い た め 、 sched_setaffinity()を 使 用 す る ）割り当て無しmain プ ロ セ ス
server プ ロ セ ス
client プ ロ セ ス
idle プ ロ セ ス

CPU0
CPU1
CPU2(エ コ ー バ ッ ク )CPU3(計 測 タ ー ゲ ッ ト )CPU3,4,5,6,7...31

通常は、デーモンなどを実行する。
SCHED_FIFO の MAX 優 先 度
SCHED_FIFO の MAX 優 先 度 -2
SCHED_FIFO の MAX 優 先 度 -1
SCHED_RR の MIN 優 先 度意味としては、① 計 測 プ ロ セ ス と 同 じ CPU に 負 荷 プ ロ セ ス を １ つ 割 り 当 る 。
②エコーバックには、最も良い状態を割り当てる
ま た 、 RedHawk RCIM の カ ウ ン タ 値 と の 差 を 排 除 す る た め に 、 CPU 内 蔵 の ク ロ ッ ク カ ウ ン タ
を tscrd 命 令 で 読 み 出 し て い る 。

Title

POSIX-OS の 性 能 評 価No

Revision
Page

11Standard Forms
ソースコード
以下に、すべてのソースコードを示す。
/** ***************************************************************************** Copyright(c) 2010 Concurrent Computer Corporation*
ALL RIGHTS RESERVED** This software is furnished under a license and may be used and copied only
* in accordance with the terms of such license and with the inclusion of the* above copyright notice. This software or any other copies thereof, may not* be provided or otherwise made available to anyone other than the licensee.
**
Title to and ownership of this software remains with*
the Concurrent Computer Corporation (CONCURRENT).
**
The information in this document is subject to change without*
notice and should not be construed as a commitment by CONCURRENT.
**CONCURRENT assumes no responsibility for the use or reliability of*its software on equipment that is not supplied by CONCURRENT.
* Version 3.0 ALL POSIX API VERSION 32bit & 64bit & TSC* *****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <time.h>#include <signal.h>#include <string.h>#include <unistd.h>#include <locale.h>#include <nl_types.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/socket.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <sys/uio.h>#include <sys/time.h>#include <poll.h>#include <netinet/tcp.h>#include <signal.h>#include <sched.h>#include <math.h>#include <string.h>#include <stdlib.h>static sig_atomic_t idle_flag=1, loop_flag=1;
char *inet_ntoa(struct in_addr in);struct sockaddr_in
tcp_srv_addr;
struct servent
tcp_serv_info;
struct hostenttcp_host_info;#define TSC#define MAX_HISTORY
200000#define MAXCOUNT
100001#define SERV_HOST_ADDR"127.0.0.1"#define CLI_HOST_ADDR"127.0.0.1"#define SERV_PORT
20000#define MAX_PACKET(65536)#define SERVER
0x01#define CLIENT
0x02#define ASYNC
0x04#define IDLE
0x08
#define TCP
0x10#define PACKET_SIZE#define END_MARK 0xFF

1024

static int DEBUG=0;
static int CYCLE=1000;
static int PORT=SERV_PORT;
Title

POSIX-OS の 性 能 評 価No

Revision
Page

12Standard Forms
FILE *logfp = NULL;
static int ASYNC_FLAG = 0;
static int TestLoop = 1;
static pid_t IdlePID[128];#definePI
3.14159265358979323846#define N 65536
typedef struct{
double r;
double i;} complex;
static int last_n = 0;
static int *bitrev = NULL;
static double *sintbl = NULL;
static double *isintbl = NULL;
static void make_sintbl2(
intn,
doublesintbl[],doubleisintbl[]){int
i,n2,n4,n8;
doublec,s,dc,ds,t;
n2 = n / 2; n4 = n / 4; n8 = n / 8;t = sin(PI / n);dc = 2 * t * t; ds = sqrt(dc*(2-dc));
t = 2 * dc; c = sintbl[n4] = 1; s = sintbl[0] = 0;
isintbl[n4] = -1; isintbl[0] = 0;
for (i=1;i<n8;i++){c -= dc; dc += t * c;s += ds; ds -= t * s;sintbl[i] = s; sintbl[n4-i] = c;isintbl[i] = -s; isintbl[n4-i] = -c;}if (n8!=0) { sintbl[n8] = sqrt(0.5); isintbl[n8]=-sintbl[n8];}
for ( i=0; i<n4; i++){sintbl[n2-i] = sintbl[i];isintbl[n2-i] = -sintbl[i];}for ( i=0; i<n2+n4; i++){sintbl[i+n2] = -sintbl[i];isintbl[i+n2] = sintbl[i];}}static int make_bitrev2(
int
n,
int
bitrev[]){int
i,j,k,n2;n2 = n/2; i = j = 0;
for( ; ; ) {bitrev[i] = j;
if (++i >= n )break;
k = n2;
while (k<=j) { j -= k; k /= 2; }j += k;}return(0);}static int make_table(int n){register int

i,j,k,n4,stage;if (n==0)
Title

POSIX-OS の 性 能 評 価No

Revision
Page

13Standard Forms{
if ( sintbl != NULL ) {free(sintbl);free(isintbl);}if ( bitrev != NULL ) free(bitrev);
return(0);}if (n<0){n= -n;}
n4 = n / 4;
if (n!=last_n || n== 0 ){last_n = n;if ( sintbl != NULL ) {free(sintbl);free(isintbl);}if ( bitrev != NULL ) free(bitrev);if (n==0) return(0);sintbl = (double *)malloc((n+n4) * sizeof(double));isintbl = (double *)malloc((n+n4) * sizeof(double));bitrev = (int *)malloc(n * sizeof(int));
if (sintbl == NULL ||isintbl == NULL|| bitrev == NULL){
fprintf(stderr,"memory allocation error¥n");return(1);}make_sintbl2(n,sintbl,isintbl);
make_bitrev2(n,bitrev);}
return(0);}static int small_fft( int n, complex v[]){int
i,j,k,ik,h,d,k2,n4,inverse;
doubles,c,dx,dy;
register complext;
if (n<0) {n= -n;

inverse = 1;

} else {inverse = 0;}n4 = n / 4;for(i=0; i < n; i++){j = bitrev[i];if(i<j){t = v[i]; v[i] = v[j]; v[j] = t;}}for (k=1;k<n;k=k2) {h = 0; k2 = k + k; d = n / k2;
for (j=0;j<k;j++) {c = sintbl[h+n4];
if (inverse) {s = -sintbl[h];} else {s = sintbl[h];}for (i=j;i<n;i+=k2) {ik = i + k;
dx = s * v[ik].i + c * v[ik].r;
dy = c * v[ik].i - s * v[ik].r;v[ik].r = v[i].r - dx; v[i].r += dx;v[ik].i = v[i].i - dy; v[i].i += dy;}h += d;}}if (!inverse) {for (i=0;i<n;i++) { v[i].r /= (double)n; v[i].i /= (double)n; }}return(0);}static void delete_posix_timer(timer_t timer_id)
Title

POSIX-OS の 性 能 評 価No

Revision
Page

14Standard Forms{
static struct itimerspec itspec;/*
Set the initial delay and period of the timer.
This also arms the timer */clock_gettime(CLOCK_MONOTONIC,&itspec.it_value);itspec.it_interval.tv_sec = 0;
itspec.it_interval.tv_nsec = 0;
timer_settime( timer_id, TIMER_ABSTIME, &itspec, NULL);
timer_delete(timer_id);}
static timer_t create_posix_timer(int signum,int sec,int nsec){
static struct sigevent event;static timer_t timer;
static struct itimerspec itspec;/* Create the POSIX timer to generate signum */event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = signum;
if (timer_create((clockid_t)CLOCK_MONOTONIC,&event,&timer)==(-1)){
fprintf(stderr, "create_posix_timer() Cannot create timer - %s¥n",strerror(errno));return ((timer_t)-1);}/*
Set the initial delay and period of the timer.
This also arms the timer */clock_gettime(CLOCK_MONOTONIC,&itspec.it_value);itspec.it_value.tv_sec += 3;
itspec.it_interval.tv_sec = sec;
itspec.it_interval.tv_nsec = nsec;
if (timer_settime( timer, TIMER_ABSTIME, &itspec, NULL)==(-1)){
return ((timer_t)-1);}
return(timer);}#if 1
unsigned long long int rdtsc() {unsigned int lo, hi;/* We cannot use "=A", since this would use %rax on x86_64 */__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));return (unsigned long long int)hi << 32 | lo;}
double cpu_clock;double getMHz(void){
double mhz;
FILE *f = fopen("/proc/cpuinfo", "r");if (f == 0){
perror("can't open /proc/cpuinfo¥n");exit(1);}for ( ; ; ){int ret;char buf[1000];
if (fgets(buf, sizeof(buf), f) == NULL){
fprintf(stderr, "FATAL: cannot locate cpu MHz in " "/proc/cpuinfo¥n");exit(1);}
ret = sscanf(buf, "cpu MHz: %lf", &mhz);
if (ret == 1){
fclose(f);return (mhz);
}
}
}

Title

POSIX-OS の 性 能 評 価No

Revision
Page

15

Standard Forms
static void readtime(struct timespec *nowtime){#ifdef TSC
unsigned long long T;
T = rdtsc();nowtime->tv_nsec = T & 0xFFFFFFFF;
nowtime->tv_sec = (T>>32) & 0xFFFFFFFF;#else
clock_gettime(CLOCK_MONOTONIC,nowtime);#endif}static void adjust(struct timespec *start,struct timespec *finish, double *realtime){#ifdef TSC
unsigned long long t0,t1;
t0 = (unsigned long long)start->tv_sec;
t0 <<=32;
t0 |= 0xFFFFFFFF & (unsigned long long)(start->tv_nsec);
t1 = (unsigned long long)finish->tv_sec;
t1 <<=32;
t1 |= 0xFFFFFFFF & (unsigned long long)(finish->tv_nsec);*realtime = (double)(t1-t0)/cpu_clock;
#else
int
sec,nsec;
sec = finish->tv_sec - start->tv_sec;
nsec = finish->tv_nsec - start->tv_nsec;
if (nsec<0){
sec --;
nsec += 1000000000;}*realtime = (double)(nsec/1000)+(double)(sec*1000000);#endif}#else#define readtime(nowtime)clock_gettime(CLOCK_MONOTONIC,nowtime)
static void adjust( struct timespec *start, struct timespec *finish, double *realtime){
int
sec,nsec;
sec = finish->tv_sec - start->tv_sec;
nsec = finish->tv_nsec - start->tv_nsec;
if (nsec<0){
sec --;
nsec += 1000000000;}*realtime = (double)(nsec/1000)+(double)(sec*1000000);}#endifstatic int server(int option){
int
listenfd,sockfd,fromlen,len,cli_len;
struct sockaddr_in serv_addr,from;struct sockaddr_in cli_addr;
static unsigned char serv_buff[MAX_PACKET];
static int count=1;
struct timespec t0,t1,t2,diff;double real;
fd_set rfd;
int ret,n;
int on = 1;
int sumlen = 0;
struct timespec seltimeout;
time_t now;
struct tm *ptm;
static struct sched_param myparam;
fd_set readfds,writefds,execptfds;
struct timeval timeout={0,0};
int
nfds=0;static sigset_t set,oset;
Title

POSIX-OS の 性 能 評 価No

Revision
Page

16Standard Forms
struct pollfd
fdarray[1];struct timespec w100={0,100000};
mlockall(MCL_CURRENT|MCL_FUTURE);
myparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-2;
sched_setscheduler(getpid(),SCHED_FIFO,&myparam);{
cpu_set_t mask;
int ret,cpu;
unsigned int cpusetsize;
cpusetsize = sizeof(cpu_set_t);
CPU_ZERO(&mask);
CPU_SET(2,&mask);
ret = sched_setaffinity(getpid(),cpusetsize,&mask);
if (ret<0){
printf("sched_setaffinity(%08X) is error %s¥n",mask,strerror(errno));}}{if ((listenfd = socket (AF_INET, SOCK_STREAM, 0)) < 0){fprintf(stderr,"server: can't create TCP socket¥n");return(-1);}
if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){fprintf(stderr,"server: can't set socket option¥n");return(-1);}
bzero((char *)&serv_addr,sizeof(serv_addr));serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(PORT);
if (bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))<0){
fprintf(stderr,"server: can't bind TCP socket¥n");close(listenfd);
return(-1);}
if (listen(listenfd,1)<0){
fprintf(stderr,"server: can't listen TCP socket¥n");close(listenfd);
return(-1);}
cli_len = sizeof(cli_addr);
if ((sockfd = accept(listenfd,(struct sockaddr*)&cli_addr,&cli_len))<0){
fprintf(stderr,"server: can't accept TCP socket¥n");close(listenfd);
return(-1);}
if(setsockopt(sockfd, IPPROTO_TCP, SO_PRIORITY, &on, sizeof(on)) < 0){fprintf(stderr,"server: can't set socket option¥n");return(-1);}}
sigemptyset(&set);sigaddset(&set,SIGALRM);
if (sigprocmask(SIG_UNBLOCK,&set,&oset)==(-1)){
fprintf(stderr, "%s: Cannot set sigprocmask - %s¥n", strerror(errno));exit(1);}
nfds=1;
fdarray[0].fd = sockfd;
fdarray[0].events = POLLIN;
for(n=0;n<TestLoop;n++){Title

POSIX-OS の 性 能 評 価No

RevisionPage

17Standard Forms
count=0;
while(loop_flag){if (poll(fdarray,nfds,1000)>0){
sched_yield(); len = read(sockfd,serv_buff,sizeof(serv_buff));
if(len == sizeof(struct timespec)){
readtime(&t1);
memcpy(serv_buff,(void*)&t1,sizeof(struct timespec));
nanosleep(&w100,0);
readtime(&t1);
memcpy(&serv_buff[sizeof(struct
timespec)],(void*)&t1,sizeof(struct timespec));
write(sockfd,serv_buff,sizeof(struct

timespec)*2);

sched_yield();
count++;}
else{
break;}}}}
close(sockfd);
if(logfp) fclose(logfp);
return(0);}void calc(FILE *logfp,struct timespec *t0,struct timespec *t1,char *tag,double target ){static double real[MAXCOUNT],min,max,avr,s,x;
static int his[MAX_HISTORY];
register int count;min=1000000000;
s=avr =max=0;
memset((void*)his,0,sizeof(his));memset((void*)real,0,sizeof(real));for(count=0;count<MAXCOUNT-1;count++){
adjust(&t0[count],&t1[count],&real[count]);
his[(int)(real[count]+0.5)/10]++;
avr += real[count];
if (min> real[count]) min = real[count];
if (max< real[count]) max = real[count];}
avr /= (double)(MAXCOUNT-1);
for(count=0;count<MAXCOUNT-1;count++){
if (target==0.0)
x=real[count]-avr;
else
x=real[count]-target;s+= (x * x);}s = sqrt(s/(double)(MAXCOUNT-2));
printf("%s¥tmin%8.1f(MicroSec)
avr
S %8.1f¥n",tag,min,avr,max,s);if(logfp){%8.1f(MicroSec)

max%8.1f(MicroSec)

fprintf(logfp,"%s¥t,Min,%8.1f,(MicroSeconds),Avr,%8.1f,(MicroSeconds),Max,%8.1f,(MicroSeconds),Sta
ndard deviation,%8.1f¥n",tag,min,avr,max,s);
fprintf(logfp,"Time(MicroSeconds),Number of Times¥n",count*10,his[count]);for(count=0;count<MAX_HISTORY;count++){
if (his[count]) fprintf(logfp,"%d,%d¥n",count*10,his[count]);}
fprintf(logfp,"¥n¥n");
}
}
Title

POSIX-OS の 性 能 評 価No

Revision
Page

18

Standard Forms
static int client(void *vp,int option){
unsigned char *host;int
sockfd,fromlen,len;struct sockaddr_in serv_addr,dest;
static unsigned char cli_sbuf[MAX_PACKET];
int err,signum,n;struct hostent *hp;
unsigned long inaddr;
int on = 1;
static struct sigaction newact;
static sigset_t set,oset;
static timer_t timer_id;
static siginfo_t info;
static struct itimerspec itspec;
static struct timespec t0[MAXCOUNT];
static struct timespec t1[MAXCOUNT];
static struct timespec t2[MAXCOUNT];
static struct timespec t3[MAXCOUNT];
static struct sched_param myparam;
union sigval val;
struct timespec w0={1,10000000};
static double interval[MAXCOUNT],min,max,avr,s,x;
static double total[MAXCOUNT];
static int his[MAX_HISTORY];
register int count;nanosleep(&w0,NULL);
mlockall(MCL_CURRENT|MCL_FUTURE);
myparam.sched_priority = sched_get_priority_max(SCHED_FIFO)-1;
sched_setscheduler(getpid(),SCHED_FIFO,&myparam);{
cpu_set_t mask;
int ret,cpu;
unsigned int cpusetsize;
cpusetsize = sizeof(cpu_set_t);
CPU_ZERO(&mask);
CPU_SET(4,&mask);
ret = sched_setaffinity(getpid(),cpusetsize,&mask);
if (ret<0){
printf("sched_setaffinity(%08X) is error %s¥n",mask,strerror(errno));}}signum = SIGRTMIN+1;
if (sigprocmask(0,NULL,&set)==(-1)){
fprintf(stderr, "Cannot get sigprocmask - %s¥n",strerror(errno));exit(1);}
sigaddset(&set,signum);if (sigprocmask(SIG_SETMASK,&set,&oset)==(-1)){
fprintf(stderr, "%s: Cannot set sigprocmask - %s¥n", strerror(errno));exit(1);}

host = (unsigned char *)vp;
bzero((char *)&serv_addr,sizeof(serv_addr));serv_addr.sin_family = AF_INET;
if((inaddr = inet_addr(host)) != (-1) ){memcpy((char *)&serv_addr.sin_addr,(char *)&inaddr,
sizeof(inaddr));} else {if((hp = gethostbyname (host))==NULL){
fprintf(stderr,"udp_open: host name error: %s¥n",host);
return(-1);}
memcpy((char *)&serv_addr.sin_addr,hp->h_addr,
Title

POSIX-OS の 性 能 評 価No

Revision
Page

19Standard Forms
hp->h_length);}{serv_addr.sin_port = htons(PORT);
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0){fprintf(stderr,"client: can't create TCP socket¥n");return(-1);}
if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0){fprintf(stderr,"client: can't set socket option¥n");return(-1);}
if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0){fprintf(stderr,"client: can't set socket option¥n");return(-1);}
if(setsockopt(sockfd, IPPROTO_TCP, SO_PRIORITY, &on, sizeof(on)) < 0){fprintf(stderr,"client: can't set socket option¥n");return(-1);}
if (connect(sockfd,(void*)&serv_addr,sizeof(struct sockaddr_in))<0){
fprintf(stderr,"client: can't connect TCP socket¥n");return(-1);}}
if (ASYNC_FLAG) fcntl(sockfd, F_SETFL, O_ASYNC);
memcpy((void*)&dest,(void*)&serv_addr,sizeof(struct sockaddr_in));
len = sizeof(struct timespec);
for(n=0;n<TestLoop;n++){if (n){
val.sival_int=n;sigqueue(IdlePID[n-1],SIGRTMIN,val);if (DEBUG) printf("sigqueue %d¥n",IdlePID[n-1]);
nanosleep(&w0,NULL);}
if (CYCLE==1){
timer_id = create_posix_timer(signum,1,0);}
else{
timer_id = create_posix_timer(signum,0,(1000*1000*1000)/CYCLE);}
if (timer_id<0){fprintf(stderr, "%s: Cannot set posix timer - %s¥n", strerror(errno));exit(1);}
printf("********************************************* ¥n");printf("**** Low priority Client Number %4d:**** ¥n",n);printf("**** Posix Timer Cycle %4d Hz**** ¥n",CYCLE);
printf("********************************************* ¥n");if (logfp){
fprintf(logfp,"********************************************* ¥n");fprintf(logfp,"**** Low priority Client Number %4d:**** ¥n",n);fprintf(logfp,"**** Posix Timer Cycle %4d Hz**** ¥n",CYCLE);
fprintf(logfp,"********************************************* ¥n");}count=0;
err = sigwaitinfo(&set,&info);do{err = sigwaitinfo(&set,&info);
readtime(&t0[count]);
memset(cli_sbuf,0,sizeof(struct timespec));
Title

POSIX-OS の 性 能 評 価No

Revision
Page

20

Standard Forms
err = write(sockfd,cli_sbuf,sizeof(struct timespec)); sched_yield();
if (err<0){
if (errno == EINTR){
printf("intr ");}fprintf(stderr,"write error %s¥n",strerror(errno));break;}
sched_yield();
len = read(sockfd,cli_sbuf,sizeof(struct timespec)*2);
readtime(&t3[count]);
memcpy(&t1[count],&cli_sbuf[0],sizeof(struct timespec));
memcpy(&t2[count],&cli_sbuf[sizeof(struct timespec)],sizeof(struct timespec));count++;} while ((loop_flag)&&(count<MAXCOUNT));
cli_sbuf[0] = END_MARK;
err = write(sockfd,cli_sbuf,1); sched_yield();
delete_posix_timer(timer_id);calc(logfp,&t0[0],&t0[1],"POSIX Timer Interval Time ",0.0);
calc(logfp,&t0[0],&t1[0],"Send Time",0.0);
calc(logfp,&t1[0],&t2[0],"nanosleep(100 Micro Sec) ",100.0);
calc(logfp,&t2[0],&t3[0],"Receive Time",0.0);
calc(logfp,&t0[0],&t3[0],"Response Time",0.0);
min=1000000000;
s=avr =max=0;
memset((void*)his,0,sizeof(his));memset((void*)interval,0,sizeof(interval));memset((void*)total,0,sizeof(total));for(count=1;count<MAXCOUNT;count++){
adjust(&t0[count-1],&t1[count],&interval[count]);
adjust(&t0[count],&t3[count],&total[count]);
adjust(&t1[count],&t2[count],&x);
total[count] -= x; total[count] += fabs(x-100);interval[count] = fabs(interval[count] - (double)CYCLE);//
total[count] += interval[count] ;his[(int)(total[count]+0.5)/10]++;
avr += total[count];
if (min> total[count]) min = total[count];
if (max< total[count]) max = total[count];}
avr /= (double)(MAXCOUNT-1);
for(count=0;count<MAXCOUNT-1;count++){
x=total[count]-avr;
s+= (x * x);}s = sqrt(s/(double)(MAXCOUNT-2));
printf("Total Jitter Time¥tmin %8.1f(MicroSec) avr %8.1f(MicroSec) max %8.1f(MicroSec)
S %8.1f¥n",min,avr,max,s);if(logfp){
fprintf(logfp,"Total
Jitter¥t,Min,%8.1f,(MicroSeconds),Avr,%8.1f,(MicroSeconds),Max,%8.1f,(MicroSeconds),Standard
deviation,%8.1f¥n",min,avr,max,s);
fprintf(logfp,"Time(MicroSeconds),Number of Times¥n",count*10,his[count]);for(count=0;count<MAX_HISTORY;count++){
if (his[count]) fprintf(logfp,"%d,%d¥n",count*10,his[count]);}
fprintf(logfp,"¥n¥n");}}close(sockfd);
if(logfp) fclose(logfp);
return(0);
}

Title

POSIX-OS の 性 能 評 価No

RevisionPage

21

Standard Forms
void main_sigint_handler(int no){
printf("main_sigint_handler¥n");loop_flag=0;}
void idle_sigint_handler(int no){idle_flag=0;}
static int idle_process(int no){
static struct sched_param myparam;
double x,y;static sigset_t set,oset;
static siginfo_t info;
char fname[256];
FILE * fp;
register int i,n;static complex c1[N],c2[N];n=N;
sprintf(fname,"/tmp/dummy%d",no);mlockall(MCL_CURRENT|MCL_FUTURE);
myparam.sched_priority = sched_get_priority_min(SCHED_RR);
sched_setscheduler(getpid(),SCHED_RR,&myparam);{
cpu_set_t mask;
int ret,cpu;
unsigned int cpusetsize;
cpusetsize = sizeof(cpu_set_t);
CPU_ZERO(&mask);
for(cpu=3;cpu<32;cpu++)
CPU_SET(cpu,&mask);
ret = sched_setaffinity(getpid(),cpusetsize,&mask);
if (ret<0){
printf("sched_setaffinity(%08X) is error %s¥n",mask,strerror(errno));}}signal(SIGINT,idle_sigint_handler);if (DEBUG) printf("suspend %d(pid=%d)¥n",no,getpid());
sigemptyset(&set);sigaddset(&set,SIGRTMIN);
if (sigprocmask(SIG_BLOCK,&set,&oset)==(-1)){
fprintf(stderr, "%s: Cannot set sigprocmask - %s¥n", strerror(errno));exit(1);}
sigwaitinfo(&set,&info);
if (DEBUG) printf("wakeup %d¥n",getpid());
while(idle_flag){
fp = fopen(fname, "w"); unlink(fname);for(i=0;i<n;i++){c1[i].r = c2[i].r = 6 * cos( 6 * PI * i / n)
+ 4 * sin(18 * PI * i / n);c1[i].i = c2[i].i = 0;}
small_fft(n,c2);
small_fft(-n,c2);
for(i=0;i<n;i++){if (fp) fprintf(fp,"(%f,%f)¥n", c1[i].r , c1[i].i );}if(fp) fclose(fp);sched_yield();}
if (DEBUG) printf("exit %d¥n",getpid());
exit(0);
Title

POSIX-OS の 性 能 評 価No

Revision
Page

22

Standard Forms}
static void do_main(int option,unsigned char *host){
pid_t ServerPID;
pid_t ClientPID;
int status,i,n;
union sigval val;
if (option & IDLE){
for (n=0;n<TestLoop-1;n++){IdlePID[n]=fork();if (IdlePID[n]<0){
fprintf(stderr,"server fork error¥n");exit(0);}if (IdlePID[n]==0){
idle_process(n);exit(0);}}}if (option & SERVER){
ServerPID=fork();
if (ServerPID<0){fprintf(stderr,"server fork error¥n");exit(0);}if (ServerPID==0){
server(TCP);
exit(0);}}if (option & CLIENT){
ClientPID=fork();
if (ClientPID<0){fprintf(stderr,"client fork error¥n");exit(0);}if (ClientPID==0){
client(host,TCP);
exit(0);}}if (option & CLIENT){
waitpid(ClientPID,&status,0);}
if (option & SERVER){
waitpid(ServerPID,&status,0);}
if (option & IDLE){
for (n=0;n<TestLoop-1;n++){val.sival_int=n;sigqueue(IdlePID[n],SIGINT,val);if (DEBUG) printf("sigqueue %d¥n",IdlePID[n-1]);
waitpid(IdlePID[n],&status,0);}}exit(0);}
Title

POSIX-OS の 性 能 評 価No

RevisionPage

23

Standard Forms
static void intr_handler(int sig,siginfo_t *info, void *dummy){
printf("signal number is %d¥n",sig);}
int main( int argc, char **argv ){extern int optind;extern char *optarg;
register int c, option = SERVER|CLIENT;
unsigned char host[256];
static struct sigaction newact;
static struct sched_param myparam;
cpu_clock = getMHz();
mlockall(MCL_CURRENT|MCL_FUTURE);
myparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(getpid(),SCHED_FIFO,&myparam);signal(SIGINT,main_sigint_handler);sigaddset(&newact.sa_mask,SIGRTMIN);
newact.sa_sigaction = intr_handler;
newact.sa_flags = SA_SIGINFO|SA_RESTART;
if (sigaction(SIGIO, &newact, 0)==(-1)){
fprintf(stderr, "Cannot set sigaction - %s¥n",strerror(errno));return(1);}strcpy((char*)host,SERV_HOST_ADDR);
while((c = getopt(argc, argv, "DC:asc:p:l:i:")) != EOF){
switch(c){case 'p':
PORT=atoi(optarg);
printf("PORT %d¥n",PORT);
break;
case 'C':CYCLE=atoi(optarg);
if (CYCLE<=0) CYCLE = 1;
if (CYCLE>=10000) CYCLE = 10000;
printf("CYCLE %d Hz¥n",CYCLE);
break;
case 'D':
DEBUG =1;
break;
case 'a':ASYNC_FLAG |=ASYNC;
break;
case 'c':option|=CLIENT;
strcpy(host,optarg);
printf("address %s¥n",host);
break;
case 's':
option|=SERVER;
break;
case 'l':logfp = fopen(optarg, "w");
break;
case 'i':
option|=IDLE;
TestLoop=atoi(optarg);
break;
default:
printf("¥tD:DEBUG¥n¥t¥tC

Cycle:default

1000Hz¥n¥ts

server¥n¥tc

client¥n");break;}}
make_table(N);do_main(option,host);
make_table(0);}Title

POSIX-OS の 性 能 評 価No

RevisionPage

24

Standard Forms
Makefile
CMPCMD = cc -c $(CCOPT) $(USRDEF) $(SETSMP) -I .
LIBCMD = ar ruv
LNKCMD = cc $(CCOPT)
TRLTP= trltp
EXTLIB= -lrt
LNKOBJ= $(TRLTP).o
TEMPFILES= core core.*
CFLAGS= -O -D_GNU_SOURCELDFLAGS=$(TRLTP): $(LNKOBJ)$(LNKCMD) $(LDFLAGS) -o $(TRLTP)$(LNKOBJ) $(LNKLIB) $(EXTLIB) -lm.c.o:$(CMPCMD) $(CFLAGS) $<$(LNKOBJ):$(SYSINC) Makefile

clean:-rm -f $(TEMPFILES) $(LNKOBJ) $(TRLTP)

Title

POSIX-OS の 性 能 評 価No

RevisionPage

25

Standard Forms
TRLTP ベ ン チ マ ー ク 試 験 の 結 果
以 下 に 、 Dell T5500 4-Core 2-CPU メ イ ン メ モ リ 6G バ イ ト で 行 っ た① kernel.org(RHEL,SUSE 等 ),② PREEMPT_RT 適 用 Linux(MRG,SLRT,Ubuntu 等 ),③ RedHawk5.4.5の結果を示す。
結 果 は 、す べ て 、同 一 マ シ ン 、同 一 バ イ ナ リ オ ブ ジ ェ ク ト 、64 ビ ッ ト OS の 性 能 で あ り 、時間 の 単 位 は μ 秒 で あ る 。 ま た 、 低 優 先 度 プ ロ セ ス は 15 個 存 在 す る 状 態 で 行 っ た 。

Title

POSIX-OS の 性 能 評 価No

RevisionPage

26

Standard Forms
POSIX Interval Timer ヒ ス ト グ ラ ム
POSIX Interval Timer Histogram
100000

Number of Times

10000

1000

100

10

1
Kernel.org Min(Micro seconds) 774.8 Avr(Micro seconds) 1000.1 Max(Micro seconds) 2225.6 Standard deviation 11.9
PREEMPT_RT Min(Micro seconds) 972.5 Avr(Micro seconds) 1000.2 Max(Micro seconds) 1027.2 Standard deviation 2.3
RedHawk545 Min(Micro seconds) 990.4 Avr(Micro seconds) 999.9 Max(Micro seconds) 1008.9 Standard deviation 0.6

770 780 790 800 810 820 830 840 850 860 870 880 890 900 910 920 930 940 950 960 970 980 990
1

2

7
5

100 101 102 103 104 105 106 107 108 109 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

3 4945 5051 5
226 2646 7293 364 13
2538 7461

6

2

1

1

Micro Seconds

POSIX Interval Timer は 、 sigwaitinfo()実 行 中 の プ リ エ ン プ シ ョ ン 時 間 を 計 測 し て い る 。
RedHawk と PREEMPT_RT は 、 ほ ぼ 同 等 の 性 能 を 示 し て い る が 、 ヒ ス ト グ ラ ム を み る と RedHawk の ジ ッ タ ー が よ り 小 さ い 。
プ リ エ ン プ ト パ ッ チ が 適 用 さ れ て い な い 、Kernel.org で は 、同 一 CPU に 割 り 当 て ら れ た 、低 優 先 度 プ ロ セ ス か ら の 影 響 を 大 き く 受 け て い る た め 、ジッターが大きいことが示されている。

Kernel.org
PREEMPT_RT
RedHawk545
Title

POSIX-OS の 性 能 評 価

最小
774.8
972.5
990.4

平均
1000.11000.2999.9
No

最大2225.61027.21008.9
Revision
Page

27

偏差
11.9
2.3
0.6

Standard Forms
Send Time ヒ ス ト グ ラ ム

Send Time Histogram
100000

Number of Times

10000

1000

100

10

1
30

40

9884 1148
Kernel.org Min(Micro seconds) 14.1 Avr(Micro seconds) 16.8 Max(Micro seconds) 574 Standard deviation 2.2
PREEMPT_RT Min(Micro seconds) 17.2 Avr(Micro seconds) 20.1 Max(Micro seconds) 52 Standard deviation 1.4 3185 6805 87
RedHawk545 Min(Micro seconds) 15.7 Avr(Micro seconds) 17.3 Max(Micro seconds) 42.7 Standard deviation 1.1 9576 4224 8

10

20

2

50

60

70

80

90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570

1

1

1

1
1

Micro Seconds
送 信 時 間 は 、エ コ ー バ ッ ク プ ロ セ ス (server)に 対 す る 、送 信 時 間 で あ る が 、送 信 プ ロ セ ス と 同 じ CPU に 負 荷 プ ロ セ ス が 存 在 す る た め か 、あ る い は
IRQ デ ー モ ン の ス ケ ジ ュ ー ル 遅 延 か 、 Kernel.org で は ジ ッ タ ー が 非 常 に 大 き く 見 え る 。

Kernel.org
PREEMPT_RT
RedHawk545
Title

POSIX-OS の 性 能 評 価

最小
14.1
17.2
15.7

平均
16.8
20.1
17.3
No

最大
574.0
52.0
42.7
Revision
Page

28

偏差
2.2
1.4
1.1

Standard Forms
nanosleep ヒ ス ト グ ラ ム

Number of Times

RedHawk の ピ ー ク は 102.9
102.2 か ら 103.6 と 1.2μ 間100μ か ら の 偏 差 は 2.9μ
PREEMPT_RT の ピ ー ク は 102.5 だが 101.9 か ら 111.1 の 9.2μ 間100μ か ら の 偏 差 は 2.5μnanosleep(100micro) Time Histogram
100000
10000
1000
100
10
1

100

Kernel.org Min(Micro seconds) 152.5 Avr(Micro seconds)
153.9 Max(Micro seconds) 279.5 Standard deviation 53.9
99841
PREEMPT_RT Min(Micro seconds) 101.9 Avr(Microseconds) 102.5 Max(Micro seconds) 111.1 Standard
deviation 2.5
100000
RedHawk545 Min(Micro seconds) 102.2 Avr(Microseconds) 102.9 Max(Micro seconds) 103.6 Standard
deviation 2.9

110

120

130

140

150
99988

160
2

170
1

180
6

190
1

270
1

280
1

159

Micro Seconds

nanosleep の 結 果 は 、 非 常 に OS の 性 格 を 現 し て い る 、 設 計 上 無 負 荷 で あ る に も か か わ ら ず 、 kernel.org で は 、 100μ 秒 の 要 求 に 対 し て 、 150μ 秒
以 上 の 時 間 で し か 戻 っ て こ な い た め 、 100μ 秒 の 使 用 に 耐 え な い 。
し か し 、kernel.org に 対 し て PREEEMPT_RT パ ッ チ を 適 用 し た OS で あ る PREEMPT_RT で は 、kernel.org に 比 較 し て 、非 常 に 良 い 結 果 を 示 して い る 。kernel.org で は 、平 均 値 で 2.5μ の オ ー バ ー ヘ ッ ド で 、RedHawk で は 2.9μ 秒 の オ ー バ ー ヘ ッ ド が 存 在 す る 結 果 と な っ た 。こ の グ ラ フ と 偏
差 を 比 較 す る と 、 偏 差 で は 、 PREEMPT_RT が 良 い 性 能 を 示 し て い る の に ヒ ス ト グ ラ ム で は PREEMPT_RT よ り RedHawk の 分 散 が 少 な い 。
こ れ は 、 目 標 値 100μ 秒 に 対 し て の 分 散 を 求 め て い る た め 、 PREEMPT_RT の 方 が 良 い 結 果 に な る た め で あ る 。
平 均 に 対 し て の 分 散 を 求 め る と RedHawk の 分 散 が 少 な い 結 果 に な る が 、nanosleep に 関 し て は 、PREEMPT_RT が 良 い 性 能 を 示 し て い る と 言 え る 。
最小
平均
最大
偏差
Kernel.org
152.5
153.9
279.5
53.9
PREEMPT_RT
101.9
102.5
111.1
2.5
RedHawk545
102.2
102.9
103.6
2.9
Title

POSIX-OS の 性 能 評 価No

RevisionPage

29

Standard Forms
Receive Time ヒ ス ト グ ラ ム
Receive Time Histogram
100000

Number of Times

10000

1000

100

10

1
10

20

30

40

50

10

20

30

40

50

4

5

Kernel.org Min(Micro seconds) 11.5 Avr(Micro seconds) 13 Max(Micro seconds) 55.2 Standard deviation 0.7

99949

26

16

PREEMPT_RT Min(Micro seconds) 14 Avr(Micro seconds) 17 Max(Micro seconds) 38.2 Standard deviation 1.9

94914

5002

84

RedHawk545 Min(Micro seconds) 12.2 Avr(Micro seconds) 13.6 Max(Micro seconds) 24.8 Standard deviation 0.4

99999

1

Micro Seconds

受 信 時 間 は 、 エ コ ー バ ッ ク プ ロ セ ス (server)か ら の 応 答 遅 延 を 現 し て い る 。 送 信 時 間 に 比 べ る と OS 間 に 差 異 は 少 な い 。
こ れ は 、 送 信 側 の CPU が 無 負 荷 で あ る こ と が 原 因 で あ る と 考 え る こ と が 出 来 る 。
し た が っ て 、 先 の 送 信 結 果 と 併 せ て 考 え る と 、 送 信 時 に 送 信 終 了 待 ち が 存 在 し 、 同 一 CPU に 優 先 度 の 低 い プ ロ セ ス が 存 在 す る と 、 優 先 度 の 低 いプロセスが送信終了まで、実行されプリエンプトパッチが適用されていないと、送信遅延を引き起こす事となることが理解できる。
最小
平均
最大
偏差
11.5
13.0
55.2
0.7
Kernel.org
14.0
17.0
38.2
1.9
PREEMPT_RT
12.2
13.6
24.8
0.4
RedHawk545
Title

POSIX-OS の 性 能 評 価No

Revision
Page

30

Standard Forms
Response Time ヒ ス ト グ ラ ム

Respoce Time Histogram
120000100000

Number of Times

80000

60000

40000

20000

0
130
Kernel.org Min(Micro seconds) 179.1 Avr(Micro seconds) 183.7 Max(Micro seconds) 746.5 Standard deviation 2.6
PREEMPT_RT Min(Micro seconds) 134 Avr(Micro seconds) 139.5 Max(Micro seconds) 186.1 Standard deviation 2.8
RedHawk545 Min(Micro seconds) 131.4 Avr(Micro seconds) 133.8 Max(Micro seconds) 170.8 Standard deviation 1.2

140

150

160

170

130

140

150

160

66103
99648

31978
349

1905
2

13

180

190

200

210

220

230

240

300

310

540

740

170

180

190

200

210

220

230

240

300

310

540

740

12

99740
1

208

17

9

8

1

1

1

1

1

1

1

Micro Seconds
こ れ は 、 送 信 、 nanosleep(100μ 秒 )、 受 信 の す べ て の 結 果 で あ る 。
最低でも、５回のシステムコール、５回の再スケジュール時のジッターを含んでいる。
最小
平均
179.1
183.7
Kernel.org
134.0
139.5
PREEMPT_RT
131.4
133.8
RedHawk545
Title

POSIX-OS の 性 能 評 価

No

最大
746.5
186.1
170.8

Revision
Page

31

偏差
2.6
2.8
1.2

Standard Forms
Total Time ヒ ス ト グ ラ ム
Total Time Histogram

80000
70000

Number of Times

60000
50000
40000
30000
20000
10000
0

10

20

30

40

50

60

70

80

58588 36738 38042
484

Kernel.org Min 88.2 Avr 100.7 Max 1332.7 Standard deviation 12.8
PREEMPT_RT Min 38 Avr 59.8 Max 109.9 Standard deviation 4.6
RedHawk545 Min 41.1 Avr 51.1 Max 83.5 Standard deviation 2.3

5309

24678 74458

804

56

100

110

120

130

140

150

190

200

210

220

230

290

780

41679 57315
67
4

90

945
1

18

11

4

1

1

7

2

1

1

1

1

1220 1230 1240 1250
1

1

6

1

1260 1330
1

1

4Micro Seconds
上 記 総 て の 時 間 を 数 値 化 し た 結 果 で あ り 。 こ の 数 値 だ け で OS の 性 能 が 端 的 に 現 さ れ て い る 。
最小
平均
最大
偏差
88.2
100.7
1332.7
12.8
Kernel.org
38.0
59.8
109.9
4.6
PREEMPT_RT
41.1
51.1
83.5
2.3
RedHawk545
このように、トータルジッターだけを見てリアルタイム総合性能を評価できることが理解でき、本プログラムの設計が正しいことを示している。
Title

POSIX-OS の 性 能 評 価No

RevisionPage

32

Standard Forms
まとめ
以下に、低優先度プロセスの数を増やした場合の、最小、平均、最大、偏差の値を示す。
トータル応答時間
最小
Kernel.org

平均

PREEMPT_RT

RedHawk

Kernel.org

最大

PREEMPT_RT

RedHawk

Kernel.org

偏差PREEMPT_RT

RedHawk

Kernel.org

PREEMPT_RT

RedHawk

96.1

54.4

54.6

118

73.4

68.5

11451.9

91

76.3

44.7

1.1

1.3

80.1

53.5

42.2

105.3

63.5

56

6927.6

100.3

77.8

33.2

1.9

1.1

81.5

51.5

42.7

93.5

64.1

56

1361.4

77.1

76.6

13.4

2.1

1

80

51

43

94.2

65.1

56.2

1221.4

95.4

82.2

12.3

2.6

1

78.1

47.8

38.1

99.6

54.3

43.4

2317.4

87.2

72

13.3

2.6

1.3

83.8

44.3

40.9

99.8

54

50.6

1748.5

82.6

80

15.6

2.2

2.2

82.4

44.9

44.7

99.8

55.2

50.6

7031.6

88.9

85.1

55.9

3.1

2.3

83.3

41

43.1

99.3

58.3

50.6

6571.4

91.1

84.8

48.2

4.1

2.3

57.4

38.4

42.8

104.9

59.2

50.6

7083.6

95.6

83.5

149.3

4.3

2.2

85.6

37.9

44

100.7

59.5

50.7

6460.3

99.8

83

82.2

4.5

2.3

86.9

38.7

45.3

100

60.6

50.7

5085.7

103.6

83.3

20.1

4.7

2.4

85.4

38.1

44.7

101.2

60

50.9

6770.7

103.8

83.8

67.5

4.8

2.3

86.7

38.6

43.3

100.3

60.3

50.9

6532.5

103.7

82.7

24.6

4.9

2.3

87.7

38.3

45.5

100.2

60.2

51

7487.8

115.2

80.1

35.7

4.9

2.4

85.8

37.5

44.8

100.2

60.5

51.1

12843.5

104.8

85.4

46.9

5

2.3

88.2

38

41.1

100.7

59.8

51.1

1332.7

109.9

83.5

12.8

4.6

2.3

リ ア ル タ イ ム 性 能 の 尺 度 と し て 、 デ タ ー ミ ニ ズ ム （ 決 定 性 ）、 つ ま り “ジ ッ タ ー が 小 さ い 事 “と 考 え る と 、 本 TRLTP 試 験 の 偏 差 が 小 さ い こ と 考 えることが出来る。
し た が っ て ① RedHawk、 ② PREEMPT_RT の 順 で リ ア ル タ イ ム 性 能 が 高 い こ と が 示 さ れ 、 kernrl.org に は リ ア ル タ イ ム 性 が 皆 無 （ 決 定 性 な し ）であるとの結果が示されている。

Title

POSIX-OS の 性 能 評 価No

Revision
Page

33

Standard Forms
平均応答時間
140
120

μ秒

100
80
60
40
20
0
0

1

2

3

4

5

6
7
8
9
低優先度プロセスの数

Kernel.org

PREEMPT_RT

10

11

12

13

14

15

RedHawk

上のグラフは平均応答時間を示したものであり、性能は異なるが同じ傾向を示していることが読み取れる。
つまり、低優先度プロセスの数を増やして行くと、平均的な応答時間は一定の値に近づき、無負荷状態からの増加ではなく減少にあるという、
一見矛盾した結果になっている点である。
これは、プロセスの数が増加するとコンテキストスイッチや割り込みの回数が増加し、カーネル内でのスケジューリング回数が増加する事に原因がある。
す な わ ち 、 “カ ー ネ ル に 対 す る 要 求 回 数 ”＝ “再 ス ケ ジ ュ ー ル “で あ る こ と で 、 高 速 に 応 答 す る こ と に な る 。
こ の 事 実 は 、 OS の 性 能 評 価 に 注 意 が 必 要 で あ る こ と を 示 し て い る 。 つ ま り 、 む や み に 負 荷 を 増 や す と 、 そ の 性 能 を 見 誤 る こ と に な り か ね な いと考えることが出来るからである。

Title

POSIX-OS の 性 能 評 価No

Revision
Page

34

Standard Forms
右のグラフは、平均応答時間に対するジッターである。
プロセス数にかかわらず、
RedHawk は 、３ μ 秒 以 下 の 良 い 性 能を 示 し て い る が 、 Kernel.org は 相 関関係が無い。
つ ま り 、 Kernel.org で は 、 計 算 可
能性（データミニズム）が欠如していることであり、リアルタイム性は無いと結論づけられる。
PREEMPT_RT は 、 一 定 の 性 能 を示しているが、低優先度クライアン
ト 数 を 増 加 し て い く とPREEMPT_RT は 、 相 対 的 に 性 能 が落ちて行く傾向に有る。
次ページのグラフは、右の棒グラ
フを折れ線グラフに変更したものである。先に述べたとおり、低優先度
クライアント数を増加していくとPREEMPT_RT は 、 相 対 的 に 性 能 が落ちて行く傾向にあり、この試験では低優先度プロセスの数が５の点から変化が起こっている。
こ れ は 、 CPU3 か ら 順 に 負 荷 プ ロ
セスを割り当てると、5 で今回のシス テ ム に 搭 載 さ れ た CPU 上 限 に 達することと関係がある。
つ ま り 、 PREEMPT_RT に お い ては 、CPU コ ア に 割 り 当 て る プ ロ セ ス
数が増加すると、それが低優先度のプロセスであっても、高優先度のプ
ロセスの応答性により影響してゆくと結論づけることが出来る。
Title

POSIX-OS の 性 能 評 価

トータルジッター
160
140
120
100
80
60
40
20
0
μ秒

0

1

2

3

4

5

6

7

8

9

10

11

低優先度プロセスの数

RedHawk 偏差No

PREEMPT_RT 偏差

Revision
Page

35

12

13

14

Kernel.org 偏差Kernel.org 偏差PREEMPT_RT 偏差
RedHawk 偏差15

Standard Forms
RedHawk の 場 合 に は 、 以 下 の グ ラ フ か ら そ の 影 響 は 小 さ い こ と を 読 み 取 る こ と が で き る 。
こ の よ う に 、RedHawk は 、リ ア ル タ イ ム 応 答 性 の 向 上 に 寄 与 す る よ う に 設 計 さ れ 応 答 性 保 証の 無 い の PREEMPT_RT パ ッ チ を 当 て た だ け の Kernel2.6 系 Linux と は 、 一 線 を 画 す る 性 能 であることを確認出来たと結論づけられる。

μ秒

トータルジッター偏差

159
156
153
150
147
144
141
138
135
132
129
126
123
120
117
114
111
108
105
102
99
96
93
90
87
84
81
78
75
72
69
66
63
60
57
54
51
48
45
42
39
36
33
30
27
24
21
18
15
12
9
6
3
0

Kernel.org
PREEMPT_RT
RedHawk

kernel.org
PREEMPT_RT

RedHawk
0

Title

1

2

3

4

5

6
7
8
9
低優先度プロセス数

POSIX-OS の 性 能 評 価

10

No

11

12

13

14

15

RevisionPage

36

Standard Forms

参考文献
(1)

“The Use of POSIX in Real-time Systems, Assessing its Effectiveness and Performance”

Kevin M. Obenland, The MITRE Corporation, 1820 Dolley Madison Blvd. McLean, VA 22102, obenland@mitre.org
http://www.mitre.org/work/tech_papers/tech_papers_00/obenland_posix/obenland_posix.pdf(2) “ An Empirical Evaluation of OS Support for Real-time CORBA Object Request Brokers”
David L. Levine, Sergio Flores-Gaitan, and Douglas C. Schmidt flevine,sergio,schmidtg@cs.wustl.edu
Department of Computer Science, Washington University St. Louis, MO 63130, USA
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.2228&rep=rep1&type=pdf

Title

POSIX-OS の 性 能 評 価No

RevisionPage37