Skip to content
Newer
Older
100644 686 lines (580 sloc) 14.7 KB
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
1 /* -*-c-*- */
2 /**********************************************************************
3
c334a09 @ko1 * common.mk, *.ci: renamed to *.c.
ko1 authored Dec 20, 2007
4 thread_win32.c -
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
5
6 $Author$
7
d907cbc @ko1 * blockinlining.c, compile.c, compile.h, debug.c, debug.h,
ko1 authored Nov 13, 2007
8 Copyright (C) 2004-2007 Koichi Sasada
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
9
10 **********************************************************************/
11
12 #ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
13
14 #include <process.h>
15
16 #define WIN32_WAIT_TIMEOUT 10 /* 10 ms */
17 #undef Sleep
18
19 #define native_thread_yield() Sleep(0)
ae317b5 @ko1 * yarvcore.h, thread.c: fix to use pthread on cygwin.
ko1 authored Feb 8, 2007
20 #define remove_signal_thread_list(th)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
21
6fc746d @nobu * thread.c (is_ruby_native_thread): check properly. [ruby-dev:31166]
nobu authored Aug 18, 2007
22 static volatile DWORD ruby_native_thread_key = TLS_OUT_OF_INDEXES;
23
5f131b6 @nobu * thread_win32.c, include/ruby/win32.h: add prototypes.
nobu authored Apr 29, 2011
24 static int w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th);
25 static int native_mutex_lock(rb_thread_lock_t *lock);
26 static int native_mutex_unlock(rb_thread_lock_t *lock);
27
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
28 static void
29 w32_error(const char *func)
30 {
31 LPVOID lpMsgBuf;
32 DWORD err = GetLastError();
33 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
34 FORMAT_MESSAGE_FROM_SYSTEM |
35 FORMAT_MESSAGE_IGNORE_INSERTS,
36 NULL,
37 err,
38 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
39 (LPTSTR) & lpMsgBuf, 0, NULL) == 0)
40 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
41 FORMAT_MESSAGE_FROM_SYSTEM |
42 FORMAT_MESSAGE_IGNORE_INSERTS,
43 NULL,
44 err,
45 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
46 (LPTSTR) & lpMsgBuf, 0, NULL);
47 rb_bug("%s: %s", func, (char*)lpMsgBuf);
48 }
49
50 static int
51 w32_mutex_lock(HANDLE lock)
52 {
53 DWORD result;
54 while (1) {
55 thread_debug("native_mutex_lock: %p\n", lock);
56 result = w32_wait_events(&lock, 1, INFINITE, 0);
57 switch (result) {
58 case WAIT_OBJECT_0:
59 /* get mutex object */
60 thread_debug("acquire mutex: %p\n", lock);
61 return 0;
62 case WAIT_OBJECT_0 + 1:
63 /* interrupt */
64 errno = EINTR;
65 thread_debug("acquire mutex interrupted: %p\n", lock);
66 return 0;
67 case WAIT_TIMEOUT:
68 thread_debug("timeout mutex: %p\n", lock);
69 break;
70 case WAIT_ABANDONED:
71 rb_bug("win32_mutex_lock: WAIT_ABANDONED");
72 break;
73 default:
f0445d1 @nobu * thread_win32.c (gvl_release, gvl_init): suppress warnings.
nobu authored Nov 28, 2010
74 rb_bug("win32_mutex_lock: unknown result (%ld)", result);
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
75 break;
76 }
77 }
78 return 0;
79 }
80
81 static HANDLE
82 w32_mutex_create(void)
83 {
84 HANDLE lock = CreateMutex(NULL, FALSE, NULL);
85 if (lock == NULL) {
86 w32_error("native_mutex_initialize");
87 }
88 return lock;
89 }
90
91 #define GVL_DEBUG 0
92
93 static void
94 gvl_acquire(rb_vm_t *vm, rb_thread_t *th)
95 {
96 w32_mutex_lock(vm->gvl.lock);
97 if (GVL_DEBUG) fprintf(stderr, "gvl acquire (%p): acquire\n", th);
98 }
99
100 static void
101 gvl_release(rb_vm_t *vm)
102 {
103 ReleaseMutex(vm->gvl.lock);
104 }
105
106 static void
107 gvl_atfork(rb_vm_t *vm)
108 {
109 rb_bug("gvl_atfork() is called on win32");
110 }
111
112 static void
113 gvl_init(rb_vm_t *vm)
114 {
115 if (GVL_DEBUG) fprintf(stderr, "gvl init\n");
116 vm->gvl.lock = w32_mutex_create();
117 }
118
119 static void
120 gvl_destroy(rb_vm_t *vm)
121 {
122 if (GVL_DEBUG) fprintf(stderr, "gvl destroy\n");
123 CloseHandle(vm->gvl.lock);
124 }
125
6fc746d @nobu * thread.c (is_ruby_native_thread): check properly. [ruby-dev:31166]
nobu authored Aug 18, 2007
126 static rb_thread_t *
127 ruby_thread_from_native(void)
128 {
129 return TlsGetValue(ruby_native_thread_key);
130 }
131
132 static int
133 ruby_thread_set_native(rb_thread_t *th)
134 {
135 return TlsSetValue(ruby_native_thread_key, th);
136 }
137
f40d2c9 @akr * vm.c (Init_BareVM): call Init_native_thread here.
akr authored Jun 5, 2010
138 void
6fc746d @nobu * thread.c (is_ruby_native_thread): check properly. [ruby-dev:31166]
nobu authored Aug 18, 2007
139 Init_native_thread(void)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
140 {
9c57438 @ko1 * blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
ko1 authored Feb 8, 2007
141 rb_thread_t *th = GET_THREAD();
6fc746d @nobu * thread.c (is_ruby_native_thread): check properly. [ruby-dev:31166]
nobu authored Aug 18, 2007
142
143 ruby_native_thread_key = TlsAlloc();
b451955 @unak * thread_win32.c (Init_native_thread): need to call
unak authored Dec 22, 2008
144 ruby_thread_set_native(th);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
145 DuplicateHandle(GetCurrentProcess(),
146 GetCurrentThread(),
147 GetCurrentProcess(),
148 &th->thread_id, 0, FALSE, DUPLICATE_SAME_ACCESS);
149
150 th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
151
152 thread_debug("initial thread (th: %p, thid: %p, event: %p)\n",
153 th, GET_THREAD()->thread_id,
154 th->native_thread_data.interrupt_event);
155 }
156
157 static void
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
158 w32_set_event(HANDLE handle)
159 {
160 if (SetEvent(handle) == 0) {
5bc85d6 @unak * thread_win32.c (w32_error): should report the function.
unak authored Dec 30, 2009
161 w32_error("w32_set_event");
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
162 }
163 }
164
165 static void
166 w32_reset_event(HANDLE handle)
167 {
168 if (ResetEvent(handle) == 0) {
5bc85d6 @unak * thread_win32.c (w32_error): should report the function.
unak authored Dec 30, 2009
169 w32_error("w32_reset_event");
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
170 }
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
171 }
172
173 static int
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
174 w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
175 {
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
176 HANDLE *targets = events;
00f60d0 @unak * thread_win32.ci (w32_wait_events): check whether interrupt_event is
unak authored Apr 10, 2007
177 HANDLE intr;
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
178 DWORD ret;
179
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
180 thread_debug(" w32_wait_events events:%p, count:%d, timeout:%ld, th:%p\n",
181 events, count, timeout, th);
00f60d0 @unak * thread_win32.ci (w32_wait_events): check whether interrupt_event is
unak authored Apr 10, 2007
182 if (th && (intr = th->native_thread_data.interrupt_event)) {
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
183 gvl_acquire(th->vm, th);
bd21118 @wanabe * thread_win32.c (w32_wait_events): get GVL before handle interrupt
wanabe authored May 5, 2010
184 if (intr == th->native_thread_data.interrupt_event) {
185 w32_reset_event(intr);
186 if (RUBY_VM_INTERRUPTED(th)) {
187 w32_set_event(intr);
188 }
189
190 targets = ALLOCA_N(HANDLE, count + 1);
191 memcpy(targets, events, sizeof(HANDLE) * count);
192
193 targets[count++] = intr;
194 thread_debug(" * handle: %p (count: %d, intr)\n", intr, count);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
195 }
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
196 gvl_release(th->vm);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
197 }
198
199 thread_debug(" WaitForMultipleObjects start (count: %d)\n", count);
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
200 ret = WaitForMultipleObjects(count, targets, FALSE, timeout);
87e4ad0 @nobu * io.c, signal.c, thread.c, thread_win32.c, include/ruby/intern.h:
nobu authored Apr 26, 2008
201 thread_debug(" WaitForMultipleObjects end (ret: %lu)\n", ret);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
202
060f18c @wanabe * thread_win32.c (w32_wait_events, w32_close_handle): suppress warnings.
wanabe authored Sep 23, 2010
203 if (ret == (DWORD)(WAIT_OBJECT_0 + count - 1) && th) {
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
204 errno = EINTR;
205 }
060f18c @wanabe * thread_win32.c (w32_wait_events, w32_close_handle): suppress warnings.
wanabe authored Sep 23, 2010
206 if (ret == WAIT_FAILED && THREAD_DEBUG) {
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
207 int i;
208 DWORD dmy;
209 for (i = 0; i < count; i++) {
210 thread_debug(" * error handle %d - %s\n", i,
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
211 GetHandleInformation(targets[i], &dmy) ? "OK" : "NG");
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
212 }
213 }
214 return ret;
215 }
216
3453b2b @ko1 * gc.h, vm_core.h: decl of rb_gc_save_machine_context()
ko1 authored Nov 20, 2007
217 static void ubf_handle(void *ptr);
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
218 #define ubf_select ubf_handle
219
220 int
c034fce @nobu * process.c (rb_waitpid_blocking, rb_waitpid): use UBF feature.
nobu authored Feb 24, 2007
221 rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
222 {
223 return w32_wait_events(events, num, timeout, GET_THREAD());
224 }
225
226 int
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
227 rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
228 {
229 int ret;
230
3453b2b @ko1 * gc.h, vm_core.h: decl of rb_gc_save_machine_context()
ko1 authored Nov 20, 2007
231 BLOCKING_REGION(ret = rb_w32_wait_events_blocking(events, num, timeout),
4b645dc @mame * thread.c, thread_win32.c, vm_core.h: try to remove false positive of
mame authored Jun 19, 2008
232 ubf_handle, GET_THREAD());
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
233 return ret;
234 }
235
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
236 static void
237 w32_close_handle(HANDLE handle)
238 {
239 if (CloseHandle(handle) == 0) {
5bc85d6 @unak * thread_win32.c (w32_error): should report the function.
unak authored Dec 30, 2009
240 w32_error("w32_close_handle");
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
241 }
242 }
243
244 static void
245 w32_resume_thread(HANDLE handle)
246 {
060f18c @wanabe * thread_win32.c (w32_wait_events, w32_close_handle): suppress warnings.
wanabe authored Sep 23, 2010
247 if (ResumeThread(handle) == (DWORD)-1) {
5bc85d6 @unak * thread_win32.c (w32_error): should report the function.
unak authored Dec 30, 2009
248 w32_error("w32_resume_thread");
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
249 }
250 }
251
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
252 #ifdef _MSC_VER
253 #define HAVE__BEGINTHREADEX 1
254 #else
255 #undef HAVE__BEGINTHREADEX
256 #endif
257
258 #ifdef HAVE__BEGINTHREADEX
259 #define start_thread (HANDLE)_beginthreadex
9e0f3e0 @nobu * thread_win32.c (thread_errno): CreateThread does not set errno.
nobu authored Nov 12, 2009
260 #define thread_errno errno
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
261 typedef unsigned long (_stdcall *w32_thread_start_func)(void*);
262 #else
263 #define start_thread CreateThread
9e0f3e0 @nobu * thread_win32.c (thread_errno): CreateThread does not set errno.
nobu authored Nov 12, 2009
264 #define thread_errno rb_w32_map_errno(GetLastError())
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
265 typedef LPTHREAD_START_ROUTINE w32_thread_start_func;
266 #endif
267
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
268 static HANDLE
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
269 w32_create_thread(DWORD stack_size, w32_thread_start_func func, void *val)
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
270 {
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
271 return start_thread(0, stack_size, func, val, CREATE_SUSPENDED, 0);
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
272 }
273
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
274 int
275 rb_w32_sleep(unsigned long msec)
276 {
277 return w32_wait_events(0, 0, msec, GET_THREAD());
278 }
279
280 int WINAPI
281 rb_w32_Sleep(unsigned long msec)
282 {
283 int ret;
284
3453b2b @ko1 * gc.h, vm_core.h: decl of rb_gc_save_machine_context()
ko1 authored Nov 20, 2007
285 BLOCKING_REGION(ret = rb_w32_sleep(msec),
4b645dc @mame * thread.c, thread_win32.c, vm_core.h: try to remove false positive of
mame authored Jun 19, 2008
286 ubf_handle, GET_THREAD());
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
287 return ret;
288 }
ae317b5 @ko1 * yarvcore.h, thread.c: fix to use pthread on cygwin.
ko1 authored Feb 8, 2007
289
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
290 static void
47e3f4e @nobu * thread.c (thread_start_func_2): wake up joining threads.
nobu authored Jul 16, 2008
291 native_sleep(rb_thread_t *th, struct timeval *tv)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
292 {
a146829 @nobu * thread.c (sleep_forever): wait until timed out. [ruby-core:17270]
nobu authored Jul 9, 2008
293 DWORD msec;
4b02286 @unak * thread_win32.c (native_sleep): fixed previous commit.
unak authored Jun 12, 2008
294
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
295 if (tv) {
296 msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
297 }
298 else {
299 msec = INFINITE;
300 }
301
302 GVL_UNLOCK_BEGIN();
303 {
a146829 @nobu * thread.c (sleep_forever): wait until timed out. [ruby-core:17270]
nobu authored Jul 9, 2008
304 DWORD ret;
305
8724448 @unak * thread_win32.c (native_sleep): must block reentrance when accessing
unak authored Jun 21, 2008
306 native_mutex_lock(&th->interrupt_lock);
1b63d7b @nobu * vm_core.h (struct rb_unblock_callback), thread.c
nobu authored May 30, 2008
307 th->unblock.func = ubf_handle;
308 th->unblock.arg = th;
8724448 @unak * thread_win32.c (native_sleep): must block reentrance when accessing
unak authored Jun 21, 2008
309 native_mutex_unlock(&th->interrupt_lock);
5f0b8af @ko1 * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(),
ko1 authored Dec 25, 2007
310
311 if (RUBY_VM_INTERRUPTED(th)) {
312 /* interrupted. return immediate */
313 }
314 else {
87e4ad0 @nobu * io.c, signal.c, thread.c, thread_win32.c, include/ruby/intern.h:
nobu authored Apr 26, 2008
315 thread_debug("native_sleep start (%lu)\n", msec);
5f0b8af @ko1 * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(),
ko1 authored Dec 25, 2007
316 ret = w32_wait_events(0, 0, msec, th);
87e4ad0 @nobu * io.c, signal.c, thread.c, thread_win32.c, include/ruby/intern.h:
nobu authored Apr 26, 2008
317 thread_debug("native_sleep done (%lu)\n", ret);
5f0b8af @ko1 * vm_core.h, thread.c, cont.c: add RUBY_VM_SET_INTERRUPT(),
ko1 authored Dec 25, 2007
318 }
319
8724448 @unak * thread_win32.c (native_sleep): must block reentrance when accessing
unak authored Jun 21, 2008
320 native_mutex_lock(&th->interrupt_lock);
1b63d7b @nobu * vm_core.h (struct rb_unblock_callback), thread.c
nobu authored May 30, 2008
321 th->unblock.func = 0;
322 th->unblock.arg = 0;
8724448 @unak * thread_win32.c (native_sleep): must block reentrance when accessing
unak authored Jun 21, 2008
323 native_mutex_unlock(&th->interrupt_lock);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
324 }
325 GVL_UNLOCK_END();
326 }
327
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
328 static int
8ee7d07 @ko1 * blockinlining.c, compile.c, compile.h, error.c, eval.c,
ko1 authored Feb 6, 2007
329 native_mutex_lock(rb_thread_lock_t *lock)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
330 {
331 #if USE_WIN32_MUTEX
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
332 w32_mutex_lock(*lock);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
333 #else
334 EnterCriticalSection(lock);
335 return 0;
336 #endif
337 }
338
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
339 static int
8ee7d07 @ko1 * blockinlining.c, compile.c, compile.h, error.c, eval.c,
ko1 authored Feb 6, 2007
340 native_mutex_unlock(rb_thread_lock_t *lock)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
341 {
342 #if USE_WIN32_MUTEX
343 thread_debug("release mutex: %p\n", *lock);
344 return ReleaseMutex(*lock);
345 #else
346 LeaveCriticalSection(lock);
347 return 0;
348 #endif
349 }
350
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
351 static int
8ee7d07 @ko1 * blockinlining.c, compile.c, compile.h, error.c, eval.c,
ko1 authored Feb 6, 2007
352 native_mutex_trylock(rb_thread_lock_t *lock)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
353 {
35eb542 @nobu * thread_win32.ci: fixed typo.
nobu authored Jun 5, 2007
354 #if USE_WIN32_MUTEX
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
355 int result;
356 thread_debug("native_mutex_trylock: %p\n", *lock);
bb022be @unak * thread.c (rb_thread_polling): check interrupts here.
unak authored Feb 23, 2007
357 result = w32_wait_events(&*lock, 1, 1, 0);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
358 thread_debug("native_mutex_trylock result: %d\n", result);
359 switch (result) {
99d65b1 @nobu * compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
nobu authored Jun 5, 2007
360 case WAIT_OBJECT_0:
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
361 return 0;
99d65b1 @nobu * compile.c, dir.c, eval.c, eval_jump.h, eval_method.h, numeric.c,
nobu authored Jun 5, 2007
362 case WAIT_TIMEOUT:
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
363 return EBUSY;
364 }
365 return EINVAL;
366 #else
367 return TryEnterCriticalSection(lock) == 0;
368 #endif
369 }
370
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
371 static void
8ee7d07 @ko1 * blockinlining.c, compile.c, compile.h, error.c, eval.c,
ko1 authored Feb 6, 2007
372 native_mutex_initialize(rb_thread_lock_t *lock)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
373 {
35eb542 @nobu * thread_win32.ci: fixed typo.
nobu authored Jun 5, 2007
374 #if USE_WIN32_MUTEX
450463d @ko1 * thread.c, vm_core.h: make gvl_acquire/release/init/destruct
ko1 authored Nov 27, 2010
375 *lock = w32_mutex_create();
205f310 @nobu * call_cfunc.ci, compile.c, compile.h, debug.h, eval.c,
nobu authored Feb 2, 2007
376 /* thread_debug("initialize mutex: %p\n", *lock); */
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
377 #else
378 InitializeCriticalSection(lock);
379 #endif
380 }
381
a000201 @nobu * thread.c (rb_thread_atfork_internal): reinitialize global lock
nobu authored Nov 18, 2009
382 #define native_mutex_reinitialize_atfork(lock) (void)(lock)
383
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
384 static void
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
385 native_mutex_destroy(rb_thread_lock_t *lock)
386 {
35eb542 @nobu * thread_win32.ci: fixed typo.
nobu authored Jun 5, 2007
387 #if USE_WIN32_MUTEX
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
388 w32_close_handle(lock);
389 #else
390 DeleteCriticalSection(lock);
391 #endif
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
392 }
393
a73ba1d @unak * thread_win32.[ch] (cond_every_entry, rb_thread_cond_struct): reverted
unak authored Jul 28, 2008
394 struct cond_event_entry {
395 struct cond_event_entry* next;
396 HANDLE event;
397 };
398
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
399 static void
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
400 native_cond_signal(rb_thread_cond_t *cond)
401 {
402 /* cond is guarded by mutex */
403 struct cond_event_entry *e = cond->next;
404
405 if (e) {
406 cond->next = e->next;
407 SetEvent(e->event);
408 }
409 else {
410 rb_bug("native_cond_signal: no pending threads");
411 }
412 }
413
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
414 static void
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
415 native_cond_broadcast(rb_thread_cond_t *cond)
416 {
417 /* cond is guarded by mutex */
418 struct cond_event_entry *e = cond->next;
419 cond->next = 0;
420
421 while (e) {
422 SetEvent(e->event);
423 e = e->next;
424 }
425 }
426
b4c5fad @kosaki * thread_win32.c (native_cond_timedwait): New. r31373 caused
kosaki authored Apr 29, 2011
427
428 static int
429 __cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, unsigned long msec)
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
430 {
431 DWORD r;
432 struct cond_event_entry entry;
433
434 entry.next = 0;
435 entry.event = CreateEvent(0, FALSE, FALSE, 0);
436
437 /* cond is guarded by mutex */
438 if (cond->next) {
439 cond->last->next = &entry;
440 cond->last = &entry;
441 }
442 else {
443 cond->next = &entry;
444 cond->last = &entry;
445 }
446
447 native_mutex_unlock(mutex);
448 {
b4c5fad @kosaki * thread_win32.c (native_cond_timedwait): New. r31373 caused
kosaki authored Apr 29, 2011
449 r = WaitForSingleObject(entry.event, msec);
450 if ((r != WAIT_OBJECT_0) && (r != WAIT_TIMEOUT)) {
87e4ad0 @nobu * io.c, signal.c, thread.c, thread_win32.c, include/ruby/intern.h:
nobu authored Apr 26, 2008
451 rb_bug("native_cond_wait: WaitForSingleObject returns %lu", r);
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
452 }
453 }
454 native_mutex_lock(mutex);
455
456 w32_close_handle(entry.event);
b4c5fad @kosaki * thread_win32.c (native_cond_timedwait): New. r31373 caused
kosaki authored Apr 29, 2011
457 return (r == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
458 }
459
460 static int
461 native_cond_wait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex)
462 {
463 return __cond_timedwait(cond, mutex, INFINITE);
464 }
465
466 static unsigned long
467 abs_timespec_to_timeout_ms(struct timespec *ts)
468 {
469 struct timeval tv;
470 struct timeval now;
471
472 gettimeofday(&now, NULL);
473 tv.tv_sec = ts->tv_sec;
474 tv.tv_usec = ts->tv_nsec;
475
476 if (!rb_w32_time_subtract(&tv, &now))
477 return 0;
478
479 return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
480 }
481
482 static int
483 native_cond_timedwait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex, struct timespec *ts)
484 {
485 unsigned long timeout_ms;
486
487 timeout_ms = abs_timespec_to_timeout_ms(ts);
488 if (!timeout_ms)
489 return ETIMEDOUT;
490
491 return __cond_timedwait(cond, mutex, timeout_ms);
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
492 }
493
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
494 static void
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
495 native_cond_initialize(rb_thread_cond_t *cond)
496 {
497 cond->next = 0;
498 cond->last = 0;
499 }
500
42f0b52 @ko1 * thread_pthread.c, thread_pthread.h, thread_win32.c,
ko1 authored Dec 25, 2007
501 static void
6244e50 @ko1 * thread.c: fix Mutex to be interruptable lock.
ko1 authored Aug 27, 2007
502 native_cond_destroy(rb_thread_cond_t *cond)
503 {
504 /* */
505 }
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
506
fc3c60f @nobu * gc.h (STACK_UPPER): moved from gc.c
nobu authored Jun 14, 2008
507 void
c7853b4 @nobu * eval.c (ruby_cleanup): the order of local variables on stack is
nobu authored Apr 19, 2009
508 ruby_init_stack(volatile VALUE *addr)
fc3c60f @nobu * gc.h (STACK_UPPER): moved from gc.c
nobu authored Jun 14, 2008
509 {
510 }
511
512 #define CHECK_ERR(expr) \
513 {if (!(expr)) {rb_bug("err: %lu - %s", GetLastError(), #expr);}}
514
515 static void
516 native_thread_init_stack(rb_thread_t *th)
517 {
518 MEMORY_BASIC_INFORMATION mi;
519 char *base, *end;
520 DWORD size, space;
521
522 CHECK_ERR(VirtualQuery(&mi, &mi, sizeof(mi)));
523 base = mi.AllocationBase;
524 end = mi.BaseAddress;
525 end += mi.RegionSize;
526 size = end - base;
527 space = size / 5;
528 if (space > 1024*1024) space = 1024*1024;
529 th->machine_stack_start = (VALUE *)end - 1;
530 th->machine_stack_maxsize = size - space;
531 }
532
dfc07e8 @unak * thread_win32.c (InterlockedExchangePointer): old SDK support.
unak authored Jan 4, 2010
533 #ifndef InterlockedExchangePointer
534 #define InterlockedExchangePointer(t, v) \
535 (void *)InterlockedExchange((long *)(t), (long)(v))
536 #endif
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
537 static void
538 native_thread_destroy(rb_thread_t *th)
539 {
9f90682 @unak * thread_win32.c (native_thread_destroy): decreased the probability of
unak authored Dec 30, 2009
540 HANDLE intr = InterlockedExchangePointer(&th->native_thread_data.interrupt_event, 0);
00f60d0 @unak * thread_win32.ci (w32_wait_events): check whether interrupt_event is
unak authored Apr 10, 2007
541 thread_debug("close handle - intr: %p, thid: %p\n", intr, th->thread_id);
542 w32_close_handle(intr);
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
543 }
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
544
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
545 static unsigned long _stdcall
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
546 thread_start_func_1(void *th_ptr)
547 {
9c57438 @ko1 * blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
ko1 authored Feb 8, 2007
548 rb_thread_t *th = th_ptr;
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
549 volatile HANDLE thread_id = th->thread_id;
550
fc3c60f @nobu * gc.h (STACK_UPPER): moved from gc.c
nobu authored Jun 14, 2008
551 native_thread_init_stack(th);
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
552 th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
553
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
554 /* run */
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
555 thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
556 th->thread_id, th->native_thread_data.interrupt_event);
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
557
df6ea23 @nobu * thread_win32.c (thread_start_func_1): use already gotten stack info.
nobu authored Nov 7, 2008
558 thread_start_func_2(th, th->machine_stack_start, rb_ia64_bsp());
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
559
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
560 w32_close_handle(thread_id);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
561 thread_debug("thread deleted (th: %p)\n", th);
562 return 0;
563 }
564
565 static int
9c57438 @ko1 * blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
ko1 authored Feb 8, 2007
566 native_thread_create(rb_thread_t *th)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
567 {
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
568 size_t stack_size = 4 * 1024; /* 4KB */
569 th->thread_id = w32_create_thread(stack_size, thread_start_func_1, th);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
570
a902624 @ko1 * thread.c, thread_pthread.ci, thread_win32.ci (thread_start_func_1):
ko1 authored Feb 8, 2007
571 if ((th->thread_id) == 0) {
9e0f3e0 @nobu * thread_win32.c (thread_errno): CreateThread does not set errno.
nobu authored Nov 12, 2009
572 return thread_errno;
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
573 }
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
574
575 w32_resume_thread(th->thread_id);
576
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
577 if (THREAD_DEBUG) {
578 Sleep(0);
cea3919 @nobu * configure.in (RUBY_CHECK_PRINTF_PREFIX): check for printf format
nobu authored Oct 12, 2010
579 thread_debug("create: (th: %p, thid: %p, intr: %p), stack size: %"PRIdSIZE"\n",
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
580 th, th->thread_id,
581 th->native_thread_data.interrupt_event, stack_size);
582 }
583 return 0;
584 }
585
586 static void
84f8da1 @ko1 * thread.c (rb_thread_stop_timer_thread(), rb_thread_reset_timer_thre…
ko1 authored Jan 7, 2007
587 native_thread_join(HANDLE th)
588 {
6198f53 @unak * thread_win32.c (native_thread_join): need to wait thread, of course.
unak authored Aug 2, 2010
589 w32_wait_events(&th, 1, INFINITE, 0);
84f8da1 @ko1 * thread.c (rb_thread_stop_timer_thread(), rb_thread_reset_timer_thre…
ko1 authored Jan 7, 2007
590 }
591
16612b3 @ko1 * thread.c, vm_core.h: add manual priority support
ko1 authored Aug 13, 2008
592 #if USE_NATIVE_THREAD_PRIORITY
593
84f8da1 @ko1 * thread.c (rb_thread_stop_timer_thread(), rb_thread_reset_timer_thre…
ko1 authored Jan 7, 2007
594 static void
9c57438 @ko1 * blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
ko1 authored Feb 8, 2007
595 native_thread_apply_priority(rb_thread_t *th)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
596 {
597 int priority = th->priority;
598 if (th->priority > 0) {
599 priority = THREAD_PRIORITY_ABOVE_NORMAL;
600 }
601 else if (th->priority < 0) {
602 priority = THREAD_PRIORITY_BELOW_NORMAL;
603 }
604 else {
605 priority = THREAD_PRIORITY_NORMAL;
606 }
607
608 SetThreadPriority(th->thread_id, priority);
609 }
610
16612b3 @ko1 * thread.c, vm_core.h: add manual priority support
ko1 authored Aug 13, 2008
611 #endif /* USE_NATIVE_THREAD_PRIORITY */
612
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
613 static void
3453b2b @ko1 * gc.h, vm_core.h: decl of rb_gc_save_machine_context()
ko1 authored Nov 20, 2007
614 ubf_handle(void *ptr)
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
615 {
3453b2b @ko1 * gc.h, vm_core.h: decl of rb_gc_save_machine_context()
ko1 authored Nov 20, 2007
616 rb_thread_t *th = (rb_thread_t *)ptr;
ae317b5 @ko1 * yarvcore.h, thread.c: fix to use pthread on cygwin.
ko1 authored Feb 8, 2007
617 thread_debug("ubf_handle: %p\n", th);
25498d2 @unak * thread_win32.c (ubf_handle): cancel blocking IO if it can (only
unak authored Jul 15, 2008
618
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
619 w32_set_event(th->native_thread_data.interrupt_event);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
620 }
621
84f8da1 @ko1 * thread.c (rb_thread_stop_timer_thread(), rb_thread_reset_timer_thre…
ko1 authored Jan 7, 2007
622 static HANDLE timer_thread_id = 0;
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
623 static HANDLE timer_thread_lock;
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
624
2840fa6 @nobu * common.mk: inverted rules order.
nobu authored Jul 21, 2007
625 static unsigned long _stdcall
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
626 timer_thread_func(void *dummy)
627 {
628 thread_debug("timer_thread\n");
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
629 while (WaitForSingleObject(timer_thread_lock, WIN32_WAIT_TIMEOUT) ==
630 WAIT_TIMEOUT) {
6bbbf98 @nobu * thread.c (thread_initialize): NUM2INT() returns int.
nobu authored Jul 5, 2008
631 timer_thread_function(dummy);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
632 }
633 thread_debug("timer killed\n");
634 return 0;
635 }
636
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
637 static void
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
638 rb_thread_create_timer_thread(void)
639 {
84f8da1 @ko1 * thread.c (rb_thread_stop_timer_thread(), rb_thread_reset_timer_thre…
ko1 authored Jan 7, 2007
640 if (timer_thread_id == 0) {
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
641 if (!timer_thread_lock) {
642 timer_thread_lock = CreateEvent(0, TRUE, FALSE, 0);
643 }
a534e39 @nobu * thread_{pthread,win32}.c (rb_thread_create_timer_thread): needs more
nobu authored Jul 9, 2008
644 timer_thread_id = w32_create_thread(1024 + (THREAD_DEBUG ? BUFSIZ : 0),
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
645 timer_thread_func, 0);
a5abb1c @ko1 * thread_win32.ci (w32_show_error_message): renamed to w32_error.
ko1 authored Feb 9, 2007
646 w32_resume_thread(timer_thread_id);
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
647 }
648 }
649
641f43d @nobu * thread_pthread.c (thread_timer): checks working flags again.
nobu authored Nov 8, 2008
650 static int
651 native_stop_timer_thread(void)
652 {
653 int stopped = --system_working <= 0;
654 if (stopped) {
9ee5e61 @unak * thread_{pthread,win32}.c (native_stop_timer_thread): join the thread
unak authored Nov 2, 2009
655 SetEvent(timer_thread_lock);
656 native_thread_join(timer_thread_id);
641f43d @nobu * thread_pthread.c (thread_timer): checks working flags again.
nobu authored Nov 8, 2008
657 CloseHandle(timer_thread_lock);
658 timer_thread_lock = 0;
659 }
660 return stopped;
661 }
5732566 @nobu * thread.c (rb_thread_stop_timer_thread): terminates timer thread
nobu authored Nov 6, 2008
662
9ee5e61 @unak * thread_{pthread,win32}.c (native_stop_timer_thread): join the thread
unak authored Nov 2, 2009
663 static void
664 native_reset_timer_thread(void)
665 {
666 if (timer_thread_id) {
667 CloseHandle(timer_thread_id);
668 timer_thread_id = 0;
669 }
670 }
671
767d708 @nobu * Makefile.in (ASFLAGS): needs INCFLAGS.
nobu authored Oct 26, 2010
672 #ifdef RUBY_ALLOCA_CHKSTK
673 void
674 ruby_alloca_chkstk(size_t len, void *sp)
675 {
676 if (ruby_stack_length(NULL) * sizeof(VALUE) >= len) {
677 rb_thread_t *th = GET_THREAD();
678 if (!rb_thread_raised_p(th, RAISED_STACKOVERFLOW)) {
679 rb_thread_raised_set(th, RAISED_STACKOVERFLOW);
680 rb_exc_raise(sysstack_error);
681 }
682 }
683 }
684 #endif
a3e1b1c @ko1 * Merge YARV
ko1 authored Dec 31, 2006
685 #endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
Something went wrong with that request. Please try again.