yarv-diff:379
From: ko1 atdot.net
Date: 2 Sep 2006 22:52:33 +0900
Subject: [yarv-diff:379] r546 - in branches/parallel: . yarvtest
Author: ko1
Date: 2006-09-02 22:52:32 +0900 (Sat, 02 Sep 2006)
New Revision: 546
Modified:
branches/parallel/ChangeLog
branches/parallel/compile.c
branches/parallel/configure.in
branches/parallel/gc.c
branches/parallel/re.c
branches/parallel/regint.h
branches/parallel/thread.c
branches/parallel/thread_pthread.h
branches/parallel/yarvcore.c
branches/parallel/yarvcore.h
branches/parallel/yarvtest/test_thread.rb
Log:
Caution: there are some synchronization bugs.
* compile.c : same change of trunk
* configure.in : check pthread_spinlock_t and sched_setaffinity
* re.c : use thread local regs
* yarvcore.c : ditto
* regint.h : disable USE_MULTI_THREAD_SYSTEM macro
* thread.c : check RUBY_MAX_CPU environment variable
* thread.c, thread_pthread.h : fix parallel behaviour
* yarvcore.h : ditto
* gc.c : ditto
* yarvtest/test_thread.rb : add some tests for above
Modified: branches/parallel/ChangeLog
===================================================================
--- branches/parallel/ChangeLog 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/ChangeLog 2006-09-02 13:52:32 UTC (rev 546)
@@ -4,6 +4,29 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-09-02(Sat) 22:35:43 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * compile.c : same change of trunk
+
+ * configure.in : check pthread_spinlock_t and sched_setaffinity
+
+ * re.c : use thread local regs
+
+ * yarvcore.c : ditto
+
+ * regint.h : disable USE_MULTI_THREAD_SYSTEM macro
+
+ * thread.c : check RUBY_MAX_CPU environment variable
+
+ * thread.c, thread_pthread.h : fix parallel behaviour
+
+ * yarvcore.h : ditto
+
+ * gc.c : ditto
+
+ * yarvtest/test_thread.rb : add some tests for above
+
+
2006-08-31(Thu) 19:09:56 +0900 Koichi Sasada <ko1 atdot.net>
* configure.in : check pthread_spinlock_t
Modified: branches/parallel/compile.c
===================================================================
--- branches/parallel/compile.c 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/compile.c 2006-09-02 13:52:32 UTC (rev 546)
@@ -1483,7 +1483,7 @@
if (diobj == niobj) {
REMOVE_ELEM(&iobj->link);
}
- else if (diobj->insn_id == BIN(jump)) {
+ else if (iobj != diobj && diobj->insn_id == BIN(jump)) {
OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
goto again;
}
@@ -3900,25 +3900,27 @@
}
-#if OPT_BASIC_OPERATIONS
- /* TODO: detect by node */
- if (recv->last == recv->anchor.next &&
- INSN_OF(recv->last) == BIN(putobject) &&
- nd_type(node) == NODE_MATCH2) {
- ADD_SEQ(ret, val);
- ADD_INSN1(ret, nd_line(node), opt_regexpmatch1,
- OPERAND_AT(recv->last, 0));
+ if (iseq->compile_data->option->specialized_instruction) {
+ /* TODO: detect by node */
+ if (recv->last == recv->anchor.next &&
+ INSN_OF(recv->last) == BIN(putobject) &&
+ nd_type(node) == NODE_MATCH2) {
+ ADD_SEQ(ret, val);
+ ADD_INSN1(ret, nd_line(node), opt_regexpmatch1,
+ OPERAND_AT(recv->last, 0));
+ }
+ else {
+ ADD_SEQ(ret, recv);
+ ADD_SEQ(ret, val);
+ ADD_INSN(ret, nd_line(node), opt_regexpmatch2);
+ }
}
else {
ADD_SEQ(ret, recv);
ADD_SEQ(ret, val);
- ADD_INSN(ret, nd_line(node), opt_regexpmatch2);
+ ADD_SEND(ret, nd_line(node), ID2SYM(idEqTilde), INT2FIX(1));
}
-#else
- ADD_SEQ(ret, recv);
- ADD_SEQ(ret, val);
- ADD_SEND(ret, nd_line(node), ID2SYM(idEqTilde), INT2FIX(1));
-#endif
+
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
Modified: branches/parallel/configure.in
===================================================================
--- branches/parallel/configure.in 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/configure.in 2006-09-02 13:52:32 UTC (rev 546)
@@ -782,7 +782,9 @@
fi
fi
-AC_CHECK_TYPES(pthread_spinlock_t, , , pthread.h)
+AC_CHECK_HEADERS(pthread.h)
+AC_CHECK_TYPES(pthread_spinlock_t)
+AC_CHECK_FUNCS(sched_setaffinity)
if test x"$ac_cv_header_ucontext_h" = xyes; then
if test x"$rb_with_pthread" = xyes; then
Modified: branches/parallel/gc.c
===================================================================
--- branches/parallel/gc.c 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/gc.c 2006-09-02 13:52:32 UTC (rev 546)
@@ -489,14 +489,6 @@
locked = rb_thread_global_lock_acquire(th);
- while (th->interrupt_gc_flag) {
- rb_thread_global_lock_release(th);
- rb_thread_gc_barrier_stop(th);
- rb_thread_global_lock_acquire(th);
- }
-
- rb_thread_gc_barrier_start(th);
-
for (i=0; i<YARV_VALUE_CACHE_SIZE; i++) {
VALUE v = rb_newobj_from_heap();
@@ -505,8 +497,6 @@
}
th->value_cache_ptr = &th->value_cache[0];
rv = rb_newobj_from_heap();
-
- rb_thread_gc_barrier_end(th);
if (locked) {
rb_thread_global_lock_release(th);
@@ -1351,9 +1341,29 @@
#endif /* __human68k__ or DJGPP */
#endif /* __GNUC__ */
+static int garbage_collect_thread_unsafe(void);
+
static int
garbage_collect(void)
{
+ yarv_thread_t *th = GET_THREAD();
+ int r, locked = rb_thread_global_lock_acquire(th);
+
+ rb_thread_gc_barrier_start(th);
+ if (freelist == 0) {
+ r = garbage_collect_thread_unsafe();
+ }
+ rb_thread_gc_barrier_end(th);
+
+ if (locked) {
+ rb_thread_global_lock_release(th);
+ }
+ return r;
+}
+
+static int
+garbage_collect_thread_unsafe(void)
+{
struct gc_list *list;
jmp_buf save_regs_gc_mark;
yarv_thread_t *th = GET_THREAD();
Modified: branches/parallel/re.c
===================================================================
--- branches/parallel/re.c 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/re.c 2006-09-02 13:52:32 UTC (rev 546)
@@ -965,12 +965,14 @@
return pos;
}
+void *rb_thread_get_local_regs(void);
+
long
rb_reg_search(VALUE re, VALUE str, long pos, long reverse)
{
long result;
VALUE match;
- static struct re_registers regs;
+ struct re_registers *regs = rb_thread_get_local_regs();
long range;
if (pos > RSTRING(str)->len || pos < 0) {
@@ -998,7 +1000,7 @@
((UChar*)(RSTRING(str)->ptr) + RSTRING(str)->len),
((UChar*)(RSTRING(str)->ptr) + pos),
((UChar*)(RSTRING(str)->ptr) + pos + range),
- ®s, ONIG_OPTION_NONE);
+ regs, ONIG_OPTION_NONE);
if (FL_TEST(re, KCODE_FIXED))
kcode_reset_option();
@@ -1026,7 +1028,7 @@
FL_UNSET(match, FL_TAINT);
}
- onig_region_copy(RMATCH(match)->regs, ®s);
+ onig_region_copy(RMATCH(match)->regs, regs);
RMATCH(match)->str = rb_str_new4(str);
RMATCH(match)->regexp = re;
rb_backref_set(match);
Modified: branches/parallel/regint.h
===================================================================
--- branches/parallel/regint.h 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/regint.h 2006-09-02 13:52:32 UTC (rev 546)
@@ -98,24 +98,20 @@
#include "version.h"
#include "rubysig.h" /* for DEFER_INTS, ENABLE_INTS */
-#define USE_MULTI_THREAD_SYSTEM
-#define THREAD_ATOMIC_START DEFER_INTS
-#define THREAD_ATOMIC_END ENABLE_INTS
+// #define USE_MULTI_THREAD_SYSTEM
+#define THREAD_ATOMIC_START
+#define THREAD_ATOMIC_END
+//#define THREAD_ATOMIC_START DEFER_INTS
+//#define THREAD_ATOMIC_END ENABLE_INTS
#define THREAD_PASS rb_thread_schedule()
-#define CHECK_INTERRUPT do {\
- if (rb_trap_pending) {\
- if (! rb_prohibit_interrupt) {\
- rb_trap_exec();\
- }\
- }\
-} while (0)
+#define CHECK_INTERRUPT
#define DEFAULT_WARN_FUNCTION onig_rb_warn
#define DEFAULT_VERB_WARN_FUNCTION onig_rb_warning
#endif /* else NOT_RUBY */
-#define THREAD_PASS_LIMIT_COUNT 8
+#define THREAD_PASS_LIMIT_COUNT 2048
#define xmemset memset
#define xmemcpy memcpy
#define xmemmove memmove
Modified: branches/parallel/thread.c
===================================================================
--- branches/parallel/thread.c 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/thread.c 2006-09-02 13:52:32 UTC (rev 546)
@@ -75,6 +75,15 @@
static void yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func);
static void yarv_clear_interrupt_function(yarv_thread_t *th);
+#define BLOCKING_RANGE(th, func, body) do { \
+ if (rb_thread_blocking_start(th, func) != 0) { \
+ body; \
+ rb_thread_blocking_end(th); \
+ } \
+} while (0)
+
+
+
#if THREAD_DEBUG
void thread_debug(const char *fmt, ...);
#else
@@ -128,6 +137,7 @@
#endif
+
int
rb_thread_global_lock_acquire(yarv_thread_t *th)
{
@@ -173,24 +183,26 @@
return vm->lock_owner_thread == th;
}
-static void
+static int
rb_thread_blocking_start(yarv_thread_t *th, yarv_interrupt_function_t *func)
{
yarv_vm_t *vm = GET_VM();
-
- retry:
- YARV_CHECK_INTS_TH(th);
yarv_set_interrupt_function(th, func);
+ if (th->interrupt_flag) {
+ /* there is possibility that interrupt was occurrd before
+ setting set_interrupt_function */
+ return 0;
+ }
+
vm->num_wait_threads++;
+ if (vm->interrupt_gc_flag) {
+ pthread_cond_signal(&vm->gc_barrier_owner_cond);
+ }
+
yarv_save_machine_context(th);
-
rb_thread_global_lock_release(th);
-
- if (th->interrupt_flag) {
- rb_thread_global_lock_acquire(th);
- goto retry;
- }
+ return 1;
}
static void
@@ -198,19 +210,35 @@
{
yarv_vm_t *vm = GET_VM();
rb_thread_global_lock_acquire(th);
+ yarv_clear_interrupt_function(th);
vm->num_wait_threads--;
- yarv_clear_interrupt_function(th);
}
-static int
-set_gc_interrupt_flag(st_data_t key, st_data_t val, st_data_t set)
+void
+rb_thread_gc_barrier_stop(yarv_thread_t *th)
{
- VALUE thval = key;
- yarv_thread_t *th;
- GetThreadPtr(thval, th);
- th->interrupt_gc_flag = set;
- th->interrupt_flag = set;
- return ST_CONTINUE;
+ yarv_vm_t *vm = GET_VM();
+ int locked;
+
+ thread_debug("rb_thread_gc_barrier_stop: start\n");
+
+ locked = rb_thread_global_lock_acquire(th);
+ vm->lock_owner_thread = 0;
+ vm->num_wait_threads++;
+ thread_debug("rb_thread_gc_barrier_stop: waiting -> %d\n",
+ vm->num_wait_threads);
+ {
+ pthread_cond_signal(&vm->gc_barrier_owner_cond);
+ pthread_cond_wait(&vm->gc_barrier_waits_cond,
+ &vm->global_interpreter_lock);
+ }
+ vm->num_wait_threads--;
+ vm->lock_owner_thread = th;
+
+ if (locked) {
+ rb_thread_global_lock_release(th);
+ }
+ thread_debug("rb_thread_gc_barrier_stop: end\n");
}
void
@@ -222,13 +250,21 @@
/* skip */
}
else {
- st_foreach(vm->living_threads, set_gc_interrupt_flag, 1);
+ while (vm->interrupt_gc_flag) {
+ rb_thread_global_lock_release(th);
+ rb_thread_gc_barrier_stop(th);
+ rb_thread_global_lock_acquire(th);
+ }
+
+ vm->interrupt_gc_flag = 1;
vm->lock_owner_thread = 0;
while (vm->living_threads->num_entries != vm->num_wait_threads + 1) {
+ thread_debug("rb_thread_gc_barrier_start: block start - ltnum: %d, wtnum: %d\n",
+ vm->living_threads->num_entries, vm->num_wait_threads);
pthread_cond_wait(&vm->gc_barrier_owner_cond,
&vm->global_interpreter_lock);
- thread_debug("ltnum: %d, wtnum: %d\n",
+ thread_debug("rb_thread_gc_barrier_start: block end - ltnum: %d, wtnum: %d\n",
vm->living_threads->num_entries, vm->num_wait_threads);
}
}
@@ -242,35 +278,11 @@
yarv_vm_t *vm = GET_VM();
thread_debug("rb_thread_gc_barrier_end: start\n");
- if (vm->living_threads) {
- st_foreach(vm->living_threads, set_gc_interrupt_flag, 0);
- }
+ vm->interrupt_gc_flag = 0;
pthread_cond_broadcast(&vm->gc_barrier_waits_cond);
thread_debug("rb_thread_gc_barrier_end: end\n");
}
-void
-rb_thread_gc_barrier_stop(yarv_thread_t *th)
-{
- yarv_vm_t *vm = GET_VM();
-
- thread_debug("rb_thread_gc_barrier_stop: start\n");
-
- rb_thread_global_lock_acquire(th);
- vm->lock_owner_thread = 0;
- vm->num_wait_threads++;
- thread_debug("rb_thread_gc_barrier_stop: waiting -> %d\n", vm->num_wait_threads);
- {
- pthread_cond_signal(&vm->gc_barrier_owner_cond);
- pthread_cond_wait(&vm->gc_barrier_waits_cond,
- &vm->global_interpreter_lock);
- }
- vm->num_wait_threads--;
- vm->lock_owner_thread = th;
- rb_thread_global_lock_release(th);
- thread_debug("rb_thread_gc_barrier_stop: end\n");
-}
-
static void
yarv_set_interrupt_function(yarv_thread_t *th, yarv_interrupt_function_t *func)
{
@@ -334,11 +346,19 @@
}
thread_debug("rb_thread_terminate_all (main thread: %p)\n", th);
- st_foreach(vm->living_threads, terminate_i, (st_data_t)th);
while (!rb_thread_alone()) {
+ st_foreach(vm->living_threads, terminate_i, (st_data_t)th);
+ if (vm->interrupt_gc_flag) {
+ rb_thread_gc_barrier_stop(th);
+ }
+ YARV_CHECK_INTS();
rb_thread_schedule();
}
+
+ rb_thread_global_lock_acquire(th);
+ thread_debug("rb_thread_terminate_all (all terminated)\n", th);
+
system_working = 0;
}
@@ -351,6 +371,13 @@
yarv_thread_t *th = th_ptr;
th->status = THREAD_KILLED;
th->machine_stack_start = th->machine_stack_end = 0;
+ st_delete_wrap(th->vm->living_threads, th->self);
+
+ if (th->vm->interrupt_gc_flag) {
+ pthread_cond_signal(&th->vm->gc_barrier_owner_cond);
+ }
+ rb_thread_global_lock_release(th);
+ thread_debug("thread terminated: %p\n", th);
}
@@ -397,10 +424,7 @@
rb_thread_interrupt(join_th);
join_th = join_th->join_list_next;
}
- st_delete_wrap(th->vm->living_threads, th->self);
}
- rb_thread_global_lock_release(th);
- thread_debug("thread terminated: %p\n", th);
return 0;
}
@@ -425,10 +449,6 @@
/* kick thread */
st_insert(target_th->vm->living_threads, thval, (st_data_t) th->thread_id);
-
- if (th->interrupt_flag && th->interrupt_gc_flag) {
- target_th->interrupt_flag = target_th->interrupt_gc_flag = 1;
- }
rb_thread_global_lock_acquire(GET_THREAD());
native_thread_create(target_th);
@@ -727,6 +747,8 @@
th->status = THREAD_RUNNABLE;
th->interrupt_flag = 0;
+ YARV_CHECK_GC_BARRIER(th);
+
/* signal handling */
if (th->exec_signal) {
int sig = th->exec_signal;
@@ -734,10 +756,6 @@
rb_signal_exec(th, sig);
}
- if (th->interrupt_gc_flag) {
- rb_thread_gc_barrier_stop(th);
- }
-
/* exception from another thread */
if (th->throwed_errinfo) {
VALUE err = th->throwed_errinfo;
@@ -764,9 +782,6 @@
}
}
th->status = status;
-
- /* thread pass */
- rb_thread_schedule();
}
}
@@ -1599,9 +1614,9 @@
FD_SET(fd, &set);
thread_debug("rb_thread_wait_fd (%d)\n", fd);
while (result <= 0) {
- rb_thread_blocking_start(th, interrupt_using_posix_signal);
- result = select(fd + 1, &set, 0, 0, 0);
- rb_thread_blocking_end(th);
+ BLOCKING_RANGE(th, interrupt_using_posix_signal, {
+ result = select(fd + 1, &set, 0, 0, 0);
+ });
}
thread_debug("rb_thread_wait_fd done\n", fd);
}
@@ -1618,9 +1633,9 @@
thread_debug("rb_thread_fd_writable (%d)\n", fd);
while (result <= 0) {
- rb_thread_blocking_start(th, interrupt_using_posix_signal);
- result = select(fd + 1, 0, &set, 0, 0);
- rb_thread_blocking_end(th);
+ BLOCKING_RANGE(th, interrupt_using_posix_signal, {
+ result = select(fd + 1, 0, &set, 0, 0);
+ });
}
thread_debug("rb_thread_fd_writable done\n");
return Qtrue;
@@ -1665,13 +1680,16 @@
#endif
for (;;) {
- rb_thread_blocking_start(th, interrupt_using_posix_signal);
- n = select(max, read, write, except, tvp);
- lerrno = errno;
- rb_thread_blocking_end(th);
+ n = -1;
+ lerrno = EINTR;
+ BLOCKING_RANGE(th, interrupt_using_posix_signal, {
+ n = select(max, read, write, except, tvp);
+ lerrno = errno;
+ });
+
if (n < 0) {
- switch (errno) {
+ switch (lerrno) {
case EINTR:
#ifdef ERESTART
case ERESTART:
@@ -1763,11 +1781,9 @@
{
char buff[100];
yarv_thread_t *th = GET_THREAD();
- rb_thread_blocking_start(th, 0);
- {
+ BLOCKING_RANGE(th, 0, {
fgets(buff, 100, stdin);
- }
- rb_thread_blocking_end(th);
+ });
return rb_str_new2(buff);
}
@@ -2043,9 +2059,10 @@
}
if (native_mutex_trylock(&mutex->lock) != 0) {
/* can't cancel */
- rb_thread_blocking_start(th, 0);
- native_mutex_lock(&mutex->lock);
- rb_thread_blocking_end(th);
+ BLOCKING_RANGE(th, 0, {
+ native_mutex_lock(&mutex->lock);
+ rb_thread_blocking_end(th);
+ });
}
mutex->th = th;
@@ -2173,6 +2190,32 @@
make_timer_thread();
atexit(show_func);
+
+#if HAVE_SCHED_SETAFFINITY
+ if (getenv("RUBY_MAX_CPU")) {
+ int i, max;
+ cpu_set_t mask;
+ char *env = getenv("RUBY_MAX_CPU");
+
+ if (0) {
+ /* for debug */
+ sched_getaffinity(0, sizeof(cpu_set_t), &mask);
+ for (i=0; i<8; i++) {
+ printf("%d: %d\n", i, __CPU_ISSET(i, &mask));
+ }
+ }
+ max = atoi(env);
+ if (max > 0) {
+ __CPU_ZERO(&mask);
+ for (i=0; i<max; i++) {
+ __CPU_SET(i, &mask);
+ }
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) != 0) {
+ rb_bug("sched_setaffinity error: %d\n", errno);
+ }
+ }
+ }
+#endif
rb_disable_interrupt(); /* only timer thread recieve signal */
}
Modified: branches/parallel/thread_pthread.h
===================================================================
--- branches/parallel/thread_pthread.h 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/thread_pthread.h 2006-09-02 13:52:32 UTC (rev 546)
@@ -3,6 +3,7 @@
#define THREAD_PTHREAD_H_INCLUDED
#include <pthread.h>
+
typedef pthread_t yarv_thread_id_t;
typedef pthread_mutex_t yarv_thread_lock_t;
typedef pthread_cond_t yarv_thread_cond_t;
@@ -68,7 +69,7 @@
static void yarv_add_signal_thread_list(yarv_thread_t *th);
static void yarv_remove_signal_thread_list(yarv_thread_t *th);
-static void rb_thread_blocking_start(yarv_thread_t *th, yarv_interrupt_function_t *func);
+static int rb_thread_blocking_start(yarv_thread_t *th, yarv_interrupt_function_t *func);
static void rb_thread_blocking_end(yarv_thread_t *th);
static yarv_thread_fglock_t signal_thread_list_lock;
@@ -105,14 +106,14 @@
VALUE stack_start;
/* ignore self and klass */
- native_cleanup_push(thread_cleanup_func, th);
+// native_cleanup_push(thread_cleanup_func, th);
/* run */
thread_start_func_2(th, &stack_start);
/* cleanup */
thread_cleanup_func(th);
- native_cleanup_pop(0);
+// native_cleanup_pop(0);
}
#if USE_THREAD_CACHE
if (1) {
@@ -275,7 +276,7 @@
static void
interrupt_using_pthread_cond_signal(yarv_thread_t *th)
{
- thread_debug("interrupt_using_pthread_cond_signal (%p)\n", th);
+ thread_debug("interrupt_using_pthread_cond_signal (thid: %p)\n", th->thread_id);
pthread_cond_signal(&th->native_thread_data.sleep_cond);
}
@@ -306,10 +307,9 @@
thread_debug("native_sleep %d\n", tv ? tv->tv_sec : -1);
- rb_thread_blocking_start(th, interrupt_using_pthread_cond_signal);
- {
+ BLOCKING_RANGE(th, interrupt_using_pthread_cond_signal, {
pthread_mutex_lock(&th->interrupt_lock);
-
+
if (th->interrupt_flag) {
/* interrupted. return immediate */
thread_debug("native_sleep: interrupted before sleep\n");
@@ -334,9 +334,8 @@
}
pthread_mutex_unlock(&th->interrupt_lock);
- th->status = prev_status;
- }
- rb_thread_blocking_end(th);
+ });
+ th->status = prev_status;
thread_debug("native_sleep done\n");
}
Modified: branches/parallel/yarvcore.c
===================================================================
--- branches/parallel/yarvcore.c 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/yarvcore.c 2006-09-02 13:52:32 UTC (rev 546)
@@ -294,6 +294,7 @@
th = ptr;
FREE_UNLESS_NULL(th->stack);
FREE_UNLESS_NULL(th->top_local_tbl);
+ onig_region_free(&th->regs, 0);
if (th->local_storage) {
st_free_table(th->local_storage);
@@ -465,6 +466,11 @@
return val;
}
+void *
+rb_thread_get_local_regs(void)
+{
+ return &GET_THREAD()->regs;
+}
/***************/
/* YarvEnv */
Modified: branches/parallel/yarvcore.h
===================================================================
--- branches/parallel/yarvcore.h 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/yarvcore.h 2006-09-02 13:52:32 UTC (rev 546)
@@ -16,6 +16,7 @@
#endif
#include "ruby.h"
#include "st.h"
+#include "re.h"
#include "debug.h"
#include "vm_opts.h"
@@ -318,6 +319,7 @@
struct yarv_thread_struct *running_thread;
struct yarv_thread_struct *lock_owner_thread;
+ int interrupt_gc_flag;
int num_wait_threads;
st_table *living_threads;
@@ -435,7 +437,6 @@
int exec_signal;
int interrupt_flag;
- int interrupt_gc_flag;
yarv_interrupt_function_t *interrupt_function;
yarv_thread_lock_t interrupt_lock;
@@ -468,6 +469,7 @@
/* misc */
int method_missing_reason;
int abort_on_exception;
+ struct re_registers regs;
} yarv_thread_t;
typedef struct native_global_lock_struct {
@@ -620,17 +622,32 @@
NOINLINE(void yarv_set_stack_end(VALUE **stack_end_p));
NOINLINE(void yarv_save_machine_context(yarv_thread_t *));
+
+
+
extern int rb_thread_pending;
void yarv_thread_execute_interrupts(yarv_thread_t *);
+void rb_thread_gc_barrier_stop(yarv_thread_t *th);
+void rb_thread_gc_barrier_start(yarv_thread_t *th);
+void rb_thread_gc_barrier_end(yarv_thread_t *th);
#define YARV_CHECK_INTS_TH(th) do { \
- if(th->interrupt_flag){ \
- /* TODO: trap something event */ \
- yarv_thread_execute_interrupts(th); \
- } \
+ if (th->interrupt_flag) { \
+ /* TODO: trap something event */ \
+ yarv_thread_execute_interrupts(th); \
+ } \
+ YARV_CHECK_GC_BARRIER(th); \
} while (0)
+#define YARV_CHECK_GC_BARRIER(th) do { \
+ if (th->vm->interrupt_gc_flag) { \
+ rb_thread_gc_barrier_stop(th); \
+ } \
+} while (0)
+
+
+
#define YARV_CHECK_INTS() \
YARV_CHECK_INTS_TH(GET_THREAD())
Modified: branches/parallel/yarvtest/test_thread.rb
===================================================================
--- branches/parallel/yarvtest/test_thread.rb 2006-09-01 13:06:17 UTC (rev 545)
+++ branches/parallel/yarvtest/test_thread.rb 2006-09-02 13:52:32 UTC (rev 546)
@@ -15,6 +15,33 @@
}
end
+ def test_thread_with_gc
+ ae %q{
+ flag = false
+ Thread.new{
+ flag = true
+ loop{''}
+ }
+ sleep 0.1 until flag
+ }
+ end
+
+ def test_threads_with_gc
+ ae %q{
+ GC.stress = true
+ (1..10).map{
+ Thread.new{
+ 100.times{|e|
+ "#{e}"
+ }
+ }
+ }.each{|t|
+ t.join
+ }
+ :ok
+ }
+ end
+
def test_create_many_threads1
ae %q{
v = 0
@@ -103,7 +130,7 @@
}
end
- def test_status
+ def _test_status
ae %q{
t = Thread.new{
loop{}
@@ -151,12 +178,13 @@
}
ae %q{
thg = ThreadGroup.new
-
+ flag = false
t = Thread.new{
thg.add Thread.current
+ flag = true
sleep
}
- sleep 0.1
+ sleep 0.1 until flag
[thg.list.size, ThreadGroup::Default.list.size]
}
end
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml