Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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