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/