source: Include/Classes/System/Threading/Thread.ab@ 166

Last change on this file since 166 was 148, checked in by dai, 18 years ago

ThreadクラスをGCに対応させた。

File size: 7.3 KB
Line 
1'threading.sbp
2
3
4'--------------------------------------------------------------------
5' スレッドの優先順位
6'--------------------------------------------------------------------
7Enum ThreadPriority
8 Highest = 2
9 AboveNormal = 1
10 Normal = 0
11 BelowNormal = -1
12 Lowest = -2
13End Enum
14
15TypeDef PTHREAD_START_ROUTINE = *Function(args As VoidPtr) As DWord
16
17
18'--------------------------------------------------------------------
19' スレッド クラス
20'--------------------------------------------------------------------
21Class Thread
22 m_hThread As HANDLE
23 m_dwThreadId As DWord
24 m_Priority As ThreadPriority
25
26 m_fp As PTHREAD_START_ROUTINE
27 m_args As VoidPtr
28
29Public
30 Sub Thread()
31 m_hThread=0
32 m_dwThreadId=0
33 m_Priority=ThreadPriority.Normal
34
35 m_fp=0
36 End Sub
37 Sub Thread(fp As PTHREAD_START_ROUTINE, args As VoidPtr)
38 m_hThread=0
39 m_dwThreadId=0
40 m_Priority=ThreadPriority.Normal
41
42 m_fp=fp
43 m_args=args
44 End Sub
45
46 Sub Thread(ByRef obj As Thread)
47 m_hThread=obj.m_hThread
48 m_dwThreadId=obj.m_dwThreadId
49 m_Priority=obj.m_Priority
50 m_fp=obj.m_fp
51 m_args=obj.m_args
52 End Sub
53
54 Sub Thread(hThread As HANDLE,dwThreadId As DWord,dummy As Long)
55 m_hThread=hThread
56 m_dwThreadId=dwThreadId
57 End Sub
58
59 Sub ~Thread()
60 End Sub
61
62
63 Function Equals(ByRef obj_Thread As Thread) As BOOL
64 If m_dwThreadId=obj_Thread.m_dwThreadId Then
65 Return _System_TRUE
66 End If
67 Return _System_FALSE
68 End Function
69
70
71
72 '-----------------------
73 ' Public Properties
74 '-----------------------
75
76 'Priority Property
77 Sub Priority(value As ThreadPriority)
78 m_Priority=value
79 SetThreadPriority(m_hThread,value)
80 End Sub
81 Function Priority() As ThreadPriority
82 Return m_Priority
83 End Function
84
85 'ThreadId
86 Function ThreadId() As DWord
87 Return m_dwThreadId
88 End Function
89
90
91
92
93 Sub Start()
94 Dim ThreadId As DWord
95 m_hThread=_beginthreadex(NULL,0,AddressOf(_run),VarPtr(This),CREATE_SUSPENDED,m_dwThreadId)
96 SetThreadPriority(m_hThread,m_Priority)
97 Resume()
98 End Sub
99
100Private
101 Function Cdecl _run() As Long
102 '------------
103 ' 前処理
104 '------------
105
106 'GCにスレッド開始を通知
107 _System_pobj_AllThreads->BeginThread(VarPtr(This),_System_GetSp() As *LONG_PTR)
108
109
110 '------------
111 '実行
112 '------------
113 _run=Run()
114
115
116 '------------
117 '後処理
118 '------------
119
120 'GCにスレッド終了を通知
121 _System_pobj_AllThreads->EndThread(VarPtr(This))
122
123 '自身のスレッドハンドルを閉じる
124 CloseHandle(m_hThread)
125 m_hThread=0
126
127 End Function
128
129Public
130 Virtual Function Run() As Long
131 If m_fp Then
132 Run=m_fp(m_args)
133 End If
134 End Function
135
136 Sub Suspend()
137 If SuspendThread(m_hThread) = &HFFFFFFFF Then
138 debug
139 End If
140 End Sub
141 Sub Resume()
142 If ResumeThread(m_hThread) = &HFFFFFFFF Then
143 debug
144 End If
145 End Sub
146
147 Function __GetContext(ByRef Context As CONTEXT) As BOOL
148 Return GetThreadContext(m_hThread,Context)
149 End Function
150 Function __SetContext(ByRef Context As CONTEXT) As BOOL
151 Return SetThreadContext(m_hThread,Context)
152 End Function
153
154
155 Static Function CurrentThread() As Thread
156 Dim obj_Thread As Thread()
157 _System_pobj_AllThreads->CurrentThread(obj_Thread)
158 Return obj_Thread
159 End Function
160End Class
161
162
163'--------------------------------------------------------------------
164' すべてのスレッドの管理
165'--------------------------------------------------------------------
166' TODO: このクラスをシングルトンにする
167Class _System_CThreadCollection
168Public
169 ppobj_Thread As **Thread
170 pStackBase As **LONG_PTR
171 ThreadNum As Long
172
173 CriticalSection As CRITICAL_SECTION
174
175 Sub _System_CThreadCollection()
176 ppobj_Thread=GC_malloc(1)
177 pStackBase=HeapAlloc(_System_hProcessHeap,0,1)
178 ppException=HeapAlloc(_System_hProcessHeap,0,1)
179 ThreadNum=0
180
181 'クリティカルセッションを生成
182 InitializeCriticalSection(CriticalSection)
183 End Sub
184
185 Sub ~_System_CThreadCollection()
186 HeapFree(_System_hProcessHeap,0,pStackBase)
187 pStackBase=0
188
189 HeapFree(_System_hProcessHeap,0,ppException)
190 ppException = 0
191
192 ThreadNum=0
193
194 'クリティカルセッションを破棄
195 DeleteCriticalSection(CriticalSection)
196 End Sub
197
198 'スレッドを生成
199 Sub BeginThread(pThread As *Thread,NowSp As *LONG_PTR)
200 EnterCriticalSection(CriticalSection)
201
202 '例外処理管理用オブジェクトを生成
203 Dim pException As *ExceptionService
204 pException = New ExceptionService
205
206 Dim i As Long
207 For i=0 To ELM(ThreadNum)
208 If ppobj_Thread[i] = 0 Then
209 ppobj_Thread[i] = pThread
210 pStackBase[i] = NowSp
211 ppException[i] = pException
212 Exit For
213 End If
214 Next
215
216 If i = ThreadNum Then
217 ppobj_Thread=realloc(ppobj_Thread,(ThreadNum+1)*SizeOf(*Thread))
218 ppobj_Thread[ThreadNum]=pThread
219 pStackBase=HeapReAlloc(_System_hProcessHeap,0,pStackBase,(ThreadNum+1)*SizeOf(LONG_PTR))
220 pStackBase[ThreadNum]=NowSp
221 ppException=HeapReAlloc(_System_hProcessHeap,0,ppException,(ThreadNum+1)*SizeOf(*ExceptionService))
222 ppException[ThreadNum]=pException
223 ThreadNum++
224 End If
225 LeaveCriticalSection(CriticalSection)
226 End Sub
227
228 'スレッドを終了
229 Sub EndThread(pThread As *Thread)
230 EnterCriticalSection(CriticalSection)
231 Dim i As Long
232 For i=0 To ELM(ThreadNum)
233 If ppobj_Thread[i] = pThread Then
234 If i = 0 Then
235 Delete pThread
236 End If
237 ppobj_Thread[i]=0
238 pStackBase[i]=0
239 Exit For
240 End If
241 Next
242 LeaveCriticalSection(CriticalSection)
243 End Sub
244
245 ' すべてのスレッドを中断
246 Sub SuspendAllThread()
247 Dim i As Long
248 For i=0 To ELM(ThreadNum)
249 If ppobj_Thread[i] Then
250 ppobj_Thread[i]->Suspend()
251 End If
252 Next
253 End Sub
254
255 ' すべてのスレッドを再開
256 Sub ResumeAllThread()
257 Dim i As Long
258 For i=0 To ELM(ThreadNum)
259 If ppobj_Thread[i] Then
260 ppobj_Thread[i]->Resume()
261 End If
262 Next
263 End Sub
264
265 ' 自分以外のスレッドを中断
266 Sub SuspendAnotherThread()
267 Dim currentThread = Thread.CurrentThread()
268
269 Dim i As Long
270 For i=0 To ELM(ThreadNum)
271
272 If currentThread.Equals( ByVal ppobj_Thread[i] ) Then
273 Continue
274 End If
275
276 If ppobj_Thread[i] Then
277 ppobj_Thread[i]->Suspend()
278 End If
279 Next
280 End Sub
281
282 ' 自分以外のスレッドを再開
283 Sub ResumeAnotherThread()
284 Dim currentThread = Thread.CurrentThread()
285
286 Dim i As Long
287 For i=0 To ELM(ThreadNum)
288
289 If currentThread.Equals( ByVal ppobj_Thread[i] ) Then
290 Continue
291 End If
292
293 If ppobj_Thread[i] Then
294 ppobj_Thread[i]->Resume()
295 End If
296 Next
297 End Sub
298
299 'カレントスレッドを取得
300 Function CurrentThread(ByRef obj_Thread As Thread) As BOOL
301 Dim dwNowThreadId As DWord
302 dwNowThreadId=GetCurrentThreadId()
303
304 Dim i As Long
305 For i=0 To ELM(ThreadNum)
306 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
307 obj_Thread.Thread(ByVal ppobj_Thread[i])
308 Return 1
309 End If
310 Next
311
312 Return 0
313 End Function
314
315
316Private
317 '------------------------------------------
318 ' スレッド固有の例外処理制御
319 '------------------------------------------
320 ppException As **ExceptionService
321
322Public
323 Function GetCurrentException() As *ExceptionService
324 Dim dwNowThreadId As DWord
325 dwNowThreadId=GetCurrentThreadId()
326
327 Dim i As Long
328 For i=0 To ELM(ThreadNum)
329 If ppobj_Thread[i]->ThreadId=dwNowThreadId Then
330 Return ppException[i]
331 End If
332 Next
333
334 Return NULL
335 End Function
336End Class
337Dim _System_pobj_AllThreads As *_System_CThreadCollection
Note: See TracBrowser for help on using the repository browser.