From 6244e502cc12a7b8c5698740d3b5b355c1695e37 Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 27 Aug 2007 16:48:14 +0000 Subject: * thread.c: fix Mutex to be interruptable lock. * thread_win32.ci, thread_win32.h, thread_pthread.ci, thread_pthread.h: prepare native_cond_*() which are based on pthread_cond_*() spec. * prelude.rb: fix Mutex#synchronize method. * vm_core.h, include/ruby/intern.h: change unblock function interface (to pass some user data). * file.c, process.c: ditto. * benchmark/bm_vm2_mutex.rb: add a benchmark for mutex. * benchmark/bm_vm3_thread_mutex.rb: add a benchmark for mutex with contension. * benchmark/run.rb: fix to remove ENV['RUBYLIB'] for matzruby. * test/ruby/test_thread.rb: add a test. * common.mk: fix benchmark options. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13290 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- thread_win32.ci | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 4 deletions(-) (limited to 'thread_win32.ci') diff --git a/thread_win32.ci b/thread_win32.ci index 3bdb2e4276..46adc01028 100644 --- a/thread_win32.ci +++ b/thread_win32.ci @@ -122,7 +122,7 @@ w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th) return ret; } -static void ubf_handle(rb_thread_t *th); +static void ubf_handle(rb_thread_t *th, void *ptr); #define ubf_select ubf_handle int @@ -136,7 +136,7 @@ rb_w32_wait_events(HANDLE *events, int num, DWORD timeout) { int ret; - BLOCKING_REGION(ret = rb_w32_wait_events_blocking(events, num, timeout), ubf_handle); + BLOCKING_REGION(ret = rb_w32_wait_events_blocking(events, num, timeout), ubf_handle, 0); return ret; } @@ -187,7 +187,7 @@ rb_w32_Sleep(unsigned long msec) { int ret; - BLOCKING_REGION(ret = rb_w32_sleep(msec), ubf_handle); + BLOCKING_REGION(ret = rb_w32_sleep(msec), ubf_handle, 0); return ret; } @@ -309,6 +309,87 @@ native_mutex_destroy(rb_thread_lock_t *lock) #endif } +struct cond_event_entry { + struct cond_event_entry* next; + HANDLE event; +}; + +struct rb_thread_cond_struct { + struct cond_event_entry *next; + struct cond_event_entry *last; +}; + +void +native_cond_signal(rb_thread_cond_t *cond) +{ + /* cond is guarded by mutex */ + struct cond_event_entry *e = cond->next; + + if (e) { + cond->next = e->next; + SetEvent(e->event); + } + else { + rb_bug("native_cond_signal: no pending threads"); + } +} + +void +native_cond_broadcast(rb_thread_cond_t *cond) +{ + /* cond is guarded by mutex */ + struct cond_event_entry *e = cond->next; + cond->next = 0; + + while (e) { + SetEvent(e->event); + e = e->next; + } +} + +void +native_cond_wait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex) +{ + DWORD r; + struct cond_event_entry entry; + + entry.next = 0; + entry.event = CreateEvent(0, FALSE, FALSE, 0); + + /* cond is guarded by mutex */ + if (cond->next) { + cond->last->next = &entry; + cond->last = &entry; + } + else { + cond->next = &entry; + cond->last = &entry; + } + + native_mutex_unlock(mutex); + { + r = WaitForSingleObject(entry.event, INFINITE); + if (r != WAIT_OBJECT_0) { + rb_bug("native_cond_wait: WaitForSingleObject returns %d", r); + } + } + native_mutex_lock(mutex); + + w32_close_handle(entry.event); +} + +void +native_cond_initialize(rb_thread_cond_t *cond) +{ + cond->next = 0; + cond->last = 0; +} + +void +native_cond_destroy(rb_thread_cond_t *cond) +{ + /* */ +} static void native_thread_destroy(rb_thread_t *th) @@ -384,7 +465,7 @@ native_thread_apply_priority(rb_thread_t *th) } static void -ubf_handle(rb_thread_t *th) +ubf_handle(rb_thread_t *th, void *ptr) { thread_debug("ubf_handle: %p\n", th); w32_set_event(th->native_thread_data.interrupt_event); -- cgit v1.2.3