Index: EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c
===================================================================
--- EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c	(revision 331)
+++ EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c	(revision 429)
@@ -6,5 +6,5 @@
  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
  *                              Toyohashi Univ. of Technology, JAPAN
- *  Copyright (C) 2004-2016 by Embedded and Real-Time Systems Laboratory
+ *  Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory
  *              Graduate School of Information Science, Nagoya Univ., JAPAN
  * 
@@ -48,23 +48,28 @@
  *  プログラムの概要:
  *
- *  ユーザインタフェースを受け持つメインタスク（タスクID: MAIN_TASK，優
- *  先度: MAIN_PRIORITY）と，3つの並行実行されるタスク（タスクID:
- *  TASK1～TASK3，初期優先度: MID_PRIORITY）で構成される．また，起動周
- *  期が2秒の周期ハンドラ（周期ハンドラID: CYCHDR1）を用いる．
- *
- *  並行実行されるタスクは，task_loop回空ループを実行する度に，タスクが
- *  実行中であることをあらわすメッセージを表示する．空ループを実行する
- *  のは，空ループなしでメッセージを出力すると，多量のメッセージが出力
- *  され，プログラムの動作が確認しずらくなるためである．また，低速なシ
+ *  ユーザインタフェースを受け持つメインタスク（MAIN_TASK）と，3つの並
+ *  行実行されるタスク（TASK1～TASK3），例外処理タスク（EXC_TASK）の5
+ *  つのタスクを用いる．これらの他に，システムログタスクが動作する．ま
+ *  た，周期ハンドラ，アラームハンドラ，割込みサービスルーチン，CPU例
+ *  外ハンドラをそれぞれ1つ用いる．
+ *
+ *  並行実行されるタスクは，task_loop回のループを実行する度に，タスク
+ *  が実行中であることをあらわすメッセージを表示する．ループを実行する
+ *  のは，プログラムの動作を確認しやすくするためである．また，低速なシ
  *  リアルポートを用いてメッセージを出力する場合に，すべてのメッセージ
  *  が出力できるように，メッセージの量を制限するという理由もある．
  *
- *  周期ハンドラは，三つの優先度（HIGH_PRIORITY，MID_PRIORITY，
- *  LOW_PRIORITY）のレディキューを回転させる．プログラムの起動直後は，
- *  周期ハンドラは停止状態になっている．
- *
- *  メインタスクは，シリアルI/Oポートからの文字入力を行い（文字入力を
- *  待っている間は，並行実行されるタスクが実行されている），入力された
- *  文字に対応した処理を実行する．入力された文字と処理の関係は次の通り．
+ *  周期ハンドラ，アラームハンドラ，割込みサービスルーチンは，3つの優
+ *  先度（HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY）のレディキューを
+ *  回転させる．周期ハンドラは，プログラムの起動直後は停止状態になって
+ *  いる．
+ *
+ *  CPU例外ハンドラは，CPU例外からの復帰が可能な場合には，例外処理タス
+ *  クを起動する．例外処理タスクは，CPU例外を起こしたタスクに対して，
+ *  終了要求を行う．
+ *
+ *  メインタスクは，シリアルポートからの文字入力を行い（文字入力を待っ
+ *  ている間は，並行実行されるタスクが実行されている），入力された文字
+ *  に対応した処理を実行する．入力された文字と処理の関係は次の通り．
  *  Control-Cまたは'Q'が入力されると，プログラムを終了する．
  *
@@ -97,12 +102,11 @@
  *  'b' : アラームハンドラを5秒後に起動するよう動作開始させる．
  *  'B' : アラームハンドラを動作停止させる．
- *  'z' : 対象タスクにCPU例外を発生させる（タスクを終了させる）．
- *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（プログラムを
- *        終了する）．
+ *  'z' : 対象タスクにCPU例外を発生させる（ターゲットによっては復帰可能）．
+ *  'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる（復帰不可能）．
  *  '@' : タスク3をacre_tskにより生成する．
  *  '!' : 対象タスクをdel_tskにより削除する．
  *  '$' : アラームハンドラをacre_almにより生成する．
  *  '#' : アラームハンドラをdel_almにより削除する．
- *  'V' : fch_hrtで高分解能タイマを2回読む．
+ *  'V' : 短いループを挟んで，fch_hrtで高分解能タイマを2回読む．
  *  'v' : 発行したシステムコールを表示する（デフォルト）．
  *  'q' : 発行したシステムコールを表示しない．
@@ -116,5 +120,4 @@
 #include "kernel_cfg.h"
 #include "sample1.h"
-/*#include "sample1n.h"*/
 
 /*
@@ -132,4 +135,22 @@
 
 /*
+ *  プロセッサ時間の消費
+ *
+ *  ループによりプロセッサ時間を消費する．最適化ができないように，ルー
+ *  プ内でvolatile変数を読み込む．
+ */
+static volatile long_t	volatile_var;
+
+static void
+consume_time(ulong_t ctime)
+{
+	ulong_t		i;
+
+	for (i = 0; i < ctime; i++) {
+		(void) volatile_var;
+	}
+}
+
+/*
  *  並行実行されるタスクへのメッセージ領域
  */
@@ -144,7 +165,7 @@
  *  並行実行されるタスク
  */
-void task(intptr_t exinf)
-{
-	volatile ulong_t	i;
+void
+task(intptr_t exinf)
+{
 	int_t		n = 0;
 	int_t		tskno = (int_t) exinf;
@@ -155,5 +176,5 @@
 		syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
 										tskno, ++n, graph[tskno-1]);
-		for (i = 0; i < task_loop; i++);
+		consume_time(task_loop);
 		c = message[tskno-1];
 		message[tskno-1] = 0;
@@ -202,9 +223,13 @@
 
 /*
- *  割込みハンドラ
+ *  割込みサービスルーチン
+ *
+ *  HIGH_PRIORITY，MID_PRIORITY，LOW_PRIORITY の各優先度のレディキュー
+ *  を回転させる．
  */
 #ifdef INTNO1
 
-void intno1_isr(intptr_t exinf)
+void
+intno1_isr(intptr_t exinf)
 {
 	intno1_clear();
@@ -235,5 +260,5 @@
 					"sns_dpn() is not true in CPU exception handler.");
 	}
-	syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d xsns_dpn = %d",
+	syslog(LOG_INFO, "sns_loc = %d, sns_dsp = %d, xsns_dpn = %d",
 								sns_loc(), sns_dsp(), xsns_dpn(p_excinf));
 
@@ -244,13 +269,6 @@
 	}
 
-#ifdef PREPARE_RETURN_CPUEXC
-	PREPARE_RETURN_CPUEXC;
 	SVC_PERROR(get_tid(&cpuexc_tskid));
 	SVC_PERROR(act_tsk(EXC_TASK));
-#else /* PREPARE_RETURN_CPUEXC */
-	syslog(LOG_NOTICE, "Sample program ends with exception.");
-	SVC_PERROR(ext_ker());
-	assert(0);
-#endif /* PREPARE_RETURN_CPUEXC */
 }
 
@@ -263,5 +281,6 @@
  *  を回転させる．
  */
-void cyclic_handler(intptr_t exinf)
+void
+cyclic_handler(intptr_t exinf)
 {
 	SVC_PERROR(rot_rdq(HIGH_PRIORITY));
@@ -276,5 +295,6 @@
  *  を回転させる．
  */
-void alarm_handler(intptr_t exinf)
+void
+alarm_handler(intptr_t exinf)
 {
 	SVC_PERROR(rot_rdq(HIGH_PRIORITY));
@@ -286,5 +306,6 @@
  *  例外処理タスク
  */
-void exc_task(intptr_t exinf)
+void
+exc_task(intptr_t exinf)
 {
 	SVC_PERROR(ras_ter(cpuexc_tskid));
@@ -294,5 +315,6 @@
  *  メインタスク
  */
-void main_task(intptr_t exinf)
+void
+main_task(intptr_t exinf)
 {
 	char	c;
@@ -302,5 +324,4 @@
 	PRI		tskpri;
 #ifndef TASK_LOOP
-	volatile ulong_t	i;
 	SYSTIM	stime1, stime2;
 #endif /* TASK_LOOP */
@@ -332,27 +353,26 @@
  	 *  ループ回数の設定
 	 *
-	 *  並行実行されるタスク内での空ループの回数（task_loop）は，空ルー
-	 *  プの実行時間が約0.4秒になるように設定する．この設定のために，
-	 *  LOOP_REF回の空ループの実行時間を，その前後でget_timを呼ぶことで
-	 *  測定し，その測定結果から空ループの実行時間が0.4秒になるループ回
-	 *  数を求め，task_loopに設定する．
+	 *  並行実行されるタスク内でのループの回数（task_loop）は，ループ
+	 *  の実行時間が約0.4秒になるように設定する．この設定のために，
+	 *  LOOP_REF回のループの実行時間を，その前後でget_timを呼ぶことで
+	 *  測定し，その測定結果から空ループの実行時間が0.4秒になるループ
+	 *  回数を求め，task_loopに設定する．
 	 *
-	 *  LOOP_REFは，デフォルトでは1,000,000に設定しているが，想定したよ
-	 *  り遅いプロセッサでは，サンプルプログラムの実行開始に時間がかか
-	 *  りすぎるという問題を生じる．逆に想定したより速いプロセッサでは，
-	 *  LOOP_REF回の空ループの実行時間が短くなり，task_loopに設定する値
-	 *  の誤差が大きくなるという問題がある．
-	 *
-	 *  そこで，そのようなターゲットでは，target_test.hで，LOOP_REFを適
-	 *  切な値に定義するのが望ましい．
+	 *  LOOP_REFは，デフォルトでは1,000,000に設定しているが，想定した
+	 *  より遅いプロセッサでは，サンプルプログラムの実行開始に時間がか
+	 *  かりすぎるという問題を生じる．逆に想定したより速いプロセッサで
+	 *  は，LOOP_REF回のループの実行時間が短くなり，task_loopに設定す
+	 *  る値の誤差が大きくなるという問題がある．そこで，そのようなター
+	 *  ゲットでは，target_test.hで，LOOP_REFを適切な値に定義すること
+	 *  とする．
 	 *
 	 *  また，task_loopの値を固定したい場合には，その値をTASK_LOOPにマ
-	 *  クロ定義する．TASK_LOOPがマクロ定義されている場合，上記の測定を
-	 *  行わずに，TASK_LOOPに定義された値を空ループの回数とする．
+	 *  クロ定義する．TASK_LOOPがマクロ定義されている場合，上記の測定
+	 *  を行わずに，TASK_LOOPに定義された値をループの回数とする．
 	 *
-	 * ターゲットによっては，空ループの実行時間の1回目の測定で，本来よ
-	 * りも長めになるものがある．このようなターゲットでは，MEASURE_TWICE
-	 * をマクロ定義することで，1回目の測定結果を捨てて，2回目の測定結果
-	 * を使う．
+	 *  ターゲットによっては，ループの実行時間の1回目の測定で，本来より
+	 *  も長めになるものがある．このようなターゲットでは，MEASURE_TWICE
+	 *  をマクロ定義することで，1回目の測定結果を捨てて，2回目の測定結
+	 *  果を使う．
 	 */
 #ifdef TASK_LOOP
@@ -361,13 +381,11 @@
 
 #ifdef MEASURE_TWICE
-	task_loop = LOOP_REF;
 	SVC_PERROR(get_tim(&stime1));
-	for (i = 0; i < task_loop; i++);
+	consume_time(LOOP_REF);
 	SVC_PERROR(get_tim(&stime2));
 #endif /* MEASURE_TWICE */
 
-	task_loop = LOOP_REF;
 	SVC_PERROR(get_tim(&stime1));
-	for (i = 0; i < task_loop; i++);
+	consume_time(LOOP_REF);
 	SVC_PERROR(get_tim(&stime2));
 	task_loop = LOOP_REF * 400LU / (ulong_t)(stime2 - stime1) * 1000LU;
@@ -477,17 +495,17 @@
 			break;
 		case 'c':
-			syslog(LOG_INFO, "#sta_cyc(1)");
+			syslog(LOG_INFO, "#sta_cyc(CYCHDR1)");
 			SVC_PERROR(sta_cyc(CYCHDR1));
 			break;
 		case 'C':
-			syslog(LOG_INFO, "#stp_cyc(1)");
+			syslog(LOG_INFO, "#stp_cyc(CYCHDR1)");
 			SVC_PERROR(stp_cyc(CYCHDR1));
 			break;
 		case 'b':
-			syslog(LOG_INFO, "#sta_alm(1, 5000000)");
+			syslog(LOG_INFO, "#sta_alm(ALMHDR1, 5000000)");
 			SVC_PERROR(sta_alm(ALMHDR1, 5000000));
 			break;
 		case 'B':
-			syslog(LOG_INFO, "#stp_alm(1)");
+			syslog(LOG_INFO, "#stp_alm(ALMHDR1)");
 			SVC_PERROR(stp_alm(ALMHDR1));
 			break;
@@ -499,7 +517,10 @@
 			ctsk.stksz = STACK_SIZE;
 			ctsk.stk = NULL;
-			SVC_PERROR(TASK3 = acre_tsk(&ctsk));
-			syslog(LOG_NOTICE, "task3 is created with tskid = %d.",
+			SVC_PERROR(ercd = acre_tsk(&ctsk));
+			if (ercd >= 0) {
+				TASK3 = ercd;
+				syslog(LOG_NOTICE, "task3 is created with tskid = %d.",
 														(int_t) TASK3);
+			}
 			break;
 		case '!':
@@ -512,10 +533,13 @@
 			calm.nfyinfo.nfy.handler.exinf = (intptr_t) 0;
 			calm.nfyinfo.nfy.handler.tmehdr = (TMEHDR) alarm_handler;
-			SVC_PERROR(ALMHDR1 = acre_alm(&calm));
-			syslog(LOG_NOTICE, "alarm handler is created with almid = %d.",
+			SVC_PERROR(ercd = acre_alm(&calm));
+			if (ercd >= 0) {
+				ALMHDR1 = ercd;
+				syslog(LOG_NOTICE, "alarm handler is created with almid = %d.",
 														(int_t) ALMHDR1);
+			}
 			break;
 		case '#':
-			syslog(LOG_INFO, "#del_alm(1)");
+			syslog(LOG_INFO, "#del_alm(ALMHDR1)");
 			SVC_PERROR(del_alm(ALMHDR1));
 			break;
@@ -523,7 +547,8 @@
 		case 'V':
 			hrtcnt1 = fch_hrt();
+			consume_time(1000LU);
 			hrtcnt2 = fch_hrt();
 			syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu",
-										hrtcnt1, hrtcnt2);
+								(uint32_t) hrtcnt1, (uint32_t) hrtcnt2);
 			break;
 
@@ -552,5 +577,10 @@
 #endif /* BIT_KERNEL */
 
+		case '\003':
+		case 'Q':
+			break;
+
 		default:
+			syslog(LOG_INFO, "Unknown command: '%c'.", c);
 			break;
 		}
