3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2003-2004 Takagi Nobuhisa
10 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によって公表されている GNU General Public License の Version 2 に記
12 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
37 * @(#) $Id: cxx_sample2.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
43 * このサンプルプログラムは「哲学者の食事」をベースとして、C++の各機能
45 * 5人の哲学者が左右のフォークを取る際、故意にデッドロックを発生させ、
46 * タイムアウトを検出した時点でC++の例外を送出している。
48 * 動作中に'q'を入力すると動作を停止することができ、restart? [y|n]に対
49 * して'y'を入力すれば再起動、'n'を入力すれば終了する。
50 * また、動作中に'a'を入力すればアボートする。
53 #include <t_services.h>
56 #include "kernel_id.h"
57 #include "cxx_sample2.h"
60 // 静的オブジェクトのコンストラクタとデストラクタの動作サンプル
61 class non_multitask_test
66 : x_(new int(12345)) // カーネル非動作状態でのnew演算子
72 syslog(LOG_NOTICE,"non-multitask test succeeded");
74 syslog(LOG_NOTICE,"non-multitask test failed");
75 delete x_; // カーネル非動作状態でのdelete演算子
87 static unsigned int seed = 1;
89 seed = seed * 1566083941UL + 1;
91 return (seed >> 16) % 0x7fff;
100 explicit fork(int semid)
101 : semid_(semid), used_(false)
109 ID id() const { return semid_; }
110 bool is_used() const { return used_; }
113 if (twai_sem(semid_, 500*5) == E_TMOUT)
114 throw timeout_error();
133 explicit philosopher(int tskid, fork* left, fork* right)
135 left_(left), right_(right)
137 syslog(LOG_NOTICE,"philosofer #%d", tskid);
141 syslog(LOG_NOTICE, "#%d thinking...", tskid_);
142 dly_tsk(100 * (rnd() % 5 + 1));
146 syslog(LOG_NOTICE, "#%d eat up", tskid_);
147 dly_tsk(100 * (rnd() % 5 + 1));
157 syslog(LOG_NOTICE, "#%d take left fork(%d)", tskid_, left_->id());
159 dly_tsk(100 * (rnd() % 5 + 1));
162 syslog(LOG_NOTICE, "#%d take right fork(%d)", tskid_, right_->id());
167 syslog(LOG_NOTICE, "#%d give left fork(%d)", tskid_, left_->id());
169 syslog(LOG_NOTICE, "#%d give right fork(%d)", tskid_, right_->id());
172 catch (timeout_error&)
174 // タイムアウトによりデッドロックを検出すると、フォークを放す。
175 syslog(LOG_NOTICE, "#%d !!!! timeout error !!!!", tskid_);
176 if (left_->is_used())
179 syslog(LOG_NOTICE, "#%d give left fork(%d)", tskid_, left_->id());
181 if (right_->is_used())
184 syslog(LOG_NOTICE, "#%d give right fork(%d)", tskid_, right_->id());
192 void task(VP_INT exinf)
194 _toppers_cxxrt_reset_specific(); // タスクの再起動を可能にするための初期化処理
195 ID tskid = ID(exinf);
196 fork* left = p_fork[(tskid - 1) % 5];
197 fork* right = p_fork[(tskid - 1 + 4) % 5];
198 philosopher phil(tskid, left, right);
202 // std::atexitで登録する終了時関数
205 syslog(LOG_NOTICE, "finish");
210 void main_task(VP_INT exinf)
212 serial_ctl_por(TASK_PORTID, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV));
213 syslog(LOG_NOTICE,"Sample program starts (exinf = %d)", exinf);
221 for (ID semid = 1; semid <= 5; semid++)
222 p_fork[semid - 1] = new fork(semid);
224 for (ID tskid = 1; tskid <= 5; tskid++)
230 serial_rea_dat(TASK_PORTID, &c, 1);
233 } while (c != 'q' && c != 'Q');
235 for (ID tskid = 1; tskid <= 5; tskid++)
240 for (ID semid = 1; semid <= 5; semid++)
242 delete p_fork[semid - 1];
243 p_fork[semid - 1] = 0;
248 syslog(LOG_NOTICE, "restart? [y|n] ");
249 serial_rea_dat(TASK_PORTID, &c, 1);
250 } while (c != 'y' && c != 'n');
256 syslog(LOG_NOTICE, "multitask test succeeded");
258 catch (std::bad_alloc&)
260 syslog(LOG_NOTICE, "multitask test failed");