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