[前][次][番号順一覧][スレッド一覧][生データ]

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

[前][次][番号順一覧][スレッド一覧][生データ]