2 * Hyper Operating System V4 Advance
5 * @brief %jp{コンテキスト制御}%en{context control}
7 * Copyright (C) 1998-2007 by Project HOS
8 * http://sourceforge.jp/projects/hos/
13 #include "core/core.h"
14 #include "object/inhobj.h"
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{スレッドの停止待ち} */
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} */
35 void _kernel_ini_prc(void)
37 InitializeCriticalSection(&_kernel_win32_CriticalSection);
39 /* %jp{プライマリスレッドIDの保存} */
40 _kernel_win32_hPrimaryThreadId = GetCurrentThreadId();
42 /* %jp{割り込み禁止に見立てるセマフォの作成} */
43 _kernel_win32_hSemDisInt = CreateSemaphore(NULL, 0, 1, NULL);
48 void _kernel_dis_int(void)
50 /* 割込みコンテキストから呼ばれたなら何もしない */
51 if ( _kernel_win32_blIntCtx )
56 /* 既に割込み禁止で無ければセマフォを取る */
57 if ( !_kernel_win32_blDisInt )
59 WaitForSingleObject(_kernel_win32_hSemDisInt, INFINITE);
60 _kernel_win32_blDisInt = TRUE;
66 void _kernel_ena_int(void)
68 /* 割込みコンテキストから呼ばれたなら何もしない */
69 if ( _kernel_win32_blIntCtx )
74 /* 既に割込み禁止ならセマフォを返す */
75 if ( _kernel_win32_blDisInt )
77 _kernel_win32_blDisInt = FALSE;
78 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
84 /** %jp{実行コンテキストの作成} */
86 _KERNEL_T_CTXCB *pk_ctxcb, /* コンテキストを作成するアドレス */
87 FP entry, /* コンテキストの実行開始番地 */
88 VP_INT exinf1, /* コンテキストの実行時パラメータ1 */
89 VP_INT exinf2) /* コンテキストの実行時パラメータ2 */
91 pk_ctxcb->blIntSuspend = FALSE;
94 pk_ctxcb->entry = entry;
95 pk_ctxcb->exinf1 = exinf1;
96 pk_ctxcb->exinf2 = exinf2;
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);
105 /** %jp{スレッドの開始関数} */
106 DWORD WINAPI _kernel_ctx_ent(LPVOID param)
108 _KERNEL_T_CTXCB *pk_ctxcb;
110 /* %jp{コンテキスト情報取得} */
111 pk_ctxcb = (_KERNEL_T_CTXCB *)param;
114 WaitForSingleObject(pk_ctxcb->hEvent, INFINITE);
116 /* %jp{リスタート用setjmp} */
117 setjmp(pk_ctxcb->jmpenv);
120 pk_ctxcb->entry(pk_ctxcb->exinf1, pk_ctxcb->exinf2);
126 /** %jp{実行コンテキストの削除} */
127 void _kernel_del_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
130 TerminateThread(pk_ctxcb->hThread, 0);
131 CloseHandle(pk_ctxcb->hThread);
132 CloseHandle(pk_ctxcb->hEvent);
136 /** %jp{実行コンテキストのリスタート} */
137 void _kernel_rst_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
139 longjmp(pk_ctxcb->jmpenv, 0);
143 /** %jp{実行コンテキストの切替} */
144 void _kernel_swi_ctx(
145 _KERNEL_T_CTXCB *ctxcb_now, /* 現在のコンテキストの保存先 */
146 _KERNEL_T_CTXCB *ctxcb_nxt) /* 新たに実行するコンテキスト */
148 /* %jp{切り替え無しならそのまま} */
149 if ( ctxcb_now == ctxcb_nxt )
155 if ( _kernel_win32_blIntCtx )
158 _kernel_win32_blIntDsp = TRUE;
159 _kernel_win32_intctxcb = ctxcb_nxt;
164 _kernel_run_ctx(ctxcb_nxt);
167 WaitForSingleObject(ctxcb_now->hEvent, INFINITE);
173 void _kernel_wai_int(void)
179 /** %jp{コンテキストの開始} */
180 void _kernel_sta_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
183 _kernel_run_ctx(pk_ctxcb);
185 if ( GetCurrentThreadId() == _kernel_win32_hPrimaryThreadId )
188 MessageBox(NULL, "Press OK, Exit a process", "Hyper Operationg System V4 Advance for Win32", MB_OK);
196 /** %jp{スレッドの実行開始} */
197 void _kernel_run_ctx(_KERNEL_T_CTXCB *pk_ctxcb)
199 /* %jp{実行中コンテキストの登録} */
200 _kernel_win32_runctxcb = pk_ctxcb;
202 /* %jp{割り込みから中断されていた場合} */
203 if ( pk_ctxcb->blIntSuspend )
205 /* %jp{割り込み用セマフォを返す} */
206 _kernel_win32_blDisInt = FALSE;
207 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
210 pk_ctxcb->blIntSuspend = FALSE;
211 ResumeThread(pk_ctxcb->hThread);
216 SetEvent(pk_ctxcb->hEvent);
223 void vsig_int(int inhno)
225 EnterCriticalSection(&_kernel_win32_CriticalSection);
227 /* %jp{割り込み用セマフォを取る} */
228 WaitForSingleObject(_kernel_win32_hSemDisInt, INFINITE);
229 _kernel_win32_blDisInt = TRUE;
231 /* %jp{現在実行中のスレッドを止める} */
232 SuspendThread(_kernel_win32_runctxcb->hThread);
235 _kernel_win32_blIntCtx = TRUE;
236 _kernel_win32_blIntDsp = FALSE;
240 _kernel_exe_inh(inhno);
244 _kernel_win32_blIntCtx = FALSE;
247 /* %jp{遅延ディスパッチ発生なら} */
248 if ( _kernel_win32_blIntDsp )
250 /* 元のスレッドをサスペンドのままマーク */
251 _kernel_win32_runctxcb->blIntSuspend = TRUE;
254 _kernel_run_ctx(_kernel_win32_intctxcb);
258 /* %jp{割り込み用セマフォを返す} */
259 _kernel_win32_blDisInt = FALSE;
260 ReleaseSemaphore(_kernel_win32_hSemDisInt, 1, NULL);
262 /* %jp{現在実行中のスレッドを再開} */
263 ResumeThread(_kernel_win32_runctxcb->hThread);
266 LeaveCriticalSection(&_kernel_win32_CriticalSection);