yarv-diff:328
From: ko1 atdot.net
Date: 4 May 2006 18:35:00 -0000
Subject: [yarv-diff:328] r495 - in trunk: . lib yarvtest
Author: ko1
Date: 2006-05-05 03:35:00 +0900 (Fri, 05 May 2006)
New Revision: 495
Modified:
trunk/
trunk/ChangeLog
trunk/common.mk
trunk/disasm.c
trunk/lib/monitor.rb
trunk/lib/mutex_m.rb
trunk/lib/singleton.rb
trunk/lib/tempfile.rb
trunk/lib/thread.rb
trunk/lib/weakref.rb
trunk/signal.c
trunk/thread.c
trunk/thread_pthread.h
trunk/thread_win32.h
trunk/yarvcore.c
trunk/yarvcore.h
trunk/yarvtest/test_thread.rb
Log:
r765@lermite: ko1 | 2006-05-05 03:32:40 +0900
* common.mk : vtune rule make run test.rb
* disasm.c : fix syntax errors (on VC)
* yarvcore.c : ditto
* lib/thread.rb : Mutex#synchronize is defined here
* lib/*.rb : ditto
* signal.c : separate pthread or not
* thread.c : support lightweight wakeup
* thread_pthread.h : ditto
* thread_win32.h : ditto
* yarvcore.h : ditto
* yarvtest/test_thread.rb : restore last change
Property changes on: trunk
___________________________________________________________________
Name: svk:merge
- 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:764
+ 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:765
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/ChangeLog 2006-05-04 18:35:00 UTC (rev 495)
@@ -4,6 +4,31 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-05-05(Fri) 03:03:22 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * common.mk : vtune rule make run test.rb
+
+ * disasm.c : fix syntax errors (on VC)
+
+ * yarvcore.c : ditto
+
+ * lib/thread.rb : Mutex#synchronize is defined here
+
+ * lib/*.rb : ditto
+
+ * signal.c : separate pthread or not
+
+ * thread.c : support lightweight wakeup
+
+ * thread_pthread.h : ditto
+
+ * thread_win32.h : ditto
+
+ * yarvcore.h : ditto
+
+ * yarvtest/test_thread.rb : restore last change
+
+
2006-05-04(Thu) 18:11:43 +0900 Koichi Sasada <ko1 atdot.net>
* eval_thread.c : remove rb_thread_interrupt
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/common.mk 2006-05-04 18:35:00 UTC (rev 495)
@@ -469,7 +469,7 @@
# Intel VTune
vtune: miniruby$(EXEEXT)
- vtl activity -c sampling -app ".\miniruby$(EXEEXT)","-I$(srcdir)/lib $(srcdir)/benchmark/bmx_temp.rb" run
+ vtl activity -c sampling -app ".\miniruby$(EXEEXT)","-I$(srcdir)/lib $(srcdir)/test.rb" run
vtl view -hf -mn miniruby$(EXEEXT) -sum -sort -cd
vtl view -ha -mn miniruby$(EXEEXT) -sum -sort -cd | $(BASERUBY) $(srcdir)/rb/vtlh.rb > ha.lines
Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/disasm.c 2006-05-04 18:35:00 UTC (rev 495)
@@ -570,7 +570,8 @@
}
#define DECL_SYMBOL(name) \
- static VALUE sym_##name;
+ static VALUE sym_##name
+
#define INIT_SYMBOL(name) \
sym_##name = ID2SYM(rb_intern(#name))
@@ -616,6 +617,7 @@
VALUE nbody;
VALUE line = rb_ary_new();
VALUE exception = rb_ary_new(); /* [[....]] */
+
static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
struct st_table *labels_table = st_init_numtable();
@@ -784,8 +786,8 @@
insn_make_insn_table(void)
{
struct st_table *table;
+ int i;
table = st_init_numtable();
- int i;
for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);
Modified: trunk/lib/monitor.rb
===================================================================
--- trunk/lib/monitor.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/monitor.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -41,8 +41,9 @@
empty_cond.signal.
=end
-
+require 'thread'
+
#
# Adds monitor functionality to an arbitrary object by mixing the module with
# +include+. For example:
Modified: trunk/lib/mutex_m.rb
===================================================================
--- trunk/lib/mutex_m.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/mutex_m.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -24,6 +24,8 @@
# this obj can be handled like Mutex
#
+require 'thread'
+
module Mutex_m
def Mutex_m.define_aliases(cl)
cl.module_eval %q{
Modified: trunk/lib/singleton.rb
===================================================================
--- trunk/lib/singleton.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/singleton.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -60,6 +60,8 @@
# and _dump(depth) hooks allows the (partially) resurrections of
# a previous state of ``the instance''.
+require 'thread'
+
module Singleton
# disable build-in copying methods
def clone
Modified: trunk/lib/tempfile.rb
===================================================================
--- trunk/lib/tempfile.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/tempfile.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -6,6 +6,7 @@
require 'delegate'
require 'tmpdir'
+require 'thread'
# A class for managing temporary files. This library is written to be
# thread safe.
Modified: trunk/lib/thread.rb
===================================================================
--- trunk/lib/thread.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/thread.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -21,6 +21,15 @@
Thread.abort_on_exception = true
end
+class Mutex
+ def synchronize
+ self.lock
+ yield
+ ensure
+ self.unlock
+ end
+end
+
#
# ConditionVariable objects augment class Mutex. Using condition variables,
# it is possible to suspend while in the middle of a critical section until a
Modified: trunk/lib/weakref.rb
===================================================================
--- trunk/lib/weakref.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/lib/weakref.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -10,6 +10,7 @@
# p foo.to_s # should raise exception (recycled)
require "delegate"
+require 'thread'
class WeakRef < Delegator
Modified: trunk/signal.c
===================================================================
--- trunk/signal.c 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/signal.c 2006-05-04 18:35:00 UTC (rev 495)
@@ -403,20 +403,19 @@
static int trap_last_mask;
# endif
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
void
rb_disable_interrupt(void)
{
#ifndef _WIN32
-#ifdef HAVE_SIGPROCMASK
sigset_t mask;
sigfillset(&mask);
sigdelset(&mask, SIGVTALRM);
- sigprocmask(SIG_SETMASK, &mask, NULL);
-#else
- int mask;
- mask = sigblock((~0) ^ (1<<SIGVTALRM));
- sigsetmask(mask);
-#endif
+ pthread_sigmask(SIG_SETMASK, &mask, NULL);
trap_last_mask = mask;
#endif
}
@@ -424,7 +423,9 @@
static void
rb_enable_interrupt(void)
{
- rb_trap_restore_mask();
+#ifndef _WIN32
+ pthread_sigmask(SIG_SETMASK, &trap_last_mask, NULL);
+#endif
}
int
Modified: trunk/thread.c
===================================================================
--- trunk/thread.c 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread.c 2006-05-04 18:35:00 UTC (rev 495)
@@ -44,7 +44,7 @@
#define THREAD_DEBUG 0
static void sleep_for_polling();
-static int sleep_timeval(yarv_thread_t *th, struct timeval time);
+static void sleep_timeval(yarv_thread_t *th, struct timeval time);
static void sleep_wait_for_interrupt(yarv_thread_t *th, double sleepsec);
static void sleep_forever(yarv_thread_t *th);
static double timeofday();
@@ -68,6 +68,27 @@
#define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
+static void native_thread_interrupt(yarv_thread_t *th);
+static void yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func, int is_return);
+static void yarv_clear_interrupt_function(yarv_thread_t *th);
+
+#define GVL_UNLOCK_RANGE(exec) do { \
+ yarv_thread_t *__th = GET_THREAD(); \
+ int __prev_status = __th->status; \
+ yarv_set_interrupt_function(__th, native_thread_interrupt, 0); \
+ __th->status = THREAD_STOPPED; \
+ GVL_UNLOCK_BEGIN(); {\
+ exec; \
+ } \
+ GVL_UNLOCK_END(); \
+ yarv_remove_signal_thread_list(__th); \
+ yarv_clear_interrupt_function(__th); \
+ if (__th->status == THREAD_STOPPED) { \
+ __th->status = __prev_status; \
+ } \
+ YARV_CHECK_INTS(); \
+} while(0)
+
#if THREAD_DEBUG
void thread_debug(const char *fmt, ...);
#else
@@ -118,34 +139,48 @@
#endif
-#define GVL_UNLOCK_RANGE(exec) do { \
- yarv_thread_t *__th = GET_THREAD(); \
- int __prev_status = __th->status; \
- YARV_CHECK_INTS(); \
- __th->status = THREAD_STOPPED; \
- GVL_UNLOCK_BEGIN(); {\
- exec; \
- } \
- GVL_UNLOCK_END(); \
- yarv_remove_signal_thread_list(__th); \
- if (__th->status == THREAD_STOPPED) { \
- __th->status = __prev_status; \
- } \
- YARV_CHECK_INTS(); \
-} while(0)
+static void
+yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func, int is_return)
+{
+ check_ints:
+ YARV_CHECK_INTS();
+ native_mutex_lock(&th->interrupt_lock);
+ if (th->interrupt_flag) {
+ native_mutex_unlock(&th->interrupt_lock);
+ if (is_return) {
+ return;
+ }
+ else {
+ goto check_ints;
+ }
+ }
+ else {
+ th->interrupt_function = func;
+ }
+ native_mutex_unlock(&th->interrupt_lock);
+}
+static void
+yarv_clear_interrupt_function(yarv_thread_t *th)
+{
+ native_mutex_lock(&th->interrupt_lock);
+ th->interrupt_function = 0;
+ native_mutex_unlock(&th->interrupt_lock);
+}
static void
rb_thread_interrupt(yarv_thread_t *th)
{
+ native_mutex_lock(&th->interrupt_lock);
th->interrupt_flag = 1;
- if (th->status == THREAD_STOPPED) {
- // (*th->interrupt_function)(th);
- native_thread_interrupt(th);
+
+ if (th->interrupt_function) {
+ (th->interrupt_function)(th);
}
else {
/* none */
}
+ native_mutex_unlock(&th->interrupt_lock);
}
@@ -158,8 +193,8 @@
if (th != main_thread) {
thread_debug("terminate_i: %p\n", th);
- th->throwed_errinfo = eTerminateSignal;
rb_thread_interrupt(th);
+ th->throwed_errinfo = eTerminateSignal;
th->status = THREAD_TO_KILL;
}
else {
@@ -174,7 +209,7 @@
yarv_thread_t *th = GET_THREAD(); /* main thread */
yarv_vm_t *vm = th->vm;
if (vm->main_thread != th) {
- rb_bug("rb_thread_terminate_all: called by child thread");
+ rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)", vm->main_thread, th);
}
thread_debug("rb_thread_terminate_all (main thread: %p)\n", th);
@@ -262,6 +297,8 @@
th->first_args = args;
th->first_proc = rb_block_proc();
+ native_mutex_initialize(&th->interrupt_lock);
+
/* kick thread */
native_thread_create(th);
st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
@@ -403,16 +440,6 @@
* Thread Scheduling
*/
-#if !defined(HAVE_PAUSE) || defined(__CYGWIN__)
-# if defined(_WIN32) || defined(__CYGWIN__)
-# define pause(th) w32_sleep(th, INFINITE)
-# else
-# define pause(th) sleep(0x7fffffff)
-# endif
-#else
-#define pause(th) pause()
-#endif
-
static struct timeval
double2timeval(double d)
{
@@ -430,13 +457,20 @@
static void
sleep_forever(yarv_thread_t *th)
{
- thread_debug("rb_thread_sleep_forever\n");
- GVL_UNLOCK_RANGE(pause(th));
+ native_sleep(th, 0);
+ YARV_CHECK_INTS();
}
+static void
+sleep_timeval(yarv_thread_t *th, struct timeval tv)
+{
+ native_sleep(th, &tv);
+}
+
void
rb_thread_sleep_forever()
{
+ thread_debug("rb_thread_sleep_forever\n");
sleep_forever(GET_THREAD());
}
@@ -448,29 +482,6 @@
return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
}
-static int
-sleep_timeval(yarv_thread_t *th, struct timeval time)
-{
-#if defined(_WIN32) || defined(__CYGWIN__)
- DWORD limit = time.tv_sec * 1000 + time.tv_usec / 1000;
- thread_debug("sleep_timeval - sleep start\n");
- w32_sleep(th, limit);
- thread_debug("sleep_timeval - sleep end\n");
- return 0;
-#else
- thread_debug("sleep_timeval\n");
- {
- int n = select(0, 0, 0, 0, &time);
- if (n == 0) {
- return 0;
- }
- else {
- return errno;
- }
- }
-#endif
-}
-
static void
sleep_wait_for_interrupt(yarv_thread_t *th, double sleepsec)
{
@@ -482,7 +493,7 @@
{
struct timeval time;
time.tv_sec = 0;
- time.tv_usec = 100000; /* 0.1 sec */
+ time.tv_usec = 100 * 1000; /* 0.1 sec */
sleep_timeval(th, time);
}
@@ -490,33 +501,7 @@
rb_thread_wait_for(struct timeval time)
{
yarv_thread_t *th = GET_THREAD();
- double d, limit;
- limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
- thread_debug("rb_thread_wait_for\n");
-
- while (1) {
- int ret;
- GVL_UNLOCK_RANGE(ret = sleep_timeval(th, time));
-
- switch (ret) {
- case 0:
- return;
- case EINTR:
-#ifdef ERESTART
- case ERESTART:
-#endif
- break;
- default:
- rb_sys_fail("rb_thread_wait_for");
- }
-
- /* prepare to restart */
- d = limit - timeofday();
- time = double2timeval(d);
- if (time.tv_sec < 0) {
- return;
- }
- }
+ sleep_timeval(th, time);
}
void
@@ -524,7 +509,7 @@
{
if (!rb_thread_alone()) {
yarv_thread_t *th = GET_THREAD();
- GVL_UNLOCK_RANGE(sleep_for_polling(th));
+ sleep_for_polling(th);
}
}
@@ -557,6 +542,7 @@
}
}
+
static VALUE
rb_thread_s_critical(VALUE self)
{
@@ -606,7 +592,6 @@
return Qnil;
}
-
/*
*
*/
@@ -614,7 +599,6 @@
void
yarv_thread_execute_interrupts(yarv_thread_t *th)
{
-
while (th->interrupt_flag) {
int status = th->status;
th->status = THREAD_RUNNABLE;
@@ -622,8 +606,9 @@
/* signal handling */
if (th->exec_signal) {
- rb_signal_exec(th, th->exec_signal);
+ int sig = th->exec_signal;
th->exec_signal = 0;
+ rb_signal_exec(th, sig);
}
/* exception from another thread */
@@ -631,7 +616,7 @@
VALUE err = th->throwed_errinfo;
th->throwed_errinfo = 0;
thread_debug("yarv_thread_execute_interrupts: %p\n", err);
-
+
if (err == eKillSignal) {
th->errinfo = INT2FIX(TAG_FATAL);
TH_JUMP_TAG(th, TAG_FATAL);
@@ -651,8 +636,8 @@
rb_exc_raise(err);
}
}
-
th->status = status;
+
/* thread pass */
rb_thread_schedule();
}
@@ -676,10 +661,7 @@
exc = rb_make_exception(argc, argv);
// TODO: need synchronization if run threads in parallel
th->throwed_errinfo = exc;
- th->interrupt_flag = 1;
-
rb_thread_ready(th);
-
return Qnil;
}
@@ -842,7 +824,6 @@
if (th->status == THREAD_KILLED) {
rb_raise(rb_eThreadError, "killed thread");
}
-
rb_thread_ready(th);
return thread;
}
@@ -905,11 +886,9 @@
"stopping only thread\n\tnote: use sleep to stop forever");
}
rb_thread_sleep_forever();
-
return Qnil;
}
-
static int
thread_list_i(st_data_t key, st_data_t val, void *data)
{
@@ -1590,7 +1569,8 @@
if (vm->bufferd_signal_size && vm->main_thread->exec_signal == 0) {
vm->main_thread->exec_signal = rb_get_next_signal(vm);
- vm->main_thread->interrupt_flag = 1;
+ thread_debug("bufferd_signal_size: %d, sig: %d\n",
+ vm->bufferd_signal_size, vm->main_thread->exec_signal);
rb_thread_interrupt(vm->main_thread);
}
}
@@ -1906,24 +1886,6 @@
return self;
}
-static VALUE
-mutex_synchronize(VALUE self)
-{
- int state;
- VALUE val;
-
- mutex_lock(self);
- PUSH_TAG(PROTO_NONE);
- if ((state = EXEC_TAG()) == 0) {
- val = rb_yield(Qnil);
- }
- mutex_unlock(self);
- POP_TAG();
- if (state) {
- JUMP_TAG(state);
- }
- return val;
-}
void
Init_yarvthread()
@@ -1993,7 +1955,6 @@
rb_define_method(cMutex, "lock", mutex_lock, 0);
rb_define_method(cMutex, "unlock", mutex_unlock, 0);
rb_define_method(cMutex, "unlock_and_stop", mutex_unlock_and_stop, 0);
- rb_define_method(cMutex, "synchronize", mutex_synchronize, 0);
Init_native_thread();
{
@@ -2003,6 +1964,7 @@
yarv_thread_lock_t *lp = &GET_THREAD()->vm->global_interpreter_lock;
native_mutex_initialize(lp);
native_mutex_lock(lp);
+ native_mutex_initialize(&GET_THREAD()->interrupt_lock);
}
}
Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread_pthread.h 2006-05-04 18:35:00 UTC (rev 495)
@@ -12,6 +12,7 @@
typedef struct native_thread_data_struct {
void *signal_thread_list;
+ pthread_cond_t sleep_cond;
} native_thread_data_t;
#endif /* THREAD_PTHREAD_H_INCLUDED */
@@ -54,7 +55,7 @@
static yarv_thread_t *register_cached_thread_and_wait(void);
-#define USE_THREAD_CACHE 1
+#define USE_THREAD_CACHE 0
static void *
thread_start_func_1(void *th_ptr)
@@ -107,11 +108,13 @@
volatile yarv_thread_t *th_area = 0;
struct cached_thread_entry *entry =
(struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
+
+ struct timeval tv;
+ struct timespec ts;
+ gettimeofday(&tv, 0);
+ ts.tv_sec = tv.tv_sec + 60;
+ ts.tv_nsec = tv.tv_usec * 1000;
- struct timespec tm = {
- time(0) + 60 /* 60 seconds */, 0,
- };
-
pthread_mutex_lock(&thread_cache_lock);
{
entry->th_area = &th_area;
@@ -119,7 +122,7 @@
entry->next = cached_thread_root;
cached_thread_root = entry;
- pthread_cond_timedwait(&cond, &thread_cache_lock, &tm);
+ pthread_cond_timedwait(&cond, &thread_cache_lock, &ts);
{
struct cached_thread_entry *e = cached_thread_root;
@@ -139,6 +142,7 @@
e = e->next;
}
}
+
free(entry);
pthread_cond_destroy(&cond);
}
@@ -222,6 +226,13 @@
}
static void
+interrupt_using_pthread_cond_signal(yarv_thread_t *th)
+{
+ thread_debug("interrupt_using_pthread_cond_signal (%p)\n", th);
+ pthread_cond_signal(&th->native_thread_data.sleep_cond);
+}
+
+static void
native_thread_send_interrupt_signal(yarv_thread_t *th)
{
thread_debug("native_thread_send_interrupt_signal (%p)\n", th->thread_id);
@@ -230,6 +241,51 @@
}
}
+static void
+native_sleep(yarv_thread_t *th, struct timeval *tv)
+{
+ int prev_status = th->status;
+ struct timespec ts;
+ struct timeval tvn;
+
+ if (tv) {
+ gettimeofday(&tvn, NULL);
+ ts.tv_sec = tvn.tv_sec + tv->tv_sec;
+ ts.tv_nsec = (tvn.tv_usec + tv->tv_usec) * 1000;
+ }
+
+ th->status = THREAD_STOPPED;
+ pthread_cond_init(&th->native_thread_data.sleep_cond, 0);
+
+ GVL_UNLOCK_BEGIN();
+ {
+ pthread_mutex_lock(&th->interrupt_lock);
+
+ if (th->interrupt_flag) {
+ /* interrupted. return immediate */
+ }
+ else {
+ th->interrupt_function = interrupt_using_pthread_cond_signal;
+ if (tv == 0) {
+ thread_debug("native_sleep: pthread_cond_wait start\n");
+ pthread_cond_wait(&th->native_thread_data.sleep_cond, &th->interrupt_lock);
+ thread_debug("native_sleep: pthread_cond_wait end\n");
+ }
+ else {
+ int r;
+ thread_debug("native_sleep: pthread_cond_timedwait start (%d, %d)\n", ts.tv_sec, ts.tv_nsec);
+ r = pthread_cond_timedwait(&th->native_thread_data.sleep_cond, &th->interrupt_lock, &ts);
+ thread_debug("native_sleep: pthread_cond_timedwait end (%d)\n", r);
+ }
+ th->interrupt_function = 0;
+ }
+ pthread_mutex_unlock(&th->interrupt_lock);
+
+ th->status = prev_status;
+ }
+ GVL_UNLOCK_END();
+}
+
void
native_thread_interrupt(yarv_thread_t *th)
{
@@ -340,7 +396,6 @@
}
});
}
-
timer_function();
}
return NULL;
Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/thread_win32.h 2006-05-04 18:35:00 UTC (rev 495)
@@ -79,6 +79,7 @@
if (th) {
HANDLE intr = th->native_thread_data.interrupt_event;
+ ResetEvent(intr);
if (th->interrupt_flag) {
SetEvent(intr);
@@ -106,12 +107,22 @@
}
static void
-w32_sleep(yarv_thread_t *th, DWORD msec)
+native_sleep(yarv_thread_t *th, struct timeval *tv)
{
- DWORD ret;
- thread_debug("w32_sleep start\n");
- ret = w32_wait_event(0, msec, th);
- thread_debug("w32_sleep done (%d)\n", ret);
+ DWORD msec;
+ if (tv) {
+ msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ }
+ else {
+ msec = INFINITE;
+ }
+
+ GVL_UNLOCK_RANGE({
+ DWORD ret;
+ thread_debug("native_sleep start (%d)\n", (int)msec);
+ ret = w32_wait_event(0, msec, th);
+ thread_debug("native_sleep done (%d)\n", ret);
+ });
}
int
@@ -253,7 +264,7 @@
SetThreadPriority(th->thread_id, priority);
}
-void
+static void
native_thread_interrupt(yarv_thread_t *th)
{
thread_debug("native_thread_interrupt: %p\n", th);
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/yarvcore.c 2006-05-04 18:35:00 UTC (rev 495)
@@ -475,6 +475,7 @@
VALUE iseq_type;
struct st_table *type_map = 0;
+ yarv_iseq_t *iseq;
/* [magic, major_version, minor_version, format_type, misc,
* name, filename, line,
@@ -499,7 +500,6 @@
exception = rb_ary_entry(data, 11);
body = rb_ary_entry(data, 12);
- yarv_iseq_t *iseq;
GetISeqVal(iseqval, iseq);
iseq->self = iseqval;
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/yarvcore.h 2006-05-04 18:35:00 UTC (rev 495)
@@ -373,7 +373,10 @@
struct yarv_tag *prev;
};
-typedef struct yarv_thread_struct {
+typedef void yarv_interrupt_function_t(struct yarv_thread_struct *);
+
+typedef struct yarv_thread_struct
+{
VALUE self;
yarv_vm_t *vm;
@@ -410,8 +413,12 @@
VALUE errinfo;
VALUE throwed_errinfo;
+ int exec_signal;
+
int interrupt_flag;
- int exec_signal;
+ yarv_interrupt_function_t *interrupt_function;
+ yarv_thread_lock_t interrupt_lock;
+
struct yarv_tag *tag;
int parse_in_eval;
@@ -420,7 +427,7 @@
struct yarv_thread_struct *join_list_next;
struct yarv_thread_struct *join_list_head;
-
+
VALUE first_proc;
VALUE first_args;
Modified: trunk/yarvtest/test_thread.rb
===================================================================
--- trunk/yarvtest/test_thread.rb 2006-05-04 18:34:07 UTC (rev 494)
+++ trunk/yarvtest/test_thread.rb 2006-05-04 18:35:00 UTC (rev 495)
@@ -31,7 +31,7 @@
def test_create_many_threads2
ae %q{
- 2000.times{|e|
+ 5000.times{|e|
(1..2).map{
Thread.new{
}
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml