Revision: 3958 http://trac.macosforge.org/projects/ruby/changeset/3958 Author: lsansonetti@apple.com Date: 2010-04-22 17:49:34 -0700 (Thu, 22 Apr 2010) Log Message: ----------- the VM is now multithreaded-aware by default Modified Paths: -------------- MacRuby/trunk/gc.c MacRuby/trunk/gcd.c MacRuby/trunk/vm.cpp MacRuby/trunk/vm.h Modified: MacRuby/trunk/gc.c =================================================================== --- MacRuby/trunk/gc.c 2010-04-22 07:50:59 UTC (rev 3957) +++ MacRuby/trunk/gc.c 2010-04-23 00:49:34 UTC (rev 3958) @@ -748,7 +748,6 @@ rb_objc_finalizer_finalize(void *rcv, SEL sel) { rb_vm_finalizer_t *f = (rb_vm_finalizer_t *)rcv; - rb_vm_set_multithreaded(true); rb_vm_call_finalizer(f); rb_vm_unregister_finalizer(f); if (rb_objc_finalizer_finalize_super != NULL) { Modified: MacRuby/trunk/gcd.c =================================================================== --- MacRuby/trunk/gcd.c 2010-04-22 07:50:59 UTC (rev 3957) +++ MacRuby/trunk/gcd.c 2010-04-23 00:49:34 UTC (rev 3958) @@ -362,7 +362,6 @@ if (block == NULL) { rb_raise(rb_eArgError, "block not given"); } - rb_vm_set_multithreaded(true); #if GCD_BLOCKS_COPY_DVARS block = rb_vm_dup_block(block); for (int i = 0; i < block->dvars_size; i++) { @@ -1150,7 +1149,7 @@ rb_dispatch_begin_thread(void) { if (old_dispatch_begin_thread_4GC != NULL) { - (*old_dispatch_begin_thread_4GC)(); + (*old_dispatch_begin_thread_4GC)(); } rb_vm_register_current_alien_thread(); } @@ -1159,7 +1158,7 @@ rb_dispatch_end_thread(void) { if (old_dispatch_end_thread_4GC != NULL) { - (*old_dispatch_end_thread_4GC)(); + (*old_dispatch_end_thread_4GC)(); } rb_vm_unregister_current_alien_thread(); } @@ -1173,7 +1172,6 @@ dispatch_end_thread_4GC = rb_dispatch_end_thread; } - void Init_Dispatch(void) { Modified: MacRuby/trunk/vm.cpp =================================================================== --- MacRuby/trunk/vm.cpp 2010-04-22 07:50:59 UTC (rev 3957) +++ MacRuby/trunk/vm.cpp 2010-04-23 00:49:34 UTC (rev 3958) @@ -298,7 +298,6 @@ RoxorCore::RoxorCore(void) { running = false; - multithreaded = false; abort_on_exception = false; pthread_assert(pthread_mutex_init(&gl, 0)); @@ -4455,26 +4454,10 @@ void * rb_vm_create_vm(void) { - GET_CORE()->set_multithreaded(true); - return (void *)new RoxorVM(*GET_VM()); } -extern "C" -bool -rb_vm_is_multithreaded(void) -{ - return GET_CORE()->get_multithreaded(); -} - -extern "C" void -rb_vm_set_multithreaded(bool flag) -{ - GET_CORE()->set_multithreaded(flag); -} - -void RoxorCore::register_thread(VALUE thread) { RoxorCoreLock lock; @@ -4988,6 +4971,8 @@ RoxorVM::main = new RoxorVM(); pthread_assert(pthread_key_create(&RoxorVM::vm_thread_key, NULL)); + pthread_assert(pthread_setspecific(RoxorVM::vm_thread_key, + (void *)RoxorVM::main)); setup_builtin_stubs(); @@ -5109,7 +5094,7 @@ void RoxorVM::setup_from_current_thread(void) { - pthread_setspecific(RoxorVM::vm_thread_key, (void *)this); + pthread_assert(pthread_setspecific(RoxorVM::vm_thread_key, (void *)this)); rb_vm_thread_t *t = (rb_vm_thread_t *)xmalloc(sizeof(rb_vm_thread_t)); rb_vm_thread_pre_init(t, NULL, 0, NULL, (void *)this); @@ -5124,10 +5109,10 @@ void rb_vm_register_current_alien_thread(void) { - // This callback is not used, we prefer to create RoxorVM objects - // lazily (in RoxorVM::current()), for performance reasons, because the - // callback is called *a lot* and most of the time from various parts of - // the system which will never ask us to execute Ruby code. + // The creation of RoxorVM objects is done lazily (in RoxorVM::current()) + // for performance reason, because the callback is called *a lot* and most + // of the time from various parts of the system which will never ask us to + // execute Ruby code. #if 0 if (GET_CORE()->get_running()) { printf("registered alien thread %p\n", pthread_self()); @@ -5141,9 +5126,18 @@ void rb_vm_unregister_current_alien_thread(void) { + if (!GET_CORE()->get_running()) { + return; + } + + pthread_t self = pthread_self(); + if (GetThreadPtr(RoxorVM::main->get_thread())->thread == self) { + // Do not unregister the main thread. + return; + } + // Check if the current pthread has been registered. RoxorCoreLock lock; - pthread_t self = pthread_self(); VALUE ary = GET_CORE()->get_threads(); bool need_to_unregister = false; for (int i = 0; i < RARRAY_LEN(ary); i++) { Modified: MacRuby/trunk/vm.h =================================================================== --- MacRuby/trunk/vm.h 2010-04-22 07:50:59 UTC (rev 3957) +++ MacRuby/trunk/vm.h 2010-04-23 00:49:34 UTC (rev 3958) @@ -425,9 +425,6 @@ Class rb_vm_set_current_class(Class klass); Class rb_vm_get_current_class(void); -bool rb_vm_is_multithreaded(void); -void rb_vm_set_multithreaded(bool flag); - bool rb_vm_aot_feature_load(const char *name); static inline VALUE @@ -620,7 +617,6 @@ // State. bool running; - bool multithreaded; bool abort_on_exception; VALUE loaded_features; VALUE load_path; @@ -689,7 +685,6 @@ ~RoxorCore(void); ACCESSOR(running, bool); - ACCESSOR(multithreaded, bool); ACCESSOR(abort_on_exception, bool); ACCESSOR(default_random, VALUE); READER(loaded_features, VALUE); @@ -706,14 +701,10 @@ int trap_level_for_signal(int signal); void lock(void) { - if (multithreaded) { - assert(pthread_mutex_lock(&gl) == 0); - } + assert(pthread_mutex_lock(&gl) == 0); } void unlock(void) { - if (multithreaded) { - assert(pthread_mutex_unlock(&gl) == 0); - } + assert(pthread_mutex_unlock(&gl) == 0); } void register_thread(VALUE thread); @@ -894,21 +885,17 @@ static pthread_key_t vm_thread_key; static force_inline RoxorVM *current(void) { - if (GET_CORE()->get_multithreaded()) { - void *vm = pthread_getspecific(vm_thread_key); - if (vm == NULL) { - // The value does not exist yet, which means we are called - // from a thread that was not created by MacRuby directly - // (potentially the GC thread or Cocoa). In this case, we - // create a new VM object just for this thread. - // XXX the VM object is never detroyed. - RoxorVM *new_vm = new RoxorVM(); - new_vm->setup_from_current_thread(); - return new_vm; - } - return (RoxorVM *)vm; + void *vm = pthread_getspecific(vm_thread_key); + if (vm == NULL) { + // The value does not exist yet, which means we are called + // from a thread that was not created by MacRuby directly + // (potentially the GC thread or Cocoa). In this case, we + // create a new VM object just for this thread. + RoxorVM *new_vm = new RoxorVM(); + new_vm->setup_from_current_thread(); + return new_vm; } - return RoxorVM::main; + return (RoxorVM *)vm; } private: