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

yarv-diff:410

From: ko1 atdot.net
Date: 9 Nov 2006 10:27:14 +0900
Subject: [yarv-diff:410] r578 - trunk

Author: ko1
Date: 2006-11-09 10:27:13 +0900 (Thu, 09 Nov 2006)
New Revision: 578

Added:
   trunk/call_cfunc.ci
   trunk/thread_pthread.ci
   trunk/thread_win32.ci
   trunk/vm_evalbody.ci
Removed:
   trunk/call_cfunc.h
   trunk/vm_evalbody.h
Modified:
   trunk/ChangeLog
   trunk/common.mk
   trunk/thread.c
   trunk/thread_pthread.h
   trunk/thread_win32.h
   trunk/vm.c
Log:
	* call_cfunc.h -> call_cfunc.ci : renamed

	* vm_evalbody.h, vm_evalbody.ci : ditto

	* thread_pthread.h, thread_pthread.ci : separate declaration and
	implementation

	* thread_win32.h, thread_win32.ci : ditto

	* thread.c : use *.ci instead of *.c as implementation

	* vm.c : ditto

	* common.mk : fix rules for above changes



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/ChangeLog	2006-11-09 01:27:13 UTC (rev 578)
@@ -4,6 +4,24 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-11-09(Thu) 10:22:59 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* call_cfunc.h -> call_cfunc.ci : renamed
+
+	* vm_evalbody.h, vm_evalbody.ci : ditto
+
+	* thread_pthread.h, thread_pthread.ci : separate declaration and
+	implementation
+
+	* thread_win32.h, thread_win32.ci : ditto
+
+	* thread.c : use *.ci instead of *.c as implementation
+
+	* vm.c : ditto
+
+	* common.mk : fix rules for above changes
+
+
 2006-11-08(Wed) 17:23:23 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* vm_dump.c : show C level backtrace (pointer only) with

Copied: trunk/call_cfunc.ci (from rev 574, trunk/call_cfunc.h)

Deleted: trunk/call_cfunc.h
===================================================================
--- trunk/call_cfunc.h	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/call_cfunc.h	2006-11-09 01:27:13 UTC (rev 578)
@@ -1,94 +0,0 @@
-/* -*-c-*- */
-
-/* from ruby1.9/eval.c */
-
-static inline VALUE
-call_cfunc(func, recv, len, argc, argv)
-    VALUE (*func) ();
-    VALUE recv;
-    int len, argc;
-    const VALUE *argv;
-{
-    // printf("len: %d, argc: %d\n", len, argc);
-
-    if (len >= 0 && argc != len) {
-	rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
-		 argc, len);
-    }
-
-    switch (len) {
-    case -2:
-	return (*func) (recv, rb_ary_new4(argc, argv));
-	break;
-    case -1:
-	return (*func) (argc, argv, recv);
-	break;
-    case 0:
-	return (*func) (recv);
-	break;
-    case 1:
-	return (*func) (recv, argv[0]);
-	break;
-    case 2:
-	return (*func) (recv, argv[0], argv[1]);
-	break;
-    case 3:
-	return (*func) (recv, argv[0], argv[1], argv[2]);
-	break;
-    case 4:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3]);
-	break;
-    case 5:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
-	break;
-    case 6:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5]);
-	break;
-    case 7:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6]);
-	break;
-    case 8:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7]);
-	break;
-    case 9:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8]);
-	break;
-    case 10:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9]);
-	break;
-    case 11:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9],
-			argv[10]);
-	break;
-    case 12:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9],
-			argv[10], argv[11]);
-	break;
-    case 13:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-			argv[11], argv[12]);
-	break;
-    case 14:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-			argv[11], argv[12], argv[13]);
-	break;
-    case 15:
-	return (*func) (recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-			argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-			argv[11], argv[12], argv[13], argv[14]);
-	break;
-    default:
-	rb_raise(rb_eArgError, "too many arguments(%d)", len);
-	break;
-    }
-    return Qnil;		/* not reached */
-}

Modified: trunk/common.mk
===================================================================
--- trunk/common.mk	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/common.mk	2006-11-09 01:27:13 UTC (rev 578)
@@ -274,7 +274,9 @@
   {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
 
 thread.$(OBJEXT): {$(VPATH)}thread.c  {$(VPATH)}eval_intern.h \
-  {$(VPATH)}thread_win32.h {$(VPATH)}thread_pthread.h {$(VPATH)}ruby.h config.h \
+  {$(VPATH)}thread_win32.h {$(VPATH)}thread_pthread.h \
+  {$(VPATH)}thread_win32.ci {$(VPATH)}thread_pthread.ci \
+  {$(VPATH)}ruby.h config.h \
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}node.h {$(VPATH)}util.h \
   {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h \
@@ -372,7 +374,8 @@
         insns.inc insns_info.inc optinsn.inc opt_sc.inc optunifs.inc vm_opts.h
 iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}yarvcore.h {$(VPATH)}debug.h vm_opts.h
 vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}insnhelper.h \
-        {$(VPATH)}yarvcore.h {$(VPATH)}debug.h {$(VPATH)}vm_evalbody.h \
+        {$(VPATH)}yarvcore.h {$(VPATH)}debug.h \
+        {$(VPATH)}vm_evalbody.ci {$(VPATH)}call_cfunc.ci \
         insns.inc vm.inc vmtc.inc vm_macro.inc vm_opts.h {$(VPATH)}eval_intern.h
 vm_dump.$(OBJEXT): {$(VPATH)}yarvcore.h {$(VPATH)}vm.h
 yarvcore.$(OBJEXT): {$(VPATH)}yarvcore.c {$(VPATH)}yarvcore.h \

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/thread.c	2006-11-09 01:27:13 UTC (rev 578)
@@ -98,7 +98,7 @@
 #endif
 
 #if   defined(_WIN32) || defined(__CYGWIN__)
-#include "thread_win32.h"
+#include "thread_win32.ci"
 
 #define DEBUG_OUT() \
   WaitForSingleObject(&debug_mutex, INFINITE); \
@@ -106,7 +106,7 @@
   ReleaseMutex(&debug_mutex);
 
 #elif defined(HAVE_PTHREAD_H)
-#include "thread_pthread.h"
+#include "thread_pthread.ci"
 
 #define DEBUG_OUT() \
   pthread_mutex_lock(&debug_mutex); \

Added: trunk/thread_pthread.ci
===================================================================
--- trunk/thread_pthread.ci	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/thread_pthread.ci	2006-11-09 01:27:13 UTC (rev 578)
@@ -0,0 +1,419 @@
+/* -*-c-*- */
+
+#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
+
+#define native_mutex_initialize(lock) do { \
+  pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; \
+  ((*lock) = _lock); \
+} while (0)
+
+#define native_cleanup_push pthread_cleanup_push
+#define native_cleanup_pop  pthread_cleanup_pop
+#define native_thread_yield() sched_yield()
+
+static void yarv_add_signal_thread_list(yarv_thread_t *th);
+static void yarv_remove_signal_thread_list(yarv_thread_t *th);
+
+static yarv_thread_lock_t signal_thread_list_lock;
+
+static void
+null_func()
+{
+}
+
+static void
+Init_native_thread()
+{
+    GET_THREAD()->thread_id = pthread_self();
+    native_mutex_initialize(&signal_thread_list_lock);
+    posix_signal(SIGVTALRM, null_func);
+}
+
+NOINLINE(static int
+	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
+void static thread_cleanup_func(void *th_ptr);
+
+static yarv_thread_t *register_cached_thread_and_wait(void);
+
+#define USE_THREAD_CACHE 0
+
+static void *
+thread_start_func_1(void *th_ptr)
+{
+#if USE_THREAD_CACHE
+  thread_start:
+#endif
+    {
+	yarv_thread_t *th = th_ptr;
+	VALUE stack_start;
+	/* ignore self and klass */
+
+	native_cleanup_push(thread_cleanup_func, th);
+
+	/* run */
+	thread_start_func_2(th, &stack_start);
+
+	/* cleanup */
+	thread_cleanup_func(th);
+	native_cleanup_pop(0);
+    }
+#if USE_THREAD_CACHE
+    if (1) {
+	/* cache thread */
+	yarv_thread_t *th;
+	if ((th = register_cached_thread_and_wait()) != 0) {
+	    th_ptr = (void *)th;
+	    th->thread_id = pthread_self();
+	    goto thread_start;
+	}
+    }
+#endif
+    return 0;
+}
+
+static void make_timer_thread();
+
+static pthread_mutex_t thread_cache_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct cached_thread_entry {
+    volatile yarv_thread_t **th_area;
+    pthread_cond_t *cond;
+    struct cached_thread_entry *next;
+};
+
+struct cached_thread_entry *cached_thread_root;
+
+static yarv_thread_t *
+register_cached_thread_and_wait(void)
+{
+    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+    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;
+    
+    pthread_mutex_lock(&thread_cache_lock);
+    {
+	entry->th_area = &th_area;
+	entry->cond = &cond;
+	entry->next = cached_thread_root;
+	cached_thread_root = entry;
+
+	pthread_cond_timedwait(&cond, &thread_cache_lock, &ts);
+
+	{
+	    struct cached_thread_entry *e = cached_thread_root;
+	    struct cached_thread_entry *prev = cached_thread_root;
+
+	    while (e) {
+		if (e == entry) {
+		    if (prev == cached_thread_root) {
+			cached_thread_root = e->next;
+		    }
+		    else {
+			prev->next = e->next;
+		    }
+		    break;
+		}
+		prev = e;
+		e = e->next;
+	    }
+	}
+
+	free(entry);
+	pthread_cond_destroy(&cond);
+    }
+    pthread_mutex_unlock(&thread_cache_lock);
+
+    return (yarv_thread_t *)th_area;
+}
+
+static int
+use_cached_thread(yarv_thread_t *th)
+{
+    int result = 0;
+#if USE_THREAD_CACHE
+    struct cached_thread_entry *entry;
+
+    if (cached_thread_root) {
+	pthread_mutex_lock(&thread_cache_lock);
+	entry = cached_thread_root;
+	{
+	    if (cached_thread_root) {
+		cached_thread_root = entry->next;
+		*entry->th_area = th;
+		result = 1;
+	    }
+	}
+	if (result) {
+	    pthread_cond_signal(entry->cond);
+	}
+	pthread_mutex_unlock(&thread_cache_lock);
+    }
+#endif
+    return result;
+}
+
+static int
+native_thread_create(yarv_thread_t *th)
+{
+    int err = 0;
+
+    if (use_cached_thread(th)) {
+	thread_debug("create (use cahced thread): %p\n", th);
+    }
+    else {
+	pthread_attr_t attr;
+	size_t stack_size = 512 * 1024 - sizeof(int);	/* 512KB */
+
+	if (stack_size < PTHREAD_STACK_MIN) {
+	    stack_size = PTHREAD_STACK_MIN * 2;
+	}
+	
+	thread_debug("create: %p, stack size: %ld\n", th, stack_size);
+
+	pthread_attr_init(&attr);
+	pthread_attr_setstacksize(&attr, stack_size);
+	pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+	err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
+
+	if (err != 0) {
+	    th->status = THREAD_KILLED;
+	    rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
+	}
+    }
+    return err;
+}
+
+static void
+native_thread_apply_priority(yarv_thread_t *th)
+{
+    struct sched_param sp;
+    int policy;
+    int priority = 0 - th->priority;
+    int max, min;
+    pthread_getschedparam(th->thread_id, &policy, &sp);
+    max = sched_get_priority_max(policy);
+    min = sched_get_priority_min(policy);
+
+    if (min < priority) {
+	priority = max;
+    }
+    else if (max > priority) {
+	priority = min;
+    }
+
+    sp.sched_priority = priority;
+    pthread_setschedparam(th->thread_id, policy, &sp);
+}
+
+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);
+    if (th) {
+	pthread_kill(th->thread_id, SIGVTALRM);
+    }
+}
+
+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);
+
+    thread_debug("native_sleep %d\n", tv ? tv->tv_sec : -1);
+    GVL_UNLOCK_BEGIN();
+    {
+	pthread_mutex_lock(&th->interrupt_lock);
+	
+	if (th->interrupt_flag) {
+	    /* interrupted.  return immediate */
+	    thread_debug("native_sleep: interrupted before sleep\n");
+	}
+	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();
+    thread_debug("native_sleep done\n");
+}
+
+void
+native_thread_interrupt(yarv_thread_t *th)
+{
+    yarv_add_signal_thread_list(th);
+}
+
+struct yarv_signal_thread_list {
+    yarv_thread_t *th;
+    struct yarv_signal_thread_list *prev;
+    struct yarv_signal_thread_list *next;
+};
+
+static struct yarv_signal_thread_list signal_thread_list_anchor = {
+    0, 0, 0,
+};
+
+#define FGLOCK(lock, body) do { \
+    native_mutex_lock(lock); \
+    { \
+	body; \
+    } \
+    native_mutex_unlock(lock); \
+} while (0)
+
+static void
+print_signal_list(char *str)
+{
+    struct yarv_signal_thread_list *list =
+      signal_thread_list_anchor.next;
+    thread_debug("list (%s)> ", str);
+    while(list){
+	thread_debug("%p (%p), ", list->th, list->th->thread_id);
+	list = list->next;
+    }
+    thread_debug("\n");
+}
+
+static void
+yarv_add_signal_thread_list(yarv_thread_t *th)
+{
+    if (!th->native_thread_data.signal_thread_list) {
+	FGLOCK(&signal_thread_list_lock, {
+	    struct yarv_signal_thread_list *list =
+	      malloc(sizeof(struct yarv_signal_thread_list));
+
+	    if (list == 0) {
+		fprintf(stderr, "[FATAL] failed to allocate memory\n");
+		exit(1);
+	    }
+
+	    list->th = th;
+
+	    list->prev = &signal_thread_list_anchor;
+	    list->next = signal_thread_list_anchor.next;
+	    if (list->next) {
+		list->next->prev = list;
+	    }
+	    signal_thread_list_anchor.next = list;
+	    th->native_thread_data.signal_thread_list = list;
+	});
+    }
+}
+
+static void
+yarv_remove_signal_thread_list(yarv_thread_t *th)
+{
+    if (th->native_thread_data.signal_thread_list) {
+	FGLOCK(&signal_thread_list_lock, {
+	    struct yarv_signal_thread_list *list =
+	      (struct yarv_signal_thread_list *)
+		th->native_thread_data.signal_thread_list;
+
+	    list->prev->next = list->next;
+	    if (list->next) {
+		list->next->prev = list->prev;
+	    }
+	    th->native_thread_data.signal_thread_list = 0;
+	    list->th = 0;
+	    free(list);
+	});
+    }
+    else {
+	/* */
+    }
+}
+
+static pthread_t time_thread;
+
+static void timer_function(void);
+
+static void *
+thread_timer(void *dummy)
+{
+    while (system_working) {
+#ifdef HAVE_NANOSLEEP
+	struct timespec req, rem;
+	req.tv_sec = 0;
+	req.tv_nsec = 10 * 1000 * 1000;	/* 10 ms */
+	nanosleep(&req, &rem);
+#else
+	struct timeval tv;
+	tv.tv_sec = 0;
+	tv.tv_usec = 10000;     	/* 10 ms */
+	select(0, NULL, NULL, NULL, &tv);
+#endif
+	
+	if (signal_thread_list_anchor.next) {
+	    FGLOCK(&signal_thread_list_lock, {
+		struct yarv_signal_thread_list *list;
+		list = signal_thread_list_anchor.next;
+		while (list) {
+		    native_thread_send_interrupt_signal(list->th);
+		    list = list->next;
+		}
+	    });
+	}
+	timer_function();
+    }
+    return NULL;
+}
+
+static void
+make_timer_thread()
+{
+    if (!time_thread) {
+	size_t stack_size = PTHREAD_STACK_MIN;
+	pthread_attr_t attr;
+	
+	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);
+    }
+}
+
+#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/thread_pthread.h	2006-11-09 01:27:13 UTC (rev 578)
@@ -16,424 +16,3 @@
 } native_thread_data_t;
 
 #endif /* THREAD_PTHREAD_H_INCLUDED */
-
-
-/**********************************************************************/
-
-#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
-
-#define native_mutex_initialize(lock) do { \
-  pthread_mutex_t _lock = PTHREAD_MUTEX_INITIALIZER; \
-  ((*lock) = _lock); \
-} while (0)
-
-#define native_cleanup_push pthread_cleanup_push
-#define native_cleanup_pop  pthread_cleanup_pop
-#define native_thread_yield() sched_yield()
-
-static void yarv_add_signal_thread_list(yarv_thread_t *th);
-static void yarv_remove_signal_thread_list(yarv_thread_t *th);
-
-static yarv_thread_lock_t signal_thread_list_lock;
-
-static void
-null_func()
-{
-}
-
-static void
-Init_native_thread()
-{
-    GET_THREAD()->thread_id = pthread_self();
-    native_mutex_initialize(&signal_thread_list_lock);
-    posix_signal(SIGVTALRM, null_func);
-}
-
-NOINLINE(static int
-	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
-void static thread_cleanup_func(void *th_ptr);
-
-static yarv_thread_t *register_cached_thread_and_wait(void);
-
-#define USE_THREAD_CACHE 0
-
-static void *
-thread_start_func_1(void *th_ptr)
-{
-#if USE_THREAD_CACHE
-  thread_start:
-#endif
-    {
-	yarv_thread_t *th = th_ptr;
-	VALUE stack_start;
-	/* ignore self and klass */
-
-	native_cleanup_push(thread_cleanup_func, th);
-
-	/* run */
-	thread_start_func_2(th, &stack_start);
-
-	/* cleanup */
-	thread_cleanup_func(th);
-	native_cleanup_pop(0);
-    }
-#if USE_THREAD_CACHE
-    if (1) {
-	/* cache thread */
-	yarv_thread_t *th;
-	if ((th = register_cached_thread_and_wait()) != 0) {
-	    th_ptr = (void *)th;
-	    th->thread_id = pthread_self();
-	    goto thread_start;
-	}
-    }
-#endif
-    return 0;
-}
-
-static void make_timer_thread();
-
-static pthread_mutex_t thread_cache_lock = PTHREAD_MUTEX_INITIALIZER;
-
-struct cached_thread_entry {
-    volatile yarv_thread_t **th_area;
-    pthread_cond_t *cond;
-    struct cached_thread_entry *next;
-};
-
-struct cached_thread_entry *cached_thread_root;
-
-static yarv_thread_t *
-register_cached_thread_and_wait(void)
-{
-    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
-    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;
-    
-    pthread_mutex_lock(&thread_cache_lock);
-    {
-	entry->th_area = &th_area;
-	entry->cond = &cond;
-	entry->next = cached_thread_root;
-	cached_thread_root = entry;
-
-	pthread_cond_timedwait(&cond, &thread_cache_lock, &ts);
-
-	{
-	    struct cached_thread_entry *e = cached_thread_root;
-	    struct cached_thread_entry *prev = cached_thread_root;
-
-	    while (e) {
-		if (e == entry) {
-		    if (prev == cached_thread_root) {
-			cached_thread_root = e->next;
-		    }
-		    else {
-			prev->next = e->next;
-		    }
-		    break;
-		}
-		prev = e;
-		e = e->next;
-	    }
-	}
-
-	free(entry);
-	pthread_cond_destroy(&cond);
-    }
-    pthread_mutex_unlock(&thread_cache_lock);
-
-    return (yarv_thread_t *)th_area;
-}
-
-static int
-use_cached_thread(yarv_thread_t *th)
-{
-    int result = 0;
-#if USE_THREAD_CACHE
-    struct cached_thread_entry *entry;
-
-    if (cached_thread_root) {
-	pthread_mutex_lock(&thread_cache_lock);
-	entry = cached_thread_root;
-	{
-	    if (cached_thread_root) {
-		cached_thread_root = entry->next;
-		*entry->th_area = th;
-		result = 1;
-	    }
-	}
-	if (result) {
-	    pthread_cond_signal(entry->cond);
-	}
-	pthread_mutex_unlock(&thread_cache_lock);
-    }
-#endif
-    return result;
-}
-
-static int
-native_thread_create(yarv_thread_t *th)
-{
-    int err = 0;
-
-    if (use_cached_thread(th)) {
-	thread_debug("create (use cahced thread): %p\n", th);
-    }
-    else {
-	pthread_attr_t attr;
-	size_t stack_size = 512 * 1024 - sizeof(int);	/* 512KB */
-
-	if (stack_size < PTHREAD_STACK_MIN) {
-	    stack_size = PTHREAD_STACK_MIN * 2;
-	}
-	
-	thread_debug("create: %p, stack size: %ld\n", th, stack_size);
-
-	pthread_attr_init(&attr);
-	pthread_attr_setstacksize(&attr, stack_size);
-	pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
-	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-	err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
-
-	if (err != 0) {
-	    th->status = THREAD_KILLED;
-	    rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
-	}
-    }
-    return err;
-}
-
-static void
-native_thread_apply_priority(yarv_thread_t *th)
-{
-    struct sched_param sp;
-    int policy;
-    int priority = 0 - th->priority;
-    int max, min;
-    pthread_getschedparam(th->thread_id, &policy, &sp);
-    max = sched_get_priority_max(policy);
-    min = sched_get_priority_min(policy);
-
-    if (min < priority) {
-	priority = max;
-    }
-    else if (max > priority) {
-	priority = min;
-    }
-
-    sp.sched_priority = priority;
-    pthread_setschedparam(th->thread_id, policy, &sp);
-}
-
-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);
-    if (th) {
-	pthread_kill(th->thread_id, SIGVTALRM);
-    }
-}
-
-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);
-
-    thread_debug("native_sleep %d\n", tv ? tv->tv_sec : -1);
-    GVL_UNLOCK_BEGIN();
-    {
-	pthread_mutex_lock(&th->interrupt_lock);
-	
-	if (th->interrupt_flag) {
-	    /* interrupted.  return immediate */
-	    thread_debug("native_sleep: interrupted before sleep\n");
-	}
-	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();
-    thread_debug("native_sleep done\n");
-}
-
-void
-native_thread_interrupt(yarv_thread_t *th)
-{
-    yarv_add_signal_thread_list(th);
-}
-
-struct yarv_signal_thread_list {
-    yarv_thread_t *th;
-    struct yarv_signal_thread_list *prev;
-    struct yarv_signal_thread_list *next;
-};
-
-static struct yarv_signal_thread_list signal_thread_list_anchor = {
-    0, 0, 0,
-};
-
-#define FGLOCK(lock, body) do { \
-    native_mutex_lock(lock); \
-    { \
-	body; \
-    } \
-    native_mutex_unlock(lock); \
-} while (0)
-
-static void
-print_signal_list(char *str)
-{
-    struct yarv_signal_thread_list *list =
-      signal_thread_list_anchor.next;
-    thread_debug("list (%s)> ", str);
-    while(list){
-	thread_debug("%p (%p), ", list->th, list->th->thread_id);
-	list = list->next;
-    }
-    thread_debug("\n");
-}
-
-static void
-yarv_add_signal_thread_list(yarv_thread_t *th)
-{
-    if (!th->native_thread_data.signal_thread_list) {
-	FGLOCK(&signal_thread_list_lock, {
-	    struct yarv_signal_thread_list *list =
-	      malloc(sizeof(struct yarv_signal_thread_list));
-
-	    if (list == 0) {
-		fprintf(stderr, "[FATAL] failed to allocate memory\n");
-		exit(1);
-	    }
-
-	    list->th = th;
-
-	    list->prev = &signal_thread_list_anchor;
-	    list->next = signal_thread_list_anchor.next;
-	    if (list->next) {
-		list->next->prev = list;
-	    }
-	    signal_thread_list_anchor.next = list;
-	    th->native_thread_data.signal_thread_list = list;
-	});
-    }
-}
-
-static void
-yarv_remove_signal_thread_list(yarv_thread_t *th)
-{
-    if (th->native_thread_data.signal_thread_list) {
-	FGLOCK(&signal_thread_list_lock, {
-	    struct yarv_signal_thread_list *list =
-	      (struct yarv_signal_thread_list *)
-		th->native_thread_data.signal_thread_list;
-
-	    list->prev->next = list->next;
-	    if (list->next) {
-		list->next->prev = list->prev;
-	    }
-	    th->native_thread_data.signal_thread_list = 0;
-	    list->th = 0;
-	    free(list);
-	});
-    }
-    else {
-	/* */
-    }
-}
-
-static pthread_t time_thread;
-
-static void timer_function(void);
-
-static void *
-thread_timer(void *dummy)
-{
-    while (system_working) {
-#ifdef HAVE_NANOSLEEP
-	struct timespec req, rem;
-	req.tv_sec = 0;
-	req.tv_nsec = 10 * 1000 * 1000;	/* 10 ms */
-	nanosleep(&req, &rem);
-#else
-	struct timeval tv;
-	tv.tv_sec = 0;
-	tv.tv_usec = 10000;     	/* 10 ms */
-	select(0, NULL, NULL, NULL, &tv);
-#endif
-	
-	if (signal_thread_list_anchor.next) {
-	    FGLOCK(&signal_thread_list_lock, {
-		struct yarv_signal_thread_list *list;
-		list = signal_thread_list_anchor.next;
-		while (list) {
-		    native_thread_send_interrupt_signal(list->th);
-		    list = list->next;
-		}
-	    });
-	}
-	timer_function();
-    }
-    return NULL;
-}
-
-static void
-make_timer_thread()
-{
-    if (!time_thread) {
-	size_t stack_size = PTHREAD_STACK_MIN;
-	pthread_attr_t attr;
-	
-	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);
-    }
-}
-
-#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */

Added: trunk/thread_win32.ci
===================================================================
--- trunk/thread_win32.ci	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/thread_win32.ci	2006-11-09 01:27:13 UTC (rev 578)
@@ -0,0 +1,300 @@
+/* -*-c-*- */
+
+#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
+
+#include <process.h>
+
+#define WIN32_WAIT_TIMEOUT 10	/* 10 ms */
+#undef Sleep
+
+#define native_thread_yield() Sleep(0)
+#define yarv_remove_signal_thread_list(th)
+
+static void
+Init_native_thread()
+{
+    yarv_thread_t *th = GET_THREAD();
+    DuplicateHandle(GetCurrentProcess(),
+		    GetCurrentThread(),
+		    GetCurrentProcess(),
+		    &th->thread_id, 0, FALSE, DUPLICATE_SAME_ACCESS);
+
+    th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
+
+    thread_debug("initial thread (th: %p, thid: %p, event: %p)\n",
+		 th, GET_THREAD()->thread_id,
+		 th->native_thread_data.interrupt_event);
+}
+
+static void
+w32_show_error_message()
+{
+    LPVOID lpMsgBuf;
+    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+		  FORMAT_MESSAGE_FROM_SYSTEM |
+		  FORMAT_MESSAGE_IGNORE_INSERTS,
+		  NULL,
+		  GetLastError(),
+		  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		  (LPTSTR) & lpMsgBuf, 0, NULL);
+    // {int *a=0; *a=0;}
+    MessageBox(NULL, (LPCTSTR) lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
+    //  exit(1);
+}
+
+static int
+w32_wait_event(HANDLE event, DWORD timeout, yarv_thread_t *th)
+{
+    HANDLE events[2];
+    int count = 0;
+    DWORD ret;
+
+    if (event) {
+	events[count++] = event;
+	thread_debug("  * handle: %p (count: %d)\n", event, count);
+    }
+
+    if (th) {
+	HANDLE intr = th->native_thread_data.interrupt_event;
+	ResetEvent(intr);
+	if (th->interrupt_flag) {
+	    SetEvent(intr);
+	}
+
+	events[count++] = intr;
+	thread_debug("  * handle: %p (count: %d, intr)\n", intr, count);
+    }
+
+    thread_debug("  WaitForMultipleObjects start (count: %d)\n", count);
+    ret = WaitForMultipleObjects(count, events, FALSE, timeout);
+    thread_debug("  WaitForMultipleObjects end (ret: %d)\n", ret);
+
+    if (ret == WAIT_OBJECT_0 + count - 1 && th) {
+	errno = EINTR;
+    }
+    if (ret == -1 && THREAD_DEBUG) {
+	int i;
+	DWORD dmy;
+	for (i = 0; i < count; i++) {
+	    thread_debug("  * error handle %d - %s\n", i,
+			 GetHandleInformation(events[i], &dmy) ? "OK" : "NG");
+	}
+    }
+    return ret;
+}
+
+static void
+native_sleep(yarv_thread_t *th, struct timeval *tv)
+{
+    DWORD msec;
+    if (tv) {
+	msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+    }
+    else {
+	msec = INFINITE;
+    }
+
+    GVL_UNLOCK_BEGIN();
+    {
+	DWORD ret;
+	int status = th->status;
+	th->status = THREAD_STOPPED;
+	th->interrupt_function = native_thread_interrupt;
+	thread_debug("native_sleep start (%d)\n", (int)msec);
+	ret = w32_wait_event(0, msec, th);
+	thread_debug("native_sleep done (%d)\n", ret);
+	th->interrupt_function = 0;
+	th->status = status;
+    }
+    GVL_UNLOCK_END();
+}
+
+int
+native_mutex_lock(yarv_thread_lock_t *lock)
+{
+#if USE_WIN32_MUTEX
+    DWORD result;
+    while (1) {
+	thread_debug("native_mutex_lock: %p\n", *lock);
+	result = w32_wait_event(*lock, INFINITE, 0);
+	switch (result) {
+	case WAIT_OBJECT_0:
+	    /* get mutex object */
+	    thread_debug("acquire mutex: %p\n", *lock);
+	    return 0;
+	case WAIT_OBJECT_0 + 1:
+	    /* interrupt */
+	    errno = EINTR;
+	    thread_debug("acquire mutex interrupted: %p\n", *lock);
+	    return 0;
+	case WAIT_TIMEOUT:
+	    thread_debug("timeout mutex: %p\n", *lock);
+	    break;
+	case WAIT_ABANDONED:
+	    rb_bug("win32_mutex_lock: WAIT_ABANDONED");
+	    break;
+	default:
+	    rb_bug("win32_mutex_lock: unknown result (%d)", result);
+	    break;
+	}
+    }
+    return 0;
+#else
+    EnterCriticalSection(lock);
+    return 0;
+#endif
+}
+
+int
+native_mutex_unlock(yarv_thread_lock_t *lock)
+{
+#if USE_WIN32_MUTEX
+    thread_debug("release mutex: %p\n", *lock);
+    return ReleaseMutex(*lock);
+#else
+    LeaveCriticalSection(lock);
+    return 0;
+#endif
+}
+
+int
+native_mutex_trylock(yarv_thread_lock_t *lock)
+{
+#if USE_WIN32MUTEX
+    int result;
+    thread_debug("native_mutex_trylock: %p\n", *lock);
+    result = w32_wait_event(*lock, 1, 0);
+    thread_debug("native_mutex_trylock result: %d\n", result);
+    switch (result) {
+    case WAIT_OBJECT_0:
+	return 0;
+    case WAIT_TIMEOUT:
+	return EBUSY;
+    }
+    return EINVAL;
+#else
+    return TryEnterCriticalSection(lock) == 0;
+#endif
+}
+
+void
+native_mutex_initialize(yarv_thread_lock_t *lock)
+{
+#if USE_WIN32MUTEX
+    *lock = CreateMutex(NULL, FALSE, NULL);
+    // thread_debug("initialize mutex: %p\n", *lock);
+#else
+    InitializeCriticalSection(lock);
+#endif
+}
+
+NOINLINE(static int
+	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
+void static thread_cleanup_func(void *th_ptr);
+
+static unsigned int _stdcall
+thread_start_func_1(void *th_ptr)
+{
+    yarv_thread_t *th = th_ptr;
+    VALUE stack_start;
+    /* run */
+    th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
+
+    thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
+		 th->thread_id, th->native_thread_data.interrupt_event);
+    thread_start_func_2(th, &stack_start);
+    thread_cleanup_func(th);
+
+    // native_mutex_unlock(&GET_VM()->global_interpreter_lock);
+
+    thread_debug("close handle - intr: %p, thid: %p\n",
+		 th->native_thread_data.interrupt_event, th->thread_id);
+    CloseHandle(th->native_thread_data.interrupt_event);
+    CloseHandle(th->thread_id);
+    thread_debug("thread deleted (th: %p)\n", th);
+    return 0;
+}
+
+static void make_timer_thread();
+
+static HANDLE
+w32_create_thread(DWORD stack_size, void *func, void *val)
+{
+    HANDLE handle;
+#ifdef __CYGWIN__
+    DWORD dmy;
+    handle = CreateThread(0, stack_size, func, val, 0, &dmy);
+#else
+    handle = (HANDLE) _beginthreadex(0, stack_size, func, val, 0, 0);
+#endif
+    return handle;
+}
+
+static int
+native_thread_create(yarv_thread_t *th)
+{
+    size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
+
+    if ((th->thread_id =
+	 w32_create_thread(stack_size, thread_start_func_1, th))
+	== 0) {
+	rb_raise(rb_eThreadError, "can't create Thread (%d)", errno);
+    }
+    if (THREAD_DEBUG) {
+	Sleep(0);
+	thread_debug("create: (th: %p, thid: %p, intr: %p), stack size: %d\n",
+		     th, th->thread_id,
+		     th->native_thread_data.interrupt_event, stack_size);
+    }
+    return 0;
+}
+
+static void
+native_thread_apply_priority(yarv_thread_t *th)
+{
+    int priority = th->priority;
+    if (th->priority > 0) {
+	priority = THREAD_PRIORITY_ABOVE_NORMAL;
+    }
+    else if (th->priority < 0) {
+	priority = THREAD_PRIORITY_BELOW_NORMAL;
+    }
+    else {
+	priority = THREAD_PRIORITY_NORMAL;
+    }
+
+    SetThreadPriority(th->thread_id, priority);
+}
+
+static void
+native_thread_interrupt(yarv_thread_t *th)
+{
+    thread_debug("native_thread_interrupt: %p\n", th);
+    SetEvent(th->native_thread_data.interrupt_event);
+}
+
+static void timer_function(void);
+
+static HANDLE timer_thread_handle = 0;
+
+static unsigned int _stdcall
+timer_thread_func(void *dummy)
+{
+    thread_debug("timer_thread\n");
+    while (system_working) {
+	Sleep(WIN32_WAIT_TIMEOUT);
+	timer_function();
+    }
+    thread_debug("timer killed\n");
+    return 0;
+}
+
+static void
+make_timer_thread()
+{
+    if (timer_thread_handle == 0) {
+	timer_thread_handle = w32_create_thread(1024, timer_thread_func, 0);
+    }
+}
+
+#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */

Modified: trunk/thread_win32.h
===================================================================
--- trunk/thread_win32.h	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/thread_win32.h	2006-11-09 01:27:13 UTC (rev 578)
@@ -22,305 +22,3 @@
 
 #endif /* THREAD_WIN32_H_INCLUDED */
 
-
-
-/**********************************************************************/
-
-#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
-
-#include <process.h>
-
-#define WIN32_WAIT_TIMEOUT 10	/* 10 ms */
-#undef Sleep
-
-#define native_thread_yield() Sleep(0)
-#define yarv_remove_signal_thread_list(th)
-
-static void
-Init_native_thread()
-{
-    yarv_thread_t *th = GET_THREAD();
-    DuplicateHandle(GetCurrentProcess(),
-		    GetCurrentThread(),
-		    GetCurrentProcess(),
-		    &th->thread_id, 0, FALSE, DUPLICATE_SAME_ACCESS);
-
-    th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
-
-    thread_debug("initial thread (th: %p, thid: %p, event: %p)\n",
-		 th, GET_THREAD()->thread_id,
-		 th->native_thread_data.interrupt_event);
-}
-
-static void
-w32_show_error_message()
-{
-    LPVOID lpMsgBuf;
-    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-		  FORMAT_MESSAGE_FROM_SYSTEM |
-		  FORMAT_MESSAGE_IGNORE_INSERTS,
-		  NULL,
-		  GetLastError(),
-		  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-		  (LPTSTR) & lpMsgBuf, 0, NULL);
-    // {int *a=0; *a=0;}
-    MessageBox(NULL, (LPCTSTR) lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
-    //  exit(1);
-}
-
-static int
-w32_wait_event(HANDLE event, DWORD timeout, yarv_thread_t *th)
-{
-    HANDLE events[2];
-    int count = 0;
-    DWORD ret;
-
-    if (event) {
-	events[count++] = event;
-	thread_debug("  * handle: %p (count: %d)\n", event, count);
-    }
-
-    if (th) {
-	HANDLE intr = th->native_thread_data.interrupt_event;
-	ResetEvent(intr);
-	if (th->interrupt_flag) {
-	    SetEvent(intr);
-	}
-
-	events[count++] = intr;
-	thread_debug("  * handle: %p (count: %d, intr)\n", intr, count);
-    }
-
-    thread_debug("  WaitForMultipleObjects start (count: %d)\n", count);
-    ret = WaitForMultipleObjects(count, events, FALSE, timeout);
-    thread_debug("  WaitForMultipleObjects end (ret: %d)\n", ret);
-
-    if (ret == WAIT_OBJECT_0 + count - 1 && th) {
-	errno = EINTR;
-    }
-    if (ret == -1 && THREAD_DEBUG) {
-	int i;
-	DWORD dmy;
-	for (i = 0; i < count; i++) {
-	    thread_debug("  * error handle %d - %s\n", i,
-			 GetHandleInformation(events[i], &dmy) ? "OK" : "NG");
-	}
-    }
-    return ret;
-}
-
-static void
-native_sleep(yarv_thread_t *th, struct timeval *tv)
-{
-    DWORD msec;
-    if (tv) {
-	msec = tv->tv_sec * 1000 + tv->tv_usec / 1000;
-    }
-    else {
-	msec = INFINITE;
-    }
-
-    GVL_UNLOCK_BEGIN();
-    {
-	DWORD ret;
-	int status = th->status;
-	th->status = THREAD_STOPPED;
-	th->interrupt_function = native_thread_interrupt;
-	thread_debug("native_sleep start (%d)\n", (int)msec);
-	ret = w32_wait_event(0, msec, th);
-	thread_debug("native_sleep done (%d)\n", ret);
-	th->interrupt_function = 0;
-	th->status = status;
-    }
-    GVL_UNLOCK_END();
-}
-
-int
-native_mutex_lock(yarv_thread_lock_t *lock)
-{
-#if USE_WIN32_MUTEX
-    DWORD result;
-    while (1) {
-	thread_debug("native_mutex_lock: %p\n", *lock);
-	result = w32_wait_event(*lock, INFINITE, 0);
-	switch (result) {
-	case WAIT_OBJECT_0:
-	    /* get mutex object */
-	    thread_debug("acquire mutex: %p\n", *lock);
-	    return 0;
-	case WAIT_OBJECT_0 + 1:
-	    /* interrupt */
-	    errno = EINTR;
-	    thread_debug("acquire mutex interrupted: %p\n", *lock);
-	    return 0;
-	case WAIT_TIMEOUT:
-	    thread_debug("timeout mutex: %p\n", *lock);
-	    break;
-	case WAIT_ABANDONED:
-	    rb_bug("win32_mutex_lock: WAIT_ABANDONED");
-	    break;
-	default:
-	    rb_bug("win32_mutex_lock: unknown result (%d)", result);
-	    break;
-	}
-    }
-    return 0;
-#else
-    EnterCriticalSection(lock);
-    return 0;
-#endif
-}
-
-int
-native_mutex_unlock(yarv_thread_lock_t *lock)
-{
-#if USE_WIN32_MUTEX
-    thread_debug("release mutex: %p\n", *lock);
-    return ReleaseMutex(*lock);
-#else
-    LeaveCriticalSection(lock);
-    return 0;
-#endif
-}
-
-int
-native_mutex_trylock(yarv_thread_lock_t *lock)
-{
-#if USE_WIN32MUTEX
-    int result;
-    thread_debug("native_mutex_trylock: %p\n", *lock);
-    result = w32_wait_event(*lock, 1, 0);
-    thread_debug("native_mutex_trylock result: %d\n", result);
-    switch (result) {
-    case WAIT_OBJECT_0:
-	return 0;
-    case WAIT_TIMEOUT:
-	return EBUSY;
-    }
-    return EINVAL;
-#else
-    return TryEnterCriticalSection(lock) == 0;
-#endif
-}
-
-void
-native_mutex_initialize(yarv_thread_lock_t *lock)
-{
-#if USE_WIN32MUTEX
-    *lock = CreateMutex(NULL, FALSE, NULL);
-    // thread_debug("initialize mutex: %p\n", *lock);
-#else
-    InitializeCriticalSection(lock);
-#endif
-}
-
-NOINLINE(static int
-	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
-void static thread_cleanup_func(void *th_ptr);
-
-static unsigned int _stdcall
-thread_start_func_1(void *th_ptr)
-{
-    yarv_thread_t *th = th_ptr;
-    VALUE stack_start;
-    /* run */
-    th->native_thread_data.interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
-
-    thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
-		 th->thread_id, th->native_thread_data.interrupt_event);
-    thread_start_func_2(th, &stack_start);
-    thread_cleanup_func(th);
-
-    // native_mutex_unlock(&GET_VM()->global_interpreter_lock);
-
-    thread_debug("close handle - intr: %p, thid: %p\n",
-		 th->native_thread_data.interrupt_event, th->thread_id);
-    CloseHandle(th->native_thread_data.interrupt_event);
-    CloseHandle(th->thread_id);
-    thread_debug("thread deleted (th: %p)\n", th);
-    return 0;
-}
-
-static void make_timer_thread();
-
-static HANDLE
-w32_create_thread(DWORD stack_size, void *func, void *val)
-{
-    HANDLE handle;
-#ifdef __CYGWIN__
-    DWORD dmy;
-    handle = CreateThread(0, stack_size, func, val, 0, &dmy);
-#else
-    handle = (HANDLE) _beginthreadex(0, stack_size, func, val, 0, 0);
-#endif
-    return handle;
-}
-
-static int
-native_thread_create(yarv_thread_t *th)
-{
-    size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
-
-    if ((th->thread_id =
-	 w32_create_thread(stack_size, thread_start_func_1, th))
-	== 0) {
-	rb_raise(rb_eThreadError, "can't create Thread (%d)", errno);
-    }
-    if (THREAD_DEBUG) {
-	Sleep(0);
-	thread_debug("create: (th: %p, thid: %p, intr: %p), stack size: %d\n",
-		     th, th->thread_id,
-		     th->native_thread_data.interrupt_event, stack_size);
-    }
-    return 0;
-}
-
-static void
-native_thread_apply_priority(yarv_thread_t *th)
-{
-    int priority = th->priority;
-    if (th->priority > 0) {
-	priority = THREAD_PRIORITY_ABOVE_NORMAL;
-    }
-    else if (th->priority < 0) {
-	priority = THREAD_PRIORITY_BELOW_NORMAL;
-    }
-    else {
-	priority = THREAD_PRIORITY_NORMAL;
-    }
-
-    SetThreadPriority(th->thread_id, priority);
-}
-
-static void
-native_thread_interrupt(yarv_thread_t *th)
-{
-    thread_debug("native_thread_interrupt: %p\n", th);
-    SetEvent(th->native_thread_data.interrupt_event);
-}
-
-static void timer_function(void);
-
-static HANDLE timer_thread_handle = 0;
-
-static unsigned int _stdcall
-timer_thread_func(void *dummy)
-{
-    thread_debug("timer_thread\n");
-    while (system_working) {
-	Sleep(WIN32_WAIT_TIMEOUT);
-	timer_function();
-    }
-    thread_debug("timer killed\n");
-    return 0;
-}
-
-static void
-make_timer_thread()
-{
-    if (timer_thread_handle == 0) {
-	timer_thread_handle = w32_create_thread(1024, timer_thread_func, 0);
-    }
-}
-
-#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/vm.c	2006-11-09 01:27:13 UTC (rev 578)
@@ -44,7 +44,7 @@
 static VALUE yarv_finish_insn_seq[1] = { BIN(finish) };
 #endif
 
-#include "call_cfunc.h"
+#include "call_cfunc.ci"
 
 void
 rb_vm_change_state(void)
@@ -1404,7 +1404,7 @@
     }
 }
 
-#include "vm_evalbody.h"
+#include "vm_evalbody.ci"
 
 /*                  finish
   VMe (h1)          finish

Copied: trunk/vm_evalbody.ci (from rev 574, trunk/vm_evalbody.h)

Deleted: trunk/vm_evalbody.h
===================================================================
--- trunk/vm_evalbody.h	2006-11-08 08:26:24 UTC (rev 577)
+++ trunk/vm_evalbody.h	2006-11-09 01:27:13 UTC (rev 578)
@@ -1,132 +0,0 @@
-/* -*-c-*- *********************************************************
- * this file is included by vm.c
- */
-
-#include <math.h>
-
-#if VMDEBUG > 0
-#define DECL_SC_REG(type, r, reg) register type reg_##r
-
-#elif __GNUC__ && __x86_64
-#define DECL_SC_REG(type, r, reg) register type reg_##r asm("r" reg)
-
-#elif __GNUC__ && __i386__
-#define DECL_SC_REG(type, r, reg) register type reg_##r asm("e" reg)
-
-#else
-#define DECL_SC_REG(type, r, reg) register type reg_##r
-#endif
-// #define DECL_SC_REG(r, reg) VALUE reg_##r
-
-typedef yarv_iseq_t *ISEQ;
-
-#if !OPT_CALL_THREADED_CODE
-VALUE
-th_eval(yarv_thread_t *th, VALUE initial)
-{
-
-#if OPT_STACK_CACHING
-#if 0
-#elif __GNUC__ && __x86_64
-    DECL_SC_REG(VALUE, a, "12");
-    DECL_SC_REG(VALUE, b, "13");
-#else
-    register VALUE reg_a;
-    register VALUE reg_b;
-#endif
-#endif
-
-#if __GNUC__ && __i386__
-    DECL_SC_REG(VALUE *, pc, "di");
-    DECL_SC_REG(yarv_control_frame_t *, cfp, "si");
-#define USE_MACHINE_REGS 1
-
-#elif __GNUC__ && __x86_64__
-    DECL_SC_REG(VALUE *, pc, "14");
-    DECL_SC_REG(yarv_control_frame_t *, cfp, "15");
-#define USE_MACHINE_REGS 1
-
-#else
-    register yarv_control_frame_t *reg_cfp;
-    VALUE *reg_pc;
-#endif
-
-#if USE_MACHINE_REGS
-
-#undef  RESTORE_REGS
-#define RESTORE_REGS() \
-{ \
-  REG_CFP = th->cfp; \
-  reg_pc  = reg_cfp->pc; \
-}
-
-#undef  REG_PC
-#define REG_PC reg_pc
-#undef  GET_PC
-#define GET_PC() (reg_pc)
-#undef  SET_PC
-#define SET_PC(x) (reg_cfp->pc = REG_PC = (x))
-#endif
-
-    ID tmp_id;
-    yarv_block_t *tmp_blockptr;
-    num_t tmp_num;
-
-#if OPT_TOKEN_THREADED_CODE || OPT_DIRECT_THREADED_CODE
-#include "vmtc.inc"
-    if (th == 0) {
-#if OPT_STACK_CACHING
-	yarv_finish_insn_seq[0] = (VALUE)&&LABEL (finish_SC_ax_ax);
-#else
-	yarv_finish_insn_seq[0] = (VALUE)&&LABEL (finish);
-#endif
-	return (VALUE)insns_address_table;
-    }
-#endif
-    reg_cfp = th->cfp;
-    reg_pc = reg_cfp->pc;
-
-#if OPT_STACK_CACHING
-    reg_a = initial;
-    reg_b = 0;
-#endif
-
-  first:
-    INSN_DISPATCH();
-  /******************/
-#include "vm.inc"
-  /******************/
-    END_INSNS_DISPATCH();
-
-    /* unreachable */
-    rb_bug("th_eval_iseq: unreachable");
-    return Qundef;
-}
-
-#else
-
-#include "vm.inc"
-#include "vmtc.inc"
-
-void **
-get_insns_address_table()
-{
-    return (void **)insns_address_table;
-}
-
-VALUE
-th_eval(yarv_thread_t *th, VALUE initial)
-{
-    register yarv_control_frame_t *reg_cfp = th->cfp;
-    SET_PC(reg_cfp->iseq->iseq_encoded);
-
-    while (*GET_PC()) {
-	reg_cfp = ((insn_func_type) (*GET_PC()))(th, reg_cfp);
-    }
-    {
-	VALUE ret = *--reg_cfp->sp;
-	th->cfp--;
-	return ret;
-    }
-}
-#endif


--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

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