[前][次][番号順一覧][スレッド一覧]

ruby-changes:7402

From: nobu <ko1@a...>
Date: Fri, 29 Aug 2008 19:46:14 +0900 (JST)
Subject: [ruby-changes:7402] Ruby:r18921 (mvm): * common.mk (VM_CORE_H_INCLUDES): needs mvm.h.

nobu	2008-08-29 19:44:55 +0900 (Fri, 29 Aug 2008)

  New Revision: 18921

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=18921

  Log:
    * common.mk (VM_CORE_H_INCLUDES): needs mvm.h.
    
    * signal.c (sighandler), thread.c (timer_thread_function): delivers to
      all VMs.
    
    * thread_{pthread,win32}.c (ruby_native_thread_lock_initialize),
      (ruby_native_thread_lock_destroy): exported.
    
    * vm_core.h (struct rb_vm_struct): added signal lock.
    
    * vm.c (vm_manager): manages MVM.
    
    * vm.c (ruby_vm_foreach): iterates over all VMs.  returnig false stops
      the iteration.
    
    * vm.c (vm_free): unregister and free VM structure.
    
    * vm.c (vm_init2): moved initialization of locks and object space.
    
    * vm.c (ruby_vm_send_signal, ruby_vm_get_next_signal): sends/retreives
      VM signal.

  Modified files:
    branches/mvm/ChangeLog
    branches/mvm/common.mk
    branches/mvm/include/ruby/mvm.h
    branches/mvm/signal.c
    branches/mvm/thread.c
    branches/mvm/thread_pthread.c
    branches/mvm/thread_win32.c
    branches/mvm/vm.c
    branches/mvm/vm_core.h

Index: mvm/thread_win32.c
===================================================================
--- mvm/thread_win32.c	(revision 18920)
+++ mvm/thread_win32.c	(revision 18921)
@@ -24,7 +24,6 @@
 static int native_mutex_lock(rb_thread_lock_t *);
 static int native_mutex_unlock(rb_thread_lock_t *);
 static int native_mutex_trylock(rb_thread_lock_t *);
-static void native_mutex_initialize(rb_thread_lock_t *);
 
 static void native_cond_signal(rb_thread_cond_t *cond);
 static void native_cond_broadcast(rb_thread_cond_t *cond);
@@ -328,8 +327,8 @@
 #endif
 }
 
-static void
-native_mutex_initialize(rb_thread_lock_t *lock)
+void
+ruby_native_thread_lock_initialize(rb_thread_lock_t *lock)
 {
 #if USE_WIN32_MUTEX
     *lock = CreateMutex(NULL, FALSE, NULL);
@@ -342,8 +341,8 @@
 #endif
 }
 
-static void
-native_mutex_destroy(rb_thread_lock_t *lock)
+void
+ruby_native_thread_lock_destroy(rb_thread_lock_t *lock)
 {
 #if USE_WIN32_MUTEX
     w32_close_handle(lock);
Index: mvm/include/ruby/mvm.h
===================================================================
--- mvm/include/ruby/mvm.h	(revision 18920)
+++ mvm/include/ruby/mvm.h	(revision 18921)
@@ -37,9 +37,14 @@
 
 #endif
 
+void ruby_native_thread_lock_initialize(rb_thread_lock_t *);
+void ruby_native_thread_lock_destroy(rb_thread_lock_t *);
+
 typedef struct rb_vm_struct rb_vm_t;
 typedef struct rb_thread_struct rb_thread_t;
 
+void ruby_vm_foreach(int (*)(rb_vm_t *, void *), void *); /* returning false stops iteration */
+
 VALUE *ruby_vm_verbose_ptr(rb_vm_t *);
 VALUE *ruby_vm_debug_ptr(rb_vm_t *);
 
Index: mvm/ChangeLog
===================================================================
--- mvm/ChangeLog	(revision 18920)
+++ mvm/ChangeLog	(revision 18921)
@@ -1,3 +1,27 @@
+Fri Aug 29 19:44:50 2008  Nobuyoshi Nakada  <nobu@r...>
+
+	* common.mk (VM_CORE_H_INCLUDES): needs mvm.h.
+
+	* signal.c (sighandler), thread.c (timer_thread_function): delivers to
+	  all VMs.
+
+	* thread_{pthread,win32}.c (ruby_native_thread_lock_initialize),
+	  (ruby_native_thread_lock_destroy): exported.
+
+	* vm_core.h (struct rb_vm_struct): added signal lock.
+
+	* vm.c (vm_manager): manages MVM.
+
+	* vm.c (ruby_vm_foreach): iterates over all VMs.  returnig false stops
+	  the iteration.
+
+	* vm.c (vm_free): unregister and free VM structure.
+
+	* vm.c (vm_init2): moved initialization of locks and object space.
+
+	* vm.c (ruby_vm_send_signal, ruby_vm_get_next_signal): sends/retreives
+	  VM signal.
+
 Sat Aug 16 18:38:13 2008  Nobuyoshi Nakada  <nobu@r...>
 
 	* tool/resolve_changelog.rb (ChangeLog.Reader#split_entry): strips
Index: mvm/thread_pthread.c
===================================================================
--- mvm/thread_pthread.c	(revision 18920)
+++ mvm/thread_pthread.c	(revision 18921)
@@ -29,8 +29,6 @@
 static void native_mutex_lock(pthread_mutex_t *lock);
 static void native_mutex_unlock(pthread_mutex_t *lock);
 static int native_mutex_trylock(pthread_mutex_t *lock);
-static void native_mutex_initialize(pthread_mutex_t *lock);
-static void native_mutex_destroy(pthread_mutex_t *lock);
 
 static void native_cond_signal(pthread_cond_t *cond);
 static void native_cond_broadcast(pthread_cond_t *cond);
@@ -71,8 +69,8 @@
     return 0;
 }
 
-static void
-native_mutex_initialize(pthread_mutex_t *lock)
+void
+ruby_native_thread_lock_initialize(pthread_mutex_t *lock)
 {
     int r = pthread_mutex_init(lock, 0);
     if (r != 0) {
@@ -80,8 +78,8 @@
     }
 }
 
-static void
-native_mutex_destroy(pthread_mutex_t *lock)
+void
+ruby_native_thread_lock_destroy(pthread_mutex_t *lock)
 {
     int r = pthread_mutex_destroy(lock);
     if (r != 0) {
Index: mvm/vm_core.h
===================================================================
--- mvm/vm_core.h	(revision 18920)
+++ mvm/vm_core.h	(revision 18921)
@@ -338,8 +338,11 @@
     struct st_table *loading_table;
     
     /* signal */
-    rb_atomic_t signal_buff[RUBY_NSIG];
-    rb_atomic_t buffered_signal_size;
+    struct {
+	rb_thread_lock_t lock;
+	rb_atomic_t buff[RUBY_NSIG];
+	rb_atomic_t buffered_size;
+    } signal;
 
     /* hook */
     rb_event_hook_t *event_hooks;
Index: mvm/thread.c
===================================================================
--- mvm/thread.c	(revision 18920)
+++ mvm/thread.c	(revision 18921)
@@ -58,6 +58,9 @@
 #define THREAD_DEBUG 0
 #endif
 
+#define native_mutex_initialize(lock) ruby_native_thread_lock_initialize(lock)
+#define native_mutex_destroy(lock) ruby_native_thread_lock_destroy(lock)
+
 static void sleep_timeval(rb_thread_t *th, struct timeval time);
 static void sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec);
 static void sleep_forever(rb_thread_t *th, int nodeadlock);
@@ -2244,24 +2247,22 @@
  *
  */
 
-int rb_get_next_signal(rb_vm_t *vm);
+int ruby_vm_get_next_signal(rb_vm_t *vm);
 
-static void
-timer_thread_function(void *arg)
+static int
+vm_timer_thread_function(rb_vm_t *vm, void *arg)
 {
-    rb_vm_t *vm = arg; /* TODO: fix me for Multi-VM */
-
     /* for time slice */
     RUBY_VM_SET_TIMER_INTERRUPT(vm->running_thread);
 
     /* check signal */
-    if (vm->buffered_signal_size && vm->main_thread->exec_signal == 0) {
+    if (vm->signal.buffered_size && vm->main_thread->exec_signal == 0) {
 	rb_thread_t *mth = vm->main_thread;
 	enum rb_thread_status prev_status = mth->status;
-	mth->exec_signal = rb_get_next_signal(vm);
+	mth->exec_signal = ruby_vm_get_next_signal(vm);
 	thread_debug("main_thread: %s\n", thread_status_name(prev_status));
 	thread_debug("buffered_signal_size: %ld, sig: %d\n",
-		     (long)vm->buffered_signal_size, vm->main_thread->exec_signal);
+		     (long)vm->signal.buffered_size, vm->main_thread->exec_signal);
 	if (mth->status != THREAD_KILLED) mth->status = THREAD_RUNNABLE;
 	rb_thread_interrupt(mth);
 	mth->status = prev_status;
@@ -2277,8 +2278,16 @@
 	}
     }
 #endif
+
+    return Qtrue;
 }
 
+static void
+timer_thread_function(void *arg)
+{
+    ruby_vm_foreach(vm_timer_thread_function, arg);
+}
+
 void
 rb_thread_stop_timer_thread(void)
 {
@@ -3667,7 +3676,6 @@
 	{
 	    /* acquire global interpreter lock */
 	    rb_thread_lock_t *lp = &GET_THREAD()->vm->global_vm_lock;
-	    native_mutex_initialize(lp);
 	    native_mutex_lock(lp);
 	    native_mutex_initialize(&GET_THREAD()->interrupt_lock);
 	}
Index: mvm/common.mk
===================================================================
--- mvm/common.mk	(revision 18920)
+++ mvm/common.mk	(revision 18921)
@@ -434,7 +434,7 @@
 		  {$(VPATH)}public_object.h
 ID_H_INCLUDES = {$(VPATH)}id.h {$(VPATH)}parse.h
 
-VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}private_object.h
+VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}mvm.h {$(VPATH)}private_object.h
 
 array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) \
   {$(VPATH)}st.h {$(VPATH)}util.h
Index: mvm/vm.c
===================================================================
--- mvm/vm.c	(revision 18920)
+++ mvm/vm.c	(revision 18921)
@@ -1340,7 +1340,56 @@
 
 /* vm */
 
+static struct {
+    rb_thread_lock_t lock;
+    st_table *list;
+} vm_manager = {RB_THREAD_LOCK_INITIALIZER};
+
 static void
+vm_add(rb_vm_t *vm)
+{
+    ruby_native_thread_lock(&vm_manager.lock);
+    st_insert(vm_manager.list, (st_data_t)vm, 0);
+    ruby_native_thread_unlock(&vm_manager.lock);
+}
+
+static void
+vm_del(rb_vm_t *vm)
+{
+    st_data_t key = (st_data_t)vm, val = 0;
+    ruby_native_thread_lock(&vm_manager.lock);
+    st_delete(vm_manager.list, &key, &val);
+    ruby_native_thread_unlock(&vm_manager.lock);
+}
+
+struct each_vm_arg {
+    int (*func)(rb_vm_t *, void *);
+    void *arg;
+};
+
+static int
+each_vm(st_data_t vm, st_data_t val, st_data_t arg)
+{
+    struct each_vm_arg *p = (void *)arg;
+    if ((*p->func)((rb_vm_t *)vm, p->arg)) return ST_CONTINUE;
+    return ST_STOP;
+}
+
+void
+ruby_vm_foreach(int (*func)(rb_vm_t *, void *), void *arg)
+{
+    struct each_vm_arg args;
+
+    args.func = func;
+    args.arg = arg;
+    ruby_native_thread_lock(&vm_manager.lock);
+    if (vm_manager.list) {
+	st_foreach(vm_manager.list, each_vm, (st_data_t)&args);
+    }
+    ruby_native_thread_unlock(&vm_manager.lock);
+}
+
+static void
 vm_free(void *ptr)
 {
     RUBY_FREE_ENTER("vm");
@@ -1349,10 +1398,8 @@
 
 	st_free_table(vmobj->living_threads);
 	vmobj->living_threads = 0;
-	/* TODO: MultiVM Instance */
-	/* VM object should not be cleaned by GC */
-	/* ruby_xfree(ptr); */
-	/* ruby_current_vm = 0; */
+	vm_del(vmobj);
+	ruby_xfree(ptr);
     }
     RUBY_FREE_LEAVE("vm");
 }
@@ -1404,16 +1451,52 @@
     RUBY_MARK_LEAVE("vm");
 }
 
+#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
+struct rb_objspace *rb_objspace_alloc(void);
+#endif
+
 static void
 vm_init2(rb_vm_t *vm)
 {
     MEMZERO(vm, rb_vm_t, 1);
+    ruby_native_thread_lock_initialize(&vm->global_vm_lock);
+    ruby_native_thread_lock_initialize(&vm->signal.lock);
+    vm->objspace = rb_objspace_alloc();
     vm->src_encoding_index = -1;
     vm->global_state_version = 1;
     vm->specific_storage.len = rb_vm_key_count();
     vm->specific_storage.ptr = calloc(vm->specific_storage.len, sizeof(VALUE));
 }
 
+int
+ruby_vm_send_signal(rb_vm_t *vm, int sig)
+{
+    if (sig <= 0 || sig >= RUBY_NSIG) return -1;
+    ruby_native_thread_lock(&vm->signal.lock);
+    ATOMIC_INC(vm->signal.buff[sig]);
+    ATOMIC_INC(vm->signal.buffered_size);
+    ruby_native_thread_unlock(&vm->signal.lock);
+    return sig;
+}
+
+int
+ruby_vm_get_next_signal(rb_vm_t *vm)
+{
+    int i, sig = 0;
+
+    ruby_native_thread_lock(&vm->signal.lock);
+    for (i = 1; i < RUBY_NSIG; i++) {
+	if (vm->signal.buff[i] > 0) {
+	    ATOMIC_DEC(vm->signal.buff[i]);
+	    ATOMIC_DEC(vm->signal.buffered_size);
+	    sig = i;
+	    break;
+	}
+    }
+    ruby_native_thread_unlock(&vm->signal.lock);
+    return sig;
+}
+
 /* Thread */
 
 #define USE_THREAD_DATA_RECYCLE 1
@@ -1896,9 +1979,6 @@
     }
 }
 
-#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
-struct rb_objspace *rb_objspace_alloc(void);
-#endif
 void ruby_thread_init_stack(rb_thread_t *th);
 
 void
@@ -1916,11 +1996,11 @@
     rb_thread_set_current_raw(th);
 
     vm_init2(vm);
-#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
-    vm->objspace = rb_objspace_alloc();
-#endif
+    th->vm = vm;
 
-    th->vm = vm;
+    vm_manager.list = st_init_numtable();
+    vm_add(vm);
+
     th_init2(th, 0);
     ruby_thread_init_stack(th);
 }
Index: mvm/signal.c
===================================================================
--- mvm/signal.c	(revision 18920)
+++ mvm/signal.c	(revision 18921)
@@ -508,13 +508,19 @@
 #endif
 #endif
 
+int ruby_vm_send_signal(rb_vm_t *, int);
+
+static int
+signal_vm(rb_vm_t *vm, void *sig)
+{
+    ruby_vm_send_signal(vm, (int)sig);
+    return Qtrue;
+}
+
 static RETSIGTYPE
 sighandler(int sig)
 {
-    rb_vm_t *vm = GET_VM(); /* fix me for Multi-VM */
-    ATOMIC_INC(vm->signal_buff[sig]);
-    ATOMIC_INC(vm->buffered_signal_size);
-
+    ruby_vm_foreach(signal_vm, (void *)sig);
 #if !defined(BSD_SIGNAL) && !defined(POSIX_SIGNAL)
     ruby_signal(sig, sighandler);
 #endif
@@ -554,26 +560,6 @@
 #endif
 }
 
-int
-rb_get_next_signal(rb_vm_t *vm)
-{
-    int i, sig = 0;
-
-    for (i=1; i<RUBY_NSIG; i++) {
-	if (vm->signal_buff[i] > 0) {
-	    rb_disable_interrupt();
-	    {
-		ATOMIC_DEC(vm->signal_buff[i]);
-		ATOMIC_DEC(vm->buffered_signal_size);
-	    }
-	    rb_enable_interrupt();
-	    sig = i;
-	    break;
-	}
-    }
-    return sig;
-}
-
 #ifdef SIGBUS
 static RETSIGTYPE
 sigbus(int sig)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]