yarv-diff:386
From: ko1 atdot.net
Date: 5 Sep 2006 09:31:53 +0900
Subject: [yarv-diff:386] r553 - branches/parallel
Author: ko1
Date: 2006-09-05 09:31:52 +0900 (Tue, 05 Sep 2006)
New Revision: 553
Modified:
branches/parallel/ChangeLog
branches/parallel/eval.c
branches/parallel/gc.c
branches/parallel/st.c
branches/parallel/thread.c
branches/parallel/thread_pthread.h
branches/parallel/yarvcore.c
branches/parallel/yarvcore.h
Log:
* gc.c : protect free/malloc/realloc with fglock
* eval.c : add Init_gc_lock();
* st.c : fix function name
* thread.c : fix GC barrier algorithm
* yarvcore.h : add gc_lock to yarv_vm_t
* thread_pthread.h : make wrapper function and join timer thread at last
* yarvcore.c : fix to remove destroy some lock/condition
Modified: branches/parallel/ChangeLog
===================================================================
--- branches/parallel/ChangeLog 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/ChangeLog 2006-09-05 00:31:52 UTC (rev 553)
@@ -4,6 +4,23 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-09-05(Tue) 09:28:37 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * gc.c : protect free/malloc/realloc with fglock
+
+ * eval.c : add Init_gc_lock();
+
+ * st.c : fix function name
+
+ * thread.c : fix GC barrier algorithm
+
+ * yarvcore.h : add gc_lock to yarv_vm_t
+
+ * thread_pthread.h : make wrapper function and join timer thread at last
+
+ * yarvcore.c : fix to remove destroy some lock/condition
+
+
2006-09-04(Mon) 14:46:29 +0900 Koichi Sasada <ko1 atdot.net>
* thread_pthread.h : cleanup lock and condition variable at termination
Modified: branches/parallel/eval.c
===================================================================
--- branches/parallel/eval.c 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/eval.c 2006-09-05 00:31:52 UTC (rev 553)
@@ -109,6 +109,7 @@
#endif
Init_stack((void *)&state);
+ Init_gc_lock();
Init_yarv();
Init_heap();
@@ -213,7 +214,6 @@
ex = error_handle(ex);
ruby_finalize_1();
POP_THREAD_TAG();
- Cleanup_native_thread();
if (vm->exit_code) {
return vm->exit_code;
Modified: branches/parallel/gc.c
===================================================================
--- branches/parallel/gc.c 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/gc.c 2006-09-05 00:31:52 UTC (rev 553)
@@ -221,6 +221,20 @@
return bool;
}
+static yarv_thread_fglock_t g_mem_lock;
+
+void
+Init_gc_lock(void)
+{
+ native_fglock_init(&g_mem_lock);
+ if (native_fg_lock(&g_mem_lock) != 0) {
+ rb_bug("Init_gc_lock: native_fg_lock");
+ }
+ if (native_fg_unlock(&g_mem_lock) != 0) {
+ rb_bug("Init_gc_lock: native_fg_unlock");
+ }
+}
+
void *
ruby_xmalloc(size_t size)
{
@@ -235,10 +249,15 @@
if (gc_stress || malloc_increase > malloc_limit) {
garbage_collect();
}
- RUBY_CRITICAL(mem = malloc(size));
+
+ FGLOCK_RANGE(&g_mem_lock, {
+ mem = malloc(size);
+ });
if (!mem) {
if (garbage_collect()) {
- RUBY_CRITICAL(mem = malloc(size));
+ FGLOCK_RANGE(&g_mem_lock, {
+ mem = malloc(size);
+ });
}
if (!mem) {
rb_memerror();
@@ -273,7 +292,7 @@
ruby_xrealloc(void *ptr, size_t size)
{
void *mem;
-
+
if (size < 0) {
rb_raise(rb_eArgError, "negative re-allocation size");
}
@@ -281,14 +300,19 @@
if (size == 0) size = 1;
malloc_increase += size;
if (gc_stress) garbage_collect();
- RUBY_CRITICAL(mem = realloc(ptr, size));
+
+ FGLOCK_RANGE(&g_mem_lock, {
+ mem = realloc(ptr, size);
+ });
if (!mem) {
if (garbage_collect()) {
- RUBY_CRITICAL(mem = realloc(ptr, size));
+ FGLOCK_RANGE(&g_mem_lock, {
+ mem = realloc(ptr, size);
+ });
}
if (!mem) {
rb_memerror();
- }
+ }
}
return mem;
@@ -307,8 +331,9 @@
void
ruby_xfree(void *x)
{
- if (x)
- RUBY_CRITICAL(free(x));
+ if (x) {
+ FGLOCK_RANGE(&g_mem_lock, free(x));
+ }
}
@@ -1347,20 +1372,20 @@
garbage_collect(void)
{
yarv_thread_t *th = GET_THREAD();
- int r, locked = rb_thread_global_lock_acquire(th);
+ int r;
- rb_thread_gc_barrier_start(th);
- if (freelist == 0) {
- r = garbage_collect_thread_unsafe();
- }
- else {
- r = Qtrue;
- }
- rb_thread_gc_barrier_end(th);
-
- if (locked) {
- rb_thread_global_lock_release(th);
- }
+ GL_LOCK_RANGE(th, {
+ rb_thread_gc_barrier_start(th);
+ //fprintf(stderr, "gc: start\n");
+ if (freelist == 0 || gc_stress) {
+ r = garbage_collect_thread_unsafe();
+ }
+ else {
+ r = Qtrue;
+ }
+ //fprintf(stderr, "gc: end\n");
+ rb_thread_gc_barrier_end(th);
+ });
return r;
}
Modified: branches/parallel/st.c
===================================================================
--- branches/parallel/st.c 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/st.c 2006-09-05 00:31:52 UTC (rev 553)
@@ -244,7 +244,7 @@
}
}
free(table->bins);
- native_fg_destroy(&table->lock);
+ native_fglock_destroy(&table->lock);
free(table);
}
Modified: branches/parallel/thread.c
===================================================================
--- branches/parallel/thread.c 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/thread.c 2006-09-05 00:31:52 UTC (rev 553)
@@ -137,7 +137,14 @@
}
#endif
+static int profile_confilict;
+static void __attribute__((destructor))
+ pr_show(void)
+{
+ //printf("profile_confilict: %d\n", profile_confilict);
+}
+static int g_spinlock_count;
int
rb_thread_global_lock_acquire(yarv_thread_t *th)
@@ -154,9 +161,49 @@
else {
thread_debug("rb_thread_global_lock_acquire: try acquire (%p) --> \n",
vm->lock_owner_thread);
- native_mutex_lock(&vm->global_interpreter_lock);
+
+ if (native_mutex_trylock(&vm->global_interpreter_lock) == EBUSY) {
+ int i;
+ for (i=0; i<g_spinlock_count; i++) {
+ if (native_mutex_trylock(&vm->global_interpreter_lock) == 0) {
+ goto gotlock;
+ }
+ if (vm->interrupt_gc_flag) {
+ break;
+ }
+ native_thread_yield();
+ }
+
+ yarv_save_machine_context(th);
+
+ profile_confilict++;
+
+ native_mutex_lock(&vm->gc_lock);
+ {
+ vm->num_wait_threads++;
+ if (vm->interrupt_gc_flag) {
+ native_cond_signal(&vm->gc_barrier_owner_cond);
+ }
+ }
+ native_mutex_unlock(&vm->gc_lock);
+
+ native_mutex_lock(&vm->global_interpreter_lock);
+ thread_debug("rb_thread_global_lock_acquire: <-- done (lock)\n");
+
+ native_mutex_lock(&vm->gc_lock);
+ {
+ vm->num_wait_threads--;
+ if (vm->interrupt_gc_flag) {
+ rb_bug("...?");
+ }
+ }
+ native_mutex_unlock(&vm->gc_lock);
+ }
+ else {
+ gotlock:
+ thread_debug("rb_thread_global_lock_acquire: <-- done (trylock)\n");
+ }
vm->lock_owner_thread = th;
- thread_debug("rb_thread_global_lock_acquire: <-- done\n");
return 1;
}
}
@@ -189,19 +236,24 @@
{
yarv_vm_t *vm = GET_VM();
- 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_set_interrupt_function(th, func);
+ yarv_save_machine_context(th);
+
+ native_mutex_lock(&vm->gc_lock);
+ {
+ vm->num_wait_threads++;
+ if (vm->interrupt_gc_flag) {
+ native_cond_signal(&vm->gc_barrier_owner_cond);
+ }
}
-
- yarv_save_machine_context(th);
+ native_mutex_unlock(&vm->gc_lock);
+
rb_thread_global_lock_release(th);
return 1;
}
@@ -210,9 +262,15 @@
rb_thread_blocking_end(yarv_thread_t *th)
{
yarv_vm_t *vm = GET_VM();
+
+ native_mutex_lock(&vm->gc_lock);
+ {
+ vm->num_wait_threads--;
+ }
+ native_mutex_unlock(&vm->gc_lock);
+
+ yarv_clear_interrupt_function(th);
rb_thread_global_lock_acquire(th);
- yarv_clear_interrupt_function(th);
- vm->num_wait_threads--;
}
void
@@ -220,26 +278,26 @@
{
yarv_vm_t *vm = GET_VM();
int locked;
-
+
thread_debug("rb_thread_gc_barrier_stop: start\n");
+ yarv_save_machine_context(th);
- 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);
- {
- yarv_save_machine_context(th);
- 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;
+ GL_LOCK_RANGE(th, {
+ if (vm->interrupt_gc_flag) {
+ native_mutex_lock(&vm->gc_lock);
+ {
+ vm->num_wait_threads++;
+ thread_debug("rb_thread_gc_barrier_stop: waiting -> %d\n",
+ vm->num_wait_threads);
+ native_cond_signal(&vm->gc_barrier_owner_cond);
+ native_cond_wait(&vm->gc_barrier_waits_cond,
+ &vm->gc_lock);
+ vm->num_wait_threads--;
+ }
+ native_mutex_unlock(&vm->gc_lock);
+ }
+ });
- if (locked) {
- rb_thread_global_lock_release(th);
- }
thread_debug("rb_thread_gc_barrier_stop: end\n");
}
@@ -247,34 +305,32 @@
rb_thread_gc_barrier_start(yarv_thread_t *th)
{
yarv_vm_t *vm = GET_VM();
- yarv_thread_t *old_owner_th = vm->lock_owner_thread;
-
thread_debug("rb_thread_gc_barrier_start: start\n");
if (rb_thread_alone() || vm->living_threads == 0) {
/* skip */
}
else {
- while (vm->interrupt_gc_flag) {
- rb_thread_global_lock_release(th);
- rb_thread_gc_barrier_stop(th);
- rb_thread_global_lock_acquire(th);
+ native_mutex_lock(&vm->gc_lock);
+ {
+ if (vm->interrupt_gc_flag) {
+ rb_bug("other thread runnning GC");
+ }
+
+ vm->interrupt_gc_flag = 1;
+
+ 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);
+ native_cond_wait(&vm->gc_barrier_owner_cond,
+ &vm->gc_lock);
+ thread_debug("rb_thread_gc_barrier_start: block end - ltnum: %d, wtnum: %d\n",
+ vm->living_threads->num_entries, vm->num_wait_threads);
+ }
}
-
- vm->interrupt_gc_flag = 1;
- old_owner_th = vm->lock_owner_thread;
- 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("rb_thread_gc_barrier_start: block end - ltnum: %d, wtnum: %d\n",
- vm->living_threads->num_entries, vm->num_wait_threads);
- }
+ native_mutex_unlock(&vm->gc_lock);
}
- vm->lock_owner_thread = old_owner_th;
+ yarv_save_machine_context(th);
thread_debug("rb_thread_gc_barrier_start: end\n");
}
@@ -285,7 +341,8 @@
thread_debug("rb_thread_gc_barrier_end: start\n");
vm->interrupt_gc_flag = 0;
- pthread_cond_broadcast(&vm->gc_barrier_waits_cond);
+ native_cond_broadcast(&vm->gc_barrier_waits_cond);
+
thread_debug("rb_thread_gc_barrier_end: end\n");
}
@@ -322,7 +379,6 @@
native_mutex_unlock(&th->interrupt_lock);
}
-
static int
terminate_i(st_data_t key, st_data_t val, yarv_thread_t *main_thread)
{
@@ -351,7 +407,7 @@
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);
while (!rb_thread_alone()) {
@@ -362,11 +418,12 @@
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;
+ timer_thread_join();
+ rb_thread_global_lock_release(th);
}
@@ -380,7 +437,7 @@
th->machine_stack_start = th->machine_stack_end = 0;
if (th->vm->interrupt_gc_flag) {
- pthread_cond_signal(&th->vm->gc_barrier_owner_cond);
+ native_cond_signal(&th->vm->gc_barrier_owner_cond);
}
rb_thread_global_lock_release(th);
thread_debug("thread terminated: %p\n", th);
@@ -422,7 +479,6 @@
th->status = THREAD_KILLED;
thread_debug("thread end: %p\n", th);
- st_delete_wrap(th->vm->living_threads, th->self);
/* wake up joinning threads */
join_th = th->join_list_head;
@@ -430,6 +486,7 @@
rb_thread_interrupt(join_th);
join_th = join_th->join_list_next;
}
+ st_delete_wrap(th->vm->living_threads, th->self);
}
return 0;
}
@@ -698,9 +755,9 @@
YARV_CHECK_INTS();
#else
- rb_thread_global_lock_release(th);
+ rb_thread_blocking_start(th, 0);
native_thread_yield();
- rb_thread_global_lock_acquire(th);
+ rb_thread_blocking_end(th);
#endif
}
}
@@ -2193,10 +2250,11 @@
{
/* acquire global interpreter lock */
native_mutex_initialize(&GET_THREAD()->vm->global_interpreter_lock);
+ native_mutex_initialize(&GET_THREAD()->vm->gc_lock);
native_mutex_initialize(&GET_THREAD()->interrupt_lock);
- pthread_cond_init(&GET_VM()->gc_barrier_owner_cond, 0);
- pthread_cond_init(&GET_VM()->gc_barrier_waits_cond, 0);
+ native_cond_init(&GET_VM()->gc_barrier_owner_cond);
+ native_cond_init(&GET_VM()->gc_barrier_waits_cond);
}
}
@@ -2228,6 +2286,13 @@
}
}
#endif
+ if (getenv("RUBY_MAX_SPIN")) {
+ char *env = getenv("RUBY_MAX_SPIN");
+ g_spinlock_count = atoi(env);
+ }
+ else {
+ g_spinlock_count = 100;
+ }
rb_disable_interrupt(); /* only timer thread recieve signal */
}
Modified: branches/parallel/thread_pthread.h
===================================================================
--- branches/parallel/thread_pthread.h 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/thread_pthread.h 2006-09-05 00:31:52 UTC (rev 553)
@@ -10,10 +10,14 @@
void native_mutex_lock(yarv_thread_lock_t *lock);
void native_mutex_unlock(yarv_thread_lock_t *lock);
-#define native_mutex_trylock pthread_mutex_trylock
-#define native_mutex_destroy pthread_mutex_destroy
+void native_mutex_destroy(yarv_thread_lock_t *lock);
+int native_mutex_trylock(yarv_thread_lock_t *lock);
-#define native_cond_destroy pthread_cond_destroy
+void native_cond_init(yarv_thread_cond_t *cond);
+void native_cond_destroy(yarv_thread_cond_t *cond);
+void native_cond_signal(yarv_thread_cond_t *cond);
+void native_cond_broadcast(yarv_thread_cond_t *cond);
+void native_cond_wait(yarv_thread_cond_t *cond, yarv_thread_lock_t *lock);
typedef struct native_thread_data_struct {
void *signal_thread_list;
@@ -26,18 +30,19 @@
#define native_fg_lock pthread_spin_lock
#define native_fg_unlock pthread_spin_unlock
#define native_fg_trylock pthread_spin_trylock
-#define native_fg_init pthread_spin_init
-#define native_fg_destroy pthread_spin_destroy
+#define native_fg_init__ pthread_spin_init
+#define native_fg_destroy__ pthread_spin_destroy
#else
typedef pthread_mutex_t yarv_thread_fglock_t;
#define native_fg_lock pthread_mutex_lock
#define native_fg_unlock pthread_mutex_unlock
#define native_fg_trylock pthread_mutex_trylock
-#define native_fg_init pthread_mutex_init
-#define native_fg_destroy pthread_mutex_destroy
+#define native_fg_init__ pthread_mutex_init
+#define native_fg_destroy__ pthread_mutex_destroy
#endif
void native_fglock_init(yarv_thread_fglock_t *fglock);
+void native_fglock_destroy(yarv_thread_fglock_t *fglock);
#define FGLOCK(lock) native_fg_lock(lock)
#define FGUNLOCK(lock) native_fg_unlock(lock)
@@ -67,15 +72,18 @@
native_mutex_lock(yarv_thread_lock_t *lock)
{
int r;
- switch (r = pthread_mutex_trylock(lock)) {
- case EBUSY:
- if ((r = pthread_mutex_lock(lock)) != 0) {
+ r = pthread_mutex_trylock(lock);
+ if (r == EBUSY) {
+ r = pthread_mutex_lock(lock);
+
+ if (r != 0) {
rb_bug("pthread_mutex_lock: %d", r);
}
- break;
- case 0:
- break;
- default:
+ }
+ else if (r == 0) {
+ /* success */
+ }
+ else {
rb_bug("pthread_mutex_trylock: %d", r);
}
}
@@ -85,24 +93,103 @@
{
int r;
if ((r = pthread_mutex_unlock(lock)) != 0) {
- char *c=0; *c=0;
rb_bug("native_mutex_unlock return non-zero: %d", r);
}
}
+int
+native_mutex_trylock(yarv_thread_lock_t *lock)
+{
+ int r;
+ if ((r = pthread_mutex_trylock(lock)) != 0) {
+ if (r == EBUSY) {
+ return EBUSY;
+ }
+ else {
+ rb_bug("native_mutex_unlock return non-zero: %d", r);
+ }
+ }
+ return 0;
+}
+
void
native_mutex_initialize(pthread_mutex_t *lock)
{
- pthread_mutex_init(lock, 0);
+ if (pthread_mutex_init(lock, 0) != 0) {
+ rb_bug("native_mutex_initialize return non-zero");
+ }
}
void
native_fglock_init(yarv_thread_fglock_t *lock)
{
- native_fg_init(lock, 0);
+ if (native_fg_init__(lock, 0) != 0) {
+ rb_bug("native_fg_init__ return non-zero");
+ }
}
+void
+native_fglock_destroy(yarv_thread_fglock_t *lock)
+{
+ if (native_fg_destroy__(lock) != 0) {
+ rb_bug("native_fg_destroy__ return non-zero");
+ }
+ thread_debug("native_fglock_destroy: %p\n", lock);
+}
+
+void native_mutex_destroy(yarv_thread_lock_t *lock)
+{
+ int r = pthread_mutex_destroy(lock);
+ if (r != 0) {
+ fprintf(stderr, "pthread_mutex_destroy: %d\n", r);
+ rb_bug("pthread_mutex_destroy return non-zero: %d", r);
+ }
+ thread_debug("native_mutex_destroy: %p\n", lock);
+}
+
+void
+native_cond_init(yarv_thread_cond_t *cond)
+{
+ if (pthread_cond_init(cond, 0) != 0) {
+ rb_bug("pthread_cond_destroy return non-zero");
+ }
+}
+
+void
+native_cond_destroy(yarv_thread_cond_t *cond)
+{
+ if (pthread_cond_destroy(cond) != 0) {
+ rb_bug("pthread_cond_destroy return non-zero");
+ }
+}
+
+void
+native_cond_signal(yarv_thread_cond_t *cond)
+{
+ if (pthread_cond_signal(cond) != 0) {
+ rb_bug("pthread_cond_signal return non-zero");
+ }
+}
+
+void
+native_cond_broadcast(yarv_thread_cond_t *cond)
+{
+ if (pthread_cond_broadcast(cond) != 0) {
+ rb_bug("pthread_cond_signal return non-zero");
+ }
+}
+
+void
+native_cond_wait(yarv_thread_cond_t *cond,
+ yarv_thread_lock_t *lock)
+{
+ if (pthread_cond_wait(cond, lock) != 0) {
+ rb_bug("pthread_cond_wait return non-zero");
+ }
+}
+
+
#define native_cleanup_push pthread_cleanup_push
#define native_cleanup_pop pthread_cleanup_pop
#define native_thread_yield() sched_yield()
@@ -129,12 +216,6 @@
posix_signal(SIGVTALRM, null_func);
}
-void
-Cleanup_native_thread(void)
-{
- native_fglock_init(&signal_thread_list_lock);
-}
-
NOINLINE(static int
thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
void static thread_cleanup_func(void *th_ptr);
@@ -232,7 +313,9 @@
}
free(entry);
- pthread_cond_destroy(&cond);
+ if (pthread_cond_destroy(&cond) != 0) {
+ rb_bug("pthread_cond_destroy return non-zero");
+ }
}
pthread_mutex_unlock(&thread_cache_lock);
@@ -373,8 +456,10 @@
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);
+ if (pthread_cond_wait(&th->native_thread_data.sleep_cond,
+ &th->interrupt_lock) != 0) {
+ rb_bug("pthread_cond_wait return non-zero");
+ }
thread_debug("native_sleep: pthread_cond_wait end\n");
}
else {
@@ -503,11 +588,20 @@
}
timer_function();
}
+ native_fglock_destroy(&signal_thread_list_lock);
+
+ if (signal_thread_list_anchor.next) {
+ fprintf(stderr, "thread_timer: remain signal_thread_list_anchor.next\n");
+ exit(1);
+ }
+ else {
+ thread_debug("thread_timer: terminate\n");
+ }
return NULL;
}
static void
-make_timer_thread()
+make_timer_thread(void)
{
if (!time_thread) {
size_t stack_size = PTHREAD_STACK_MIN * 2;
@@ -515,9 +609,20 @@
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, stack_size);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_create(&time_thread, &attr, thread_timer, 0);
+ if (pthread_create(&time_thread, &attr, thread_timer, 0) != 0) {
+ rb_bug("make_timer_thread: unable create timer thread");
+ }
}
}
+static void
+timer_thread_join(void)
+{
+ thread_debug("timer_thread_join: start\n");
+ if (pthread_join(time_thread, 0) != 0) {
+ rb_bug("timer_thread_join: error");
+ }
+ thread_debug("timer_thread_join: done\n");
+}
+
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
Modified: branches/parallel/yarvcore.c
===================================================================
--- branches/parallel/yarvcore.c 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/yarvcore.c 2006-09-05 00:31:52 UTC (rev 553)
@@ -226,16 +226,17 @@
FREE_REPORT_ENTER("vm");
if (ptr) {
yarv_vm_t *vm = ptr;
-
st_free_table(vm->living_threads);
- // TODO: MultiVM Instance
- // VM object should not be cleaned by GC
- // ruby_xfree(ptr);
- // theYarvVM = 0;
- native_mutex_destroy(&vm->global_interpreter_lock);
+ //native_mutex_destroy(&vm->global_interpreter_lock);
+ //native_mutex_destroy(&vm->gc_lock);
native_cond_destroy(&vm->gc_barrier_owner_cond);
native_cond_destroy(&vm->gc_barrier_waits_cond);
+
+ // TODO: MultiVM Instance
+ // VM object should not be cleaned by GC
+ //ruby_xfree(ptr);
+ //theYarvVM = 0;
}
FREE_REPORT_LEAVE("vm");
}
@@ -304,7 +305,10 @@
st_free_table(th->local_storage);
}
- native_mutex_destroy(&th->interrupt_lock);
+ if (th->vm->main_thread != th) {
+ /* for other finilizer */
+ native_mutex_destroy(&th->interrupt_lock);
+ }
#if USE_VALUE_CACHE
{
@@ -364,6 +368,14 @@
rb_mark_tbl(th->local_storage);
+ {
+ yarv_thread_t *join_th = th->join_list_head;
+ while (join_th) {
+ rb_gc_mark(join_th->self);
+ join_th = join_th->join_list_next;
+ }
+ }
+
if (GET_THREAD() != th &&
th->machine_stack_start && th->machine_stack_end) {
yarv_machine_stack_mark(th);
@@ -1008,6 +1020,7 @@
vm->main_thread = th;
vm->running_thread = th;
+
GET_THREAD()->vm = vm;
thread_free(GET_THREAD());
th->vm = vm;
Modified: branches/parallel/yarvcore.h
===================================================================
--- branches/parallel/yarvcore.h 2006-09-04 05:54:33 UTC (rev 552)
+++ branches/parallel/yarvcore.h 2006-09-05 00:31:52 UTC (rev 553)
@@ -312,6 +312,7 @@
VALUE self;
yarv_thread_lock_t global_interpreter_lock;
+ yarv_thread_lock_t gc_lock;
yarv_thread_cond_t gc_barrier_owner_cond;
yarv_thread_cond_t gc_barrier_waits_cond;
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml