SEMA.C
[目次 | 関数 | マクロ]
1|/**************************************************************************
2|* 1. <<< 状態セマフォ (Sema) >>>
3|*
4|* Status Semaphore
5|*
6|*・資源の状態に対するセマフォ。
7|*・一般のセマフォは、複数のタスクが同じ資源にアクセスすることによる共有違反
8|* を防ぐためのものだが、状態セマフォは、1つのタスクであっても資源をアクセ
9|* スするのに適切な状態になっていない場合にエラー通知するためのもの。
10|*・たとえば、メモリを節約するために巨大なメモリ領域を様々な用途に用いる場合、
11|* そのメモリに入っている内容がどの状態(内容)なのかをチェックすることが出来る。
12|*・_CHECKER マクロを define しているときだけチェックが有効になります。
13|*・同じ関数の"引数"の中で Sema_chg と Sema_chk をいっしょに使わないこと。
14|* 評価のタイミングがコンパイラによって未定義なため。
15|*・ca732 コンパイラでは -O0 オプションにすると正しく動きません。
16|* -O1 以上にしてください。
17|*
18|*・次の2つのクラスがあります。
19|* ・状態セマフォ [Sema]
20|* ・状態(資源) [Sema_Res]
21|*
22|*・たとえば、次のように用います。
23|*
24|* char buf[1000];
25|* Sema buf_sem; // buf の状態を監視する状態セマフォ
26|* Sema_Res DiskLabel, Zuyo, ViewSet;
27|* DiskLabel = Zuyo = ViewSet = buf_sem; // 3つの状態を buf_sem の管理下に置いた
28|*
29|* // ファイルから DiskLabel を buf へ読み込み、
30|* // buf の状態を DiskLabel に変える
31|* // Sema_chg(buf,DiskLabel) は、状態を変える以外は buf の参照と同じ
32|* read_DiskLabel( file, Sema_chg(buf,DiskLabel), size );
33|* // 上は read_DiskLabel( file, buf, size ); と等価
34|*
35|* // アクセスする際は、buf の状態をチェック
36|* // Sema_chk(buf,DiskLabel) は、状態チェック以外は buf の参照と同じ
37|* Sema_chk(buf,DiskLabel)[100] = 0x61;
38|* // 上は buf[100] = 0x61; と等価
39|*
40|***************************************************************************/
41|
42|#include <all.h>
43|
44|#ifdef _CA732
45|void error_func( char* file, int line );
46|
47|int Sema_error_func( char* file, int line )
48|{
49| error_func( file, line ); return 0;
50|}
51|#endif
52|
53|/*-----------------------------------------------------------------*/
54|#if 0 /* テスト */
55|
56|#define _CHECKER
57|#include "sema.h"
58|/*
59|cl -D_DOS16 sema.c
60|a:\ca732\bin\ca732 -c -O3 -Xi -w2 -cpu 742 -G0 -D_CA732 sema.c
61|run386 ld732 -B -cpu 742 -o sema.elf -D dfile start.o sema.o
62|*/
63|
64|#define NULL 0
65|
66|/* エラーチェック変数 */
67|/* CA732 では err0 == 0 なら成功、DOS16 では ERROR! 表示が無ければ成功 */
68|extern int err[];
69|#ifdef _CA732
70| extern int err0;
71|#endif
72|
73|/* errors コンポーネントの代わり */
74|#define error() error_func( __FILE__, __LINE__ )
75|void error_func( char* file, int line )
76|{
77| static int i=0;
78| err[i++] = line;
79|
80| #ifdef _DOS16
81| printf( "Error in %s:%d\n", file, line );
82| #endif
83|}
84|
85|/* チェック用変数 */
86|char* buf = "a";
87|char *p, *p2, *p3, *p4, *p5, *p6;
88|Sema s1,s2,s3,s4,s5,s6;
89|
90|int err[10];
91|#ifdef _CA732
92|int err0;
93|#endif
94|
95|Sema sem;
96|Sema_Res DiskLabel;
97|Sema_Res Zuyo;
98|Sema_Res ViewSet;
99|
100|/* チェックする内容 */
101|void main()
102|{
103| int line1, line2;
104|
105| DiskLabel = &sem;
106| Zuyo = &sem;
107| ViewSet = &sem;
108|
109| p = Sema_chg(buf,DiskLabel);
110| s1 = sem;
111| p2 = Sema_chk(buf,DiskLabel);
112| s2 = sem;
113|
114| p3 = Sema_chg(buf,Zuyo);
115| s3 = sem;
116| p4 = Sema_chk(buf,DiskLabel); line1 = __LINE__;
117| s4 = sem;
118| p5 = Sema_chk(buf,ViewSet); line2 = __LINE__;
119| s5 = sem;
120| p6 = Sema_chk(buf,Zuyo);
121| s6 = sem;
122|
123| if ( buf != p || buf != p2 || buf != p3 ||
124| buf != p4 || buf != p5 || buf != p6 ||
125| s1 != &DiskLabel || s2 != &DiskLabel ||
126| s3 != &Zuyo || s4 != &Zuyo || s5 != &Zuyo || s6 != &Zuyo ||
127| err[0] != line1 || err[1] !=line2 || err[3] != 0 )
128| #ifdef _DOS16
129| { int i; printf( "ERROR!\n" );
130| for (i=0;i<3;i++) printf( "%d\n",err[i] ); }
131| #endif
132| #ifdef _CA732
133| err0 = 1;
134| #endif
135|}
136|
137|#endif
138|
139|