Skip to content

Commit

Permalink
Cleaned up checking for interrupted thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen committed Apr 30, 2016
1 parent 11c9a6f commit 0b306fb
Show file tree
Hide file tree
Showing 19 changed files with 107 additions and 154 deletions.
5 changes: 0 additions & 5 deletions core/rubinius.rb
Expand Up @@ -219,11 +219,6 @@ def self.thread_state
raise PrimitiveFailure, "Rubinius.thread_state primitive failed"
end

def self.check_interrupts
Rubinius.primitive :vm_check_interrupts
raise PrimitiveFailure, "Rubinius.check_interrupts primitive failed"
end

# Used to invoke a CompiledCode instance as a script body. Sets up the MAIN
# object as self and bypasses JIT'ing (because why JIT a script you only run
# once).
Expand Down
24 changes: 7 additions & 17 deletions machine/builtin/block_environment.cpp
Expand Up @@ -462,28 +462,18 @@ namespace rubinius {

OnStack<2> os(state, env, mod);

// Check the stack and interrupts here rather than in the interpreter
// loop itself.
if(state->check_interrupts(state)) {
tooling::BlockEntry method(state, env, mod);
value = (*mcode->run)(state, mcode);
}
tooling::BlockEntry method(state, env, mod);
value = (*mcode->run)(state, mcode);
} else {
// Check the stack and interrupts here rather than in the interpreter
// loop itself.
if(state->check_interrupts(state)) {
value = (*mcode->run)(state, mcode);
}
}
#else
// Check the stack and interrupts here rather than in the interpreter
// loop itself.
if(state->check_interrupts(state)) {
value = (*mcode->run)(state, mcode);
}
#else
value = (*mcode->run)(state, mcode);
#endif

state->vm()->pop_call_frame(previous_frame);
if(!state->vm()->pop_call_frame(state, previous_frame)) {
return NULL;
}

return value;
}
Expand Down
6 changes: 3 additions & 3 deletions machine/builtin/channel.cpp
Expand Up @@ -134,7 +134,7 @@ namespace rubinius {
ts.tv_nsec = nano % NANOSECONDS;
}

if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
return NULL;
}

Expand All @@ -161,7 +161,7 @@ namespace rubinius {

// or there are values available.
if(self->semaphore_count() > 0 || !self->value()->empty_p()) break;
if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
exception = true;
break;
}
Expand All @@ -173,7 +173,7 @@ namespace rubinius {
self->unpin();
self->_waiters_--;

if(exception || !state->check_async(state)) return NULL;
if(exception) return NULL;

if(self->semaphore_count() > 0) {
self->dec_semaphore_count();
Expand Down
7 changes: 6 additions & 1 deletion machine/builtin/fiber.cpp
Expand Up @@ -155,10 +155,15 @@ namespace rubinius {

cur = Fiber::current(state);

// TODO: clean up this and the following conditional.
if(state->vm()->thread_interrupted_p(state)) {
return NULL;
}

if(!cur->exception()->nil_p()) {
state->raise_exception(cur->exception());
cur->exception(state, nil<Exception>());
return 0;
return NULL;
}

Array* ret = cur->value();
Expand Down
10 changes: 5 additions & 5 deletions machine/builtin/io.cpp
Expand Up @@ -288,7 +288,7 @@ namespace rubinius {

if(events == -1) {
if(errno == EAGAIN || errno == EINTR) {
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;

// Recalculate the limit and go again.
if(maybe_limit) {
Expand Down Expand Up @@ -678,7 +678,7 @@ namespace rubinius {

if(bytes_read == -1) {
if(errno == EAGAIN || errno == EINTR) {
if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
if(malloc_buf) free(malloc_buf);
return NULL;
}
Expand Down Expand Up @@ -967,7 +967,7 @@ namespace rubinius {

if(bytes_read == -1) {
if(errno == EINTR) {
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;
ensure_open(state);
goto retry;
} else {
Expand Down Expand Up @@ -1321,7 +1321,7 @@ namespace rubinius {

if(code == -1) {
if(errno == EAGAIN || errno == EINTR) {
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;
ensure_open(state);
goto retry;
}
Expand Down Expand Up @@ -1429,7 +1429,7 @@ namespace rubinius {
break;
case EAGAIN:
case EINTR:
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;
io->ensure_open(state);
goto retry;
default:
Expand Down
11 changes: 5 additions & 6 deletions machine/builtin/native_method.cpp
Expand Up @@ -741,7 +741,7 @@ namespace rubinius {
} catch(const RubyException& exc) {
LEAVE_CAPI(state);

state->vm()->pop_call_frame(previous_frame);
state->vm()->pop_call_frame(state, previous_frame);
env->set_current_call_frame(saved_frame);
env->set_current_native_frame(nmf.previous());
ep.pop(env);
Expand All @@ -751,15 +751,14 @@ namespace rubinius {

LEAVE_CAPI(state);

state->vm()->pop_call_frame(previous_frame);
if(!state->vm()->pop_call_frame(state, previous_frame)) {
value = NULL;
}

env->set_current_call_frame(saved_frame);
env->set_current_native_frame(nmf.previous());
ep.pop(env);

// Handle any signals that occurred while the native method
// was running.
if(!state->check_async(state)) return NULL;

return value;
}

Expand Down
14 changes: 3 additions & 11 deletions machine/builtin/system.cpp
Expand Up @@ -657,7 +657,7 @@ namespace rubinius {
switch(errno) {
case EAGAIN:
case EINTR:
if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
close(output[0]);
return NULL;
}
Expand Down Expand Up @@ -783,7 +783,7 @@ namespace rubinius {
if(pid == -1) {
if(errno == ECHILD) return cFalse;
if(errno == EINTR) {
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;
goto retry;
}

Expand Down Expand Up @@ -1091,19 +1091,11 @@ namespace rubinius {
if(!state->park(state)) return NULL;
}

if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;

return Fixnum::from(time(0) - start);
}

Object* System::vm_check_interrupts(STATE) {
if(state->check_async(state)) {
return cNil;
} else {
return NULL;
}
}

static inline double tv_to_dbl(struct timeval* tv) {
return (double)tv->tv_sec + ((double)tv->tv_usec / 1000000.0);
}
Expand Down
3 changes: 0 additions & 3 deletions machine/builtin/system.hpp
Expand Up @@ -167,9 +167,6 @@ namespace rubinius {
// Rubinius.primitive :vm_sleep
static Object* vm_sleep(STATE, Object* duration);

// Rubinius.primitive :vm_check_interrupts
static Object* vm_check_interrupts(STATE);

// Rubinius.primitive :vm_times
static Array* vm_times(STATE);

Expand Down
5 changes: 3 additions & 2 deletions machine/capi/capi.cpp
Expand Up @@ -58,9 +58,10 @@ namespace rubinius {
return false;
}

if(unlikely(state->check_local_interrupts())) {
if(!state->process_async(state)) return false;
if(unlikely(state->vm()->check_local_interrupts())) {
return state->vm()->check_thread_raise_or_kill(state);
}

return true;
}

Expand Down
4 changes: 2 additions & 2 deletions machine/capi/thread.cpp
Expand Up @@ -63,7 +63,7 @@ extern "C" {
ret = select(max, read, write, except, tvp);
}

bool ok = env->state()->check_async(env->state());
bool ok = !env->state()->vm()->thread_interrupted_p(env->state());

ENTER_CAPI(env->state());

Expand Down Expand Up @@ -199,7 +199,7 @@ extern "C" {
State* state = env->state();
void* ret = NULL;

if(!state->check_async(env->state())) {
if(state->vm()->thread_interrupted_p(state)) {
return ret;
}
if(ubf == RUBY_UBF_IO || ubf == RUBY_UBF_PROCESS) {
Expand Down
2 changes: 0 additions & 2 deletions machine/instructions.def
Expand Up @@ -1766,8 +1766,6 @@ instruction check_interrupts() [ -- ]
mcode->call_count++;
}

if(!state->check_async(state)) RUN_EXCEPTION();

state->vm()->checkpoint(state);
end

Expand Down
12 changes: 1 addition & 11 deletions machine/jit/llvm/util.cpp
Expand Up @@ -179,7 +179,7 @@ extern "C" {
}

void rbx_pop_call_frame(STATE) {
state->vm()->pop_call_frame(state->vm()->call_frame()->previous);
state->vm()->pop_call_frame(state, state->vm()->call_frame()->previous);
}

Object* rbx_splat_send(STATE, CallSite* call_site,
Expand Down Expand Up @@ -1007,20 +1007,10 @@ extern "C" {
}

Object* rbx_prologue_check(STATE) {
if(!state->check_interrupts(state)) return NULL;

// TODO: ensure no stack references exist at this point
// state->vm()->checkpoint(state);

return cTrue;
}

Object* rbx_check_interrupts(STATE) {
if(!state->check_async(state)) return NULL;

// TODO: ensure no stack references exist at this point
// state->vm()->checkpoint(state);

return cTrue;
}

Expand Down
37 changes: 14 additions & 23 deletions machine/machine_code.cpp
Expand Up @@ -792,29 +792,25 @@ namespace rubinius {
// Check the stack and interrupts here rather than in the interpreter
// loop itself.
OnStack<2> os(state, exec, code);
if(state->check_interrupts(state)) {
tooling::MethodEntry method(state, exec, scope->module(), args, code);
tooling::MethodEntry method(state, exec, scope->module(), args, code);

RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name());
value = (*mcode->run)(state, mcode);
RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name());
}
RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name());
value = (*mcode->run)(state, mcode);
RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name());
} else {
if(state->check_interrupts(state)) {
RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name());
value = (*mcode->run)(state, mcode);
RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name());
}
}
#else
if(state->check_interrupts(state)) {
RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name());
value = (*mcode->run)(state, mcode);
RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name());
}
#else
RUBINIUS_METHOD_ENTRY_HOOK(state, scope->module(), args.name());
value = (*mcode->run)(state, mcode);
RUBINIUS_METHOD_RETURN_HOOK(state, scope->module(), args.name());
#endif

state->vm()->pop_call_frame(previous_frame);
if(!state->vm()->pop_call_frame(state, previous_frame)) {
return NULL;
}

return value;
}
Expand Down Expand Up @@ -857,21 +853,16 @@ namespace rubinius {
return NULL;
}

// Do NOT check if we should JIT this. We NEVER want to jit a script.

// Check the stack and interrupts here rather than in the interpreter
// loop itself.

if(!state->check_interrupts(state)) return NULL;

state->vm()->checkpoint(state);

// Don't generate profiling info here, it's expected
// to be done by the caller.

Object* value = (*mcode->run)(state, mcode);

state->vm()->pop_call_frame(previous_frame);
if(!state->vm()->pop_call_frame(state, previous_frame)) {
return NULL;
}

return value;
}
Expand Down
2 changes: 1 addition & 1 deletion machine/memory/finalizer.cpp
Expand Up @@ -225,7 +225,7 @@ namespace memory {
(*process_item_->finalizer)(state, process_item_->object);
}

state->vm()->pop_call_frame(previous_frame);
state->vm()->pop_call_frame(state, previous_frame);
env->set_current_call_frame(0);
env->set_current_native_frame(0);
} else {
Expand Down
8 changes: 4 additions & 4 deletions machine/park.cpp
Expand Up @@ -9,7 +9,7 @@

namespace rubinius {
Object* Park::park(STATE) {
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;

utilities::thread::Mutex::LockGuard lg(mutex_);

Expand All @@ -25,7 +25,7 @@ namespace rubinius {
cond_.wait(mutex_);
}
mutex_.unlock();
if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
mutex_.lock();
result = NULL;
break;
Expand All @@ -40,7 +40,7 @@ namespace rubinius {

Object* Park::park_timed(STATE, struct timespec* ts) {
utilities::thread::Mutex::LockGuard lg(mutex_);
if(!state->check_async(state)) return NULL;
if(state->vm()->thread_interrupted_p(state)) return NULL;

wake_ = false;
sleeping_ = true;
Expand All @@ -59,7 +59,7 @@ namespace rubinius {
}
}
mutex_.unlock();
if(!state->check_async(state)) {
if(state->vm()->thread_interrupted_p(state)) {
mutex_.lock();
timeout = NULL;
break;
Expand Down

0 comments on commit 0b306fb

Please sign in to comment.