Project

General

Profile

Feature #10187 » inline_storage-16.patch

normalperson (Eric Wong), 08/30/2014 01:42 AM

View differences:

insns.def
{
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)ic;
#define RUNNING_THREAD_ONCE_DONE ((rb_thread_t *)(0x1))
retry:
if (is->once.done == Qfalse) {
if (is->once.running_thread == NULL) {
is->once.running_thread = th;
val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
/* is->once.running_thread is cleared by vm_once_clear() */
is->once.done = Qtrue;
rb_iseq_add_mark_object(GET_ISEQ(), val);
}
else if (is->once.running_thread == th) {
/* recursive once */
val = vm_once_exec((VALUE)iseq);
}
else {
/* waiting for finish */
RUBY_VM_CHECK_INTS(th);
rb_thread_schedule();
goto retry;
}
if (is->once.running_thread == RUNNING_THREAD_ONCE_DONE) {
val = is->once.value;
}
else if (is->once.running_thread == NULL) {
is->once.running_thread = th;
val = is->once.value = rb_ensure(vm_once_exec, (VALUE)iseq, vm_once_clear, (VALUE)is);
/* is->once.running_thread is cleared by vm_once_clear() */
is->once.running_thread = RUNNING_THREAD_ONCE_DONE; /* success */
rb_iseq_add_mark_object(GET_ISEQ(), val);
}
else if (is->once.running_thread == th) {
/* recursive once */
val = vm_once_exec((VALUE)iseq);
}
else {
val = is->once.value;
/* waiting for finish */
RUBY_VM_CHECK_INTS(th);
rb_thread_schedule();
goto retry;
}
}
vm_core.h
struct {
struct rb_thread_struct *running_thread;
VALUE value;
VALUE done;
} once;
struct iseq_inline_cache_entry cache;
};
-
(1-1/3)