1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

thread.c: reuse tag

* thread.c (rb_thread_terminate_all): reuse the tag pushed before
  a loop, instead of pushing/popping same tag repeatedly.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51301 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-07-20 00:11:40 +00:00
parent 1b8ff4f799
commit d8d9148506

View file

@ -179,6 +179,12 @@ vm_check_ints_blocking(rb_thread_t *th)
rb_threadptr_execute_interrupts(th, 1); rb_threadptr_execute_interrupts(th, 1);
} }
static int
vm_living_thread_num(rb_vm_t *vm)
{
return (int)vm->living_thread_num;
}
#if THREAD_DEBUG #if THREAD_DEBUG
#ifdef HAVE_VA_ARGS_MACRO #ifdef HAVE_VA_ARGS_MACRO
void rb_thread_debug(const char *file, int line, const char *fmt, ...); void rb_thread_debug(const char *file, int line, const char *fmt, ...);
@ -479,6 +485,7 @@ rb_thread_terminate_all(void)
{ {
rb_thread_t *th = GET_THREAD(); /* main thread */ rb_thread_t *th = GET_THREAD(); /* main thread */
rb_vm_t *vm = th->vm; rb_vm_t *vm = th->vm;
volatile int sleeping = 0;
if (vm->main_thread != th) { if (vm->main_thread != th) {
rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)", rb_bug("rb_thread_terminate_all: called by child thread (%p, %p)",
@ -488,33 +495,35 @@ rb_thread_terminate_all(void)
/* unlock all locking mutexes */ /* unlock all locking mutexes */
rb_threadptr_unlock_all_locking_mutexes(th); rb_threadptr_unlock_all_locking_mutexes(th);
retry: TH_PUSH_TAG(th);
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th); if (TH_EXEC_TAG() == 0) {
terminate_all(vm, th); retry:
thread_debug("rb_thread_terminate_all (main thread: %p)\n", (void *)th);
terminate_all(vm, th);
while (!rb_thread_alone()) { while (vm_living_thread_num(vm) > 1) {
int state;
TH_PUSH_TAG(th);
if ((state = TH_EXEC_TAG()) == 0) {
/* /*
* Thread exiting routine in thread_start_func_2 notify * Thread exiting routine in thread_start_func_2 notify
* me when the last sub-thread exit. * me when the last sub-thread exit.
*/ */
sleeping = 1;
native_sleep(th, 0); native_sleep(th, 0);
RUBY_VM_CHECK_INTS_BLOCKING(th); RUBY_VM_CHECK_INTS_BLOCKING(th);
sleeping = 0;
} }
TH_POP_TAG(); }
else {
/* /*
* When caught an exception (e.g. Ctrl+C), let's broadcast * When caught an exception (e.g. Ctrl+C), let's broadcast
* kill request again to ensure killing all threads even * kill request again to ensure killing all threads even
* if they are blocked on sleep, mutex, etc. * if they are blocked on sleep, mutex, etc.
*/ */
if (state) { if (sleeping) {
sleeping = 0;
goto retry; goto retry;
} }
} }
TH_POP_TAG();
} }
static void static void
@ -3054,12 +3063,6 @@ thread_keys_i(ID key, VALUE value, VALUE ary)
return ST_CONTINUE; return ST_CONTINUE;
} }
static int
vm_living_thread_num(rb_vm_t *vm)
{
return (int)vm->living_thread_num;
}
int int
rb_thread_alone(void) rb_thread_alone(void)
{ {