OSDN Git Service

(none)
[hos/hos-v4a.git] / kernel / source / arch / proc / win / win32 / ctxctl.c
1 /** 
2  *  Hyper Operating System V4 Advance
3  *
4  * @file  ctxctlc
5  * @brief %jp{コンテキスト制御}%en{context control}
6  *
7  * Copyright (C) 1998-2007 by Project HOS
8  * http://sourceforge.jp/projects/hos/
9  */
10
11
12
13 #include "core/core.h"
14 #include "object/inhobj.h"
15
16
17
18 static DWORD WINAPI             _kernel_ctx_ent(LPVOID param);                                  /* %jp{スレッドの開始関数} */
19 static void                             _kernel_run_ctx(_KERNEL_T_CTXCB *pk_ctxcb);             /* %jp{スレッドの実行開始} */
20 static void                             _kernel_wai_ctx(_KERNEL_T_CTXCB *pk_ctxcb);             /* %jp{スレッドの停止待ち} */
21
22
23 static CRITICAL_SECTION _kernel_win32_CriticalSection;
24 static _KERNEL_T_CTXCB  *_kernel_win32_runctxcb        = NULL;          /**< %jp{実行中のコンテキスト} */
25 static _KERNEL_T_CTXCB  *_kernel_win32_intctxcb        = NULL;          /**< %jp{割込みからスイッチされたコンテキスト} */
26 static HANDLE                   _kernel_win32_hSemDisInt       = NULL;          /**< %jp{システムの排他制御用セマフォ} */
27 static volatile BOOL    _kernel_win32_blIntCtx         = FALSE;         /**< %jp{割込み処理中フラグ} */
28 static volatile BOOL    _kernel_win32_blDisInt         = TRUE;          /**< %jp{割込み禁止フラグ} */
29 static volatile BOOL    _kernel_win32_blIntDsp         = FALSE;         /**< %jp{割込み時ディスパッチフラグ} */
30 static DWORD                    _kernel_win32_hPrimaryThreadId = 0;                     /**< %jp{プライマリスレッドID} */
31
32
33
34 /** %jp{システムの初期化} */
35 void _kernel_ini_prc(void)
36 {
37         InitializeCriticalSection(&_kernel_win32_CriticalSection);
38
39         /* %jp{プライマリスレッドIDの保存} */
40         _kernel_win32_hPrimaryThreadId = GetCurrentThreadId();
41
42         /* %jp{割り込み禁止に見立てるセマフォの作成} */
43         _kernel_win32_hSemDisInt = CreateSemaphore(NULL, 0, 1, NULL);
44 }
45
46
47 /** %jp{割り込み禁止} */
48 void _kernel_dis_int(void)
49 {
50         /* 割込みコンテキストから呼ばれたなら何もしない */
51         if ( _kernel_win32_blIntCtx )
52         {
53                 return;
54         }
55
56         /* 既に割込み禁止で無ければセマフォを取る */
57         if ( !_kernel_win32_blDisInt )
58         {
59                 WaitForSingleObject(_kernel_win32_hSemDisInt, INFINITE);
60                 _kernel_win32_blDisInt = TRUE;
61         }
62 }
63
64
65 /** %jp{割り込み許可} */
66 void _kernel_ena_int(void)
67 {
68         /* 割込みコンテキストから呼ばれたなら何もしない */
69         if ( _kernel_win32_blIntCtx )
70         {
71                 return;
72         }
73         
74         /* 既に割込み禁止ならセマフォを返す */
75         if ( _kernel_win32_blDisInt )
76         {
77                 _kernel_win32_blDisInt = FALSE;
78                 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
79         }
80 }
81
82
83
84 /** %jp{実行コンテキストの作成} */
85 void _kernel_cre_ctx(
86                 _KERNEL_T_CTXCB *pk_ctxcb,              /* コンテキストを作成するアドレス */
87                 FP              entry,                  /* コンテキストの実行開始番地 */
88                 VP_INT          exinf1,                 /* コンテキストの実行時パラメータ1 */
89                 VP_INT          exinf2)                 /* コンテキストの実行時パラメータ2 */
90 {
91         pk_ctxcb->blIntSuspend = FALSE;
92
93         /* %jp{起動情報を格納} */
94         pk_ctxcb->entry  = entry;
95         pk_ctxcb->exinf1 = exinf1;
96         pk_ctxcb->exinf2 = exinf2;
97         
98         /* %jp{コンテキストスレッド生成} */
99         pk_ctxcb->hEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);
100         pk_ctxcb->hThread = CreateThread(NULL, 0, _kernel_ctx_ent, (LPVOID)pk_ctxcb,
101                                                                         0, &pk_ctxcb->dwThreadId);
102 }
103
104
105 /** %jp{スレッドの開始関数} */
106 DWORD WINAPI _kernel_ctx_ent(LPVOID param)
107 {
108         _KERNEL_T_CTXCB *pk_ctxcb;
109
110         /* %jp{コンテキスト情報取得} */
111         pk_ctxcb = (_KERNEL_T_CTXCB *)param;
112
113         /* %jp{開始待ち} */
114         WaitForSingleObject(pk_ctxcb->hEvent, INFINITE);
115
116         /* %jp{リスタート用setjmp} */
117         setjmp(pk_ctxcb->jmpenv);
118
119         /* 開始 */
120         pk_ctxcb->entry(pk_ctxcb->exinf1, pk_ctxcb->exinf2);
121         
122         return 0;
123 }
124
125
126 /** %jp{実行コンテキストの削除} */
127 void _kernel_del_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
128 {
129         /* スレッド削除 */
130         TerminateThread(pk_ctxcb->hThread, 0);
131         CloseHandle(pk_ctxcb->hThread);
132         CloseHandle(pk_ctxcb->hEvent);
133 }
134
135
136 /** %jp{実行コンテキストのリスタート} */
137 void _kernel_rst_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
138 {
139         longjmp(pk_ctxcb->jmpenv, 0);
140 }
141
142
143 /** %jp{実行コンテキストの切替} */
144 void _kernel_swi_ctx(
145                 _KERNEL_T_CTXCB *ctxcb_now,             /* 現在のコンテキストの保存先 */
146                 _KERNEL_T_CTXCB *ctxcb_nxt)             /* 新たに実行するコンテキスト */
147 {
148         /* %jp{切り替え無しならそのまま} */
149         if ( ctxcb_now == ctxcb_nxt )
150         {
151                 return;
152         }
153         
154         /* 割込み処理から呼ばれたら */
155         if ( _kernel_win32_blIntCtx )
156         {
157                 /* 切り替えを予約 */
158                 _kernel_win32_blIntDsp = TRUE;
159                 _kernel_win32_intctxcb = ctxcb_nxt;
160         }
161         else
162         {
163                 /* 切り替え先スレッドの動作開始 */
164                 _kernel_run_ctx(ctxcb_nxt);
165                 
166                 /* %jp{再開待ち} */
167                 WaitForSingleObject(ctxcb_now->hEvent, INFINITE);
168         }
169 }       
170
171
172 /** %jp{アイドル時の処理} */
173 void _kernel_wai_int(void)
174 {
175         Sleep(10);
176 }
177
178
179 /** %jp{コンテキストの開始} */
180 void _kernel_sta_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
181 {
182         /* %jp{スレッドの実行開始} */
183         _kernel_run_ctx(pk_ctxcb);
184
185         if ( GetCurrentThreadId() == _kernel_win32_hPrimaryThreadId )
186         {
187                 /* %jp{ダイアログを表示} */
188                 MessageBox(NULL, "Press OK, Exit a process", "Hyper Operationg System V4 Advance for Win32", MB_OK);
189
190                 /* %jp{終了} */
191                 ExitProcess(0);
192         }
193 }
194
195
196 /** %jp{スレッドの実行開始} */
197 void _kernel_run_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
198 {
199         /* %jp{実行中コンテキストの登録} */
200         _kernel_win32_runctxcb = pk_ctxcb;
201         
202         /* %jp{割り込みから中断されていた場合} */
203         if ( pk_ctxcb->blIntSuspend )
204         {
205                 /* %jp{割り込み用セマフォを返す} */
206                 _kernel_win32_blDisInt = FALSE;
207                 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
208                 
209                 /* スレッド動作再開 */
210                 pk_ctxcb->blIntSuspend = FALSE;
211                 ResumeThread(pk_ctxcb->hThread);
212         }
213         else
214         {
215                 /* %jp{スレッドを起こす} */
216                 SetEvent(pk_ctxcb->hEvent);
217         }
218 }
219
220
221
222 /* %jp{割り込み用処理} */
223 void vsig_int(int inhno)
224 {
225         EnterCriticalSection(&_kernel_win32_CriticalSection);
226
227         /* %jp{割り込み用セマフォを取る} */
228         WaitForSingleObject(_kernel_win32_hSemDisInt, INFINITE);
229         _kernel_win32_blDisInt = TRUE;
230         
231         /* %jp{現在実行中のスレッドを止める} */
232         SuspendThread(_kernel_win32_runctxcb->hThread);
233         
234         /* %jp{割り込み状態に設定} */
235         _kernel_win32_blIntCtx = TRUE;
236         _kernel_win32_blIntDsp = FALSE;
237         
238         /* %jp{割り込み処理} */
239         _kernel_sta_inh();
240         _kernel_exe_inh(inhno);
241         _kernel_end_inh();
242
243         /* %jp{割り込み状態を解除} */
244         _kernel_win32_blIntCtx = FALSE;
245         
246
247         /* %jp{遅延ディスパッチ発生なら} */
248         if ( _kernel_win32_blIntDsp )
249         {
250                 /* 元のスレッドをサスペンドのままマーク */
251                 _kernel_win32_runctxcb->blIntSuspend = TRUE;
252                 
253                 /* 切り替え先スレッドの動作開始 */
254                 _kernel_run_ctx(_kernel_win32_intctxcb);
255         }
256         else
257         {
258                 /* %jp{割り込み用セマフォを返す} */
259                 _kernel_win32_blDisInt = FALSE;
260                 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
261                 
262                 /* %jp{現在実行中のスレッドを再開} */
263                 ResumeThread(_kernel_win32_runctxcb->hThread);
264         }
265
266         LeaveCriticalSection(&_kernel_win32_CriticalSection);
267 }
268
269
270
271 /* end of file */