Skip to content

Commit

Permalink
Showing 17 changed files with 60 additions and 329 deletions.
8 changes: 0 additions & 8 deletions vm/builtin/channel.cpp
Original file line number Diff line number Diff line change
@@ -133,20 +133,12 @@ namespace rubinius {
ts.tv_nsec = nano % NANOSECONDS;
}

// We lock to manipulate the wait condition on the VM* so that
// we can sync up properly with another thread trying to wake us
// up right as we're trying to go to sleep.
state->lock(gct, call_frame);

if(!state->check_async(call_frame)) {
state->unlock();
return NULL;
}

state->vm()->wait_on_channel(self);

state->unlock();

self->waiters_++;

bool exception = false;
4 changes: 0 additions & 4 deletions vm/builtin/compiled_code.cpp
Original file line number Diff line number Diff line change
@@ -204,8 +204,6 @@ namespace rubinius {
Object* CompiledCode::default_executor(STATE, CallFrame* call_frame,
Executable* exec, Module* mod, Arguments& args)
{
LockableScopedLock lg(state, &state->shared(), __FILE__, __LINE__);

CompiledCode* code = as<CompiledCode>(exec);
if(code->execute == default_executor) {
const char* reason = 0;
@@ -223,8 +221,6 @@ namespace rubinius {
}
}

lg.unlock();

return code->execute(state, call_frame, exec, mod, args);
}

3 changes: 1 addition & 2 deletions vm/gc/managed.cpp
Original file line number Diff line number Diff line change
@@ -12,8 +12,7 @@ namespace rubinius {

ManagedThread::ManagedThread(uint32_t id, SharedState& ss,
ManagedThread::Kind kind, const char* name)
: Lockable(true)
, shared_(ss)
: shared_(ss)
, run_state_(eIndependent)
, kind_(kind)
, os_thread_(pthread_self())
3 changes: 1 addition & 2 deletions vm/gc/managed.hpp
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
#include "gc/variable_buffer.hpp"
#include "gc/root_buffer.hpp"
#include "gc/root.hpp"
#include "lock.hpp"
#include "metrics.hpp"

#include <algorithm>
@@ -19,7 +18,7 @@ namespace rubinius {

typedef std::vector<ObjectHeader*> LockedObjects;

class ManagedThread : public Lockable {
class ManagedThread {
public:
// WorldState sets the run_state_ directly.
friend class WorldState;
6 changes: 2 additions & 4 deletions vm/global_cache.hpp
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ namespace rubinius {

typedef std_unordered_set<native_int> SeenMethodSet;

class GlobalCache : public Lockable {
class GlobalCache {
public:
struct CacheEntry {
Module* klass;
@@ -44,9 +44,7 @@ namespace rubinius {
static bool resolve(STATE, Symbol* name, Dispatch& msg, LookupData& lookup);
bool resolve_i(STATE, Symbol* name, Dispatch& msg, LookupData& lookup);

GlobalCache()
: Lockable(true)
{
GlobalCache() {
reset();
}

2 changes: 0 additions & 2 deletions vm/internal_threads.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#ifndef RBX_AUXILIARY_THREADS_H
#define RBX_AUXILIARY_THREADS_H

#include "lock.hpp"

#include "util/thread.hpp"

#include <string>
22 changes: 0 additions & 22 deletions vm/lock.cpp

This file was deleted.

240 changes: 0 additions & 240 deletions vm/lock.hpp

This file was deleted.

16 changes: 5 additions & 11 deletions vm/object_memory.cpp
Original file line number Diff line number Diff line change
@@ -54,8 +54,7 @@ namespace rubinius {

/* ObjectMemory methods */
ObjectMemory::ObjectMemory(VM* state, Configuration& config)
: Lockable(true)
, young_(new BakerGC(this, config.gc_young_initial_bytes * 2))
: young_(new BakerGC(this, config.gc_young_initial_bytes * 2))
, mark_sweep_(new MarkSweepGC(this, config))
, immix_(new ImmixGC(this))
, immix_marker_(NULL)
@@ -126,7 +125,6 @@ namespace rubinius {
}

void ObjectMemory::after_fork_child(STATE) {
lock_init(state->vm());
contention_lock_.init();
mature_gc_in_progress_ = false;
}
@@ -520,9 +518,6 @@ namespace rubinius {
if(!collect_young_now && !collect_mature_now) return;
}

// Ok, everyone in stopped! LET'S GC!
SYNC(state);

state->shared().finalizer_handler()->start_collection(state);

if(cDebugThreading) {
@@ -575,8 +570,6 @@ namespace rubinius {
}

state->restart_world();

UNSYNC;
}

void ObjectMemory::collect_young(STATE, GCData* data, YoungCollectStats* stats) {
@@ -1042,7 +1035,8 @@ namespace rubinius {

void ObjectMemory::add_global_capi_handle_location(STATE, capi::Handle** loc,
const char* file, int line) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(state->shared().global_capi_handle_lock());

if(*loc && REFERENCE_P(*loc)) {
if(!capi_handles_->validate(*loc)) {
std::cerr << std::endl << "==================================== ERROR ====================================" << std::endl;
@@ -1092,7 +1086,7 @@ namespace rubinius {
}

void ObjectMemory::del_global_capi_handle_location(STATE, capi::Handle** loc) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(state->shared().global_capi_handle_lock());

for(std::list<capi::GlobalHandle*>::iterator i = global_capi_handle_locations_.begin();
i != global_capi_handle_locations_.end(); ++i) {
@@ -1106,7 +1100,7 @@ namespace rubinius {
}

void ObjectMemory::make_capi_handle_cached(STATE, capi::Handle* handle) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(state->shared().capi_handle_cache_lock());
cached_capi_handles_.push_back(handle);
}

3 changes: 1 addition & 2 deletions vm/object_memory.hpp
Original file line number Diff line number Diff line change
@@ -13,7 +13,6 @@

#include "util/immix.hpp"
#include "util/thread.hpp"
#include "lock.hpp"

#include "shared_state.hpp"

@@ -84,7 +83,7 @@ namespace rubinius {
* mautre generations independently.
*/

class ObjectMemory : public gc::WriteBarrier, public Lockable {
class ObjectMemory : public gc::WriteBarrier {

utilities::thread::SpinLock allocation_lock_;
utilities::thread::SpinLock inflation_lock_;
3 changes: 2 additions & 1 deletion vm/park.cpp
Original file line number Diff line number Diff line change
@@ -4,9 +4,10 @@

namespace rubinius {
Object* Park::park(STATE, CallFrame* call_frame) {
utilities::thread::Mutex::LockGuard lg(mutex_);
if(!state->check_async(call_frame)) return NULL;

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

wake_ = false;
sleeping_ = true;
state->vm()->thread->sleep(state, cTrue);
21 changes: 12 additions & 9 deletions vm/shared_state.cpp
Original file line number Diff line number Diff line change
@@ -31,8 +31,7 @@
namespace rubinius {

SharedState::SharedState(Environment* env, Configuration& config, ConfigParser& cp)
: Lockable(true)
, internal_threads_(0)
: internal_threads_(0)
, signals_(0)
, finalizer_thread_(0)
, console_(0)
@@ -50,10 +49,13 @@ namespace rubinius {
, env_(env)
, tool_broker_(new tooling::ToolBroker)
, ruby_critical_lock_()
, set_critical_lock_()
, fork_exec_lock_()
, capi_ds_lock_()
, capi_locks_lock_()
, capi_constant_lock_()
, global_capi_handle_lock_()
, capi_handle_cache_lock_()
, llvm_state_lock_()
, vm_lock_()
, wait_lock_()
@@ -188,6 +190,7 @@ namespace rubinius {

void SharedState::reset_threads(STATE, GCToken gct, CallFrame* call_frame) {
VM* current = state->vm();
current->after_fork_child(state);

for(ThreadList::iterator i = threads_.begin();
i != threads_.end();
@@ -206,7 +209,6 @@ namespace rubinius {
}
}

vm->unlock();
vm->reset_parked();
}
}
@@ -227,13 +229,15 @@ namespace rubinius {
reset_threads(state, gct, call_frame);

// Reinit the locks for this object
lock_init(state->vm());
global_cache->reset();
ruby_critical_lock_.init();
set_critical_lock_.init();
fork_exec_lock_.init();
capi_ds_lock_.init();
capi_locks_lock_.init();
capi_constant_lock_.init();
global_capi_handle_lock_.init();
capi_handle_cache_lock_.init();
llvm_state_lock_.init();
vm_lock_.init();
wait_lock_.init();
@@ -303,12 +307,11 @@ namespace rubinius {
}

void SharedState::set_critical(STATE, CallFrame* call_frame) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(set_critical_lock_);

if(!ruby_critical_set_ ||
!pthread_equal(ruby_critical_thread_, pthread_self())) {

UNSYNC;
GCIndependent gc_guard(state, call_frame);
ruby_critical_lock_.lock();
ruby_critical_thread_ = pthread_self();
@@ -319,7 +322,7 @@ namespace rubinius {
}

void SharedState::clear_critical(STATE) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(set_critical_lock_);

if(ruby_critical_set_ && pthread_equal(ruby_critical_thread_, pthread_self())) {
ruby_critical_set_ = false;
@@ -330,7 +333,7 @@ namespace rubinius {
void SharedState::enter_capi(STATE, const char* file, int line) {
NativeMethodEnvironment* env = state->vm()->native_method_environment;
if(int lock_index = env->current_native_frame()->capi_lock_index()) {
capi_locks_[lock_index - 1]->lock(state->vm(), file, line);
capi_locks_[lock_index - 1]->lock();
}
}

@@ -355,7 +358,7 @@ namespace rubinius {
return 0;
}

Mutex* lock = new Mutex(true);
utilities::thread::Mutex* lock = new utilities::thread::Mutex(true);
capi_locks_.push_back(lock);

// We use a 1 offset index, so 0 can indicate no lock used
17 changes: 13 additions & 4 deletions vm/shared_state.hpp
Original file line number Diff line number Diff line change
@@ -12,8 +12,6 @@

#include "primitives.hpp"

#include "lock.hpp"

#include "util/thread.hpp"

#include "capi/capi_constants.h"
@@ -66,7 +64,7 @@ namespace rubinius {
struct CallFrame;

typedef std_unordered_set<std::string> CApiBlackList;
typedef std::vector<Mutex*> CApiLocks;
typedef std::vector<utilities::thread::Mutex*> CApiLocks;
typedef std_unordered_map<std::string, int> CApiLockMap;

typedef std::vector<std::string> CApiConstantNameMap;
@@ -84,7 +82,7 @@ namespace rubinius {
* single process.
*/

class SharedState : public Lockable {
class SharedState {
private:
InternalThreads* internal_threads_;
SignalThread* signals_;
@@ -116,12 +114,15 @@ namespace rubinius {
// the name would make it sound.
utilities::thread::Mutex ruby_critical_lock_;
pthread_t ruby_critical_thread_;
utilities::thread::SpinLock set_critical_lock_;

utilities::thread::Mutex fork_exec_lock_;

utilities::thread::SpinLock capi_ds_lock_;
utilities::thread::SpinLock capi_locks_lock_;
utilities::thread::SpinLock capi_constant_lock_;
utilities::thread::SpinLock global_capi_handle_lock_;
utilities::thread::SpinLock capi_handle_cache_lock_;
utilities::thread::SpinLock llvm_state_lock_;
utilities::thread::SpinLock vm_lock_;
utilities::thread::SpinLock wait_lock_;
@@ -293,6 +294,14 @@ namespace rubinius {
return capi_constant_lock_;
}

utilities::thread::SpinLock& global_capi_handle_lock() {
return global_capi_handle_lock_;
}

utilities::thread::SpinLock& capi_handle_cache_lock() {
return capi_handle_cache_lock_;
}

int capi_lock_index(std::string name);

utilities::thread::SpinLock& llvm_state_lock() {
2 changes: 2 additions & 0 deletions vm/state.cpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,8 @@ namespace rubinius {
}

bool State::process_async(CallFrame* call_frame) {
utilities::thread::SpinLock::LockGuard guard(vm_->interrupt_lock());

set_call_frame(call_frame);
vm_->clear_check_local_interrupts();

10 changes: 0 additions & 10 deletions vm/state.hpp
Original file line number Diff line number Diff line change
@@ -163,16 +163,6 @@ namespace rubinius {
}
}

void lock(GCToken gct, CallFrame* call_frame) {
gc_independent(gct, call_frame);
vm_->lock(vm_);
gc_dependent(gct, call_frame);
}

void unlock() {
vm_->unlock();
}

Object* park(GCToken gct, CallFrame* call_frame);

Object* park_timed(GCToken gct, CallFrame* call_frame, struct timespec* ts);
21 changes: 13 additions & 8 deletions vm/vm.cpp
Original file line number Diff line number Diff line change
@@ -73,6 +73,7 @@ namespace rubinius {
, fiber_stacks_(this, shared)
, park_(new Park)
, tooling_env_(NULL)
, interrupt_lock_()
, method_missing_reason_(eNone)
, constant_missing_reason_(vFound)
, zombie_(false)
@@ -322,6 +323,10 @@ namespace rubinius {
om->collect_maybe(&state, gct, call_frame);
}

void VM::after_fork_child(STATE) {
interrupt_lock_.init();
}

void VM::set_const(const char* name, Object* val) {
State state(this);
globals().object->set_const(&state, (char*)name, val);
@@ -370,7 +375,7 @@ namespace rubinius {
}

bool VM::wakeup(STATE, GCToken gct, CallFrame* call_frame) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(interrupt_lock_);

set_check_local_interrupts();
Object* wait = waiting_object_.get();
@@ -384,27 +389,27 @@ namespace rubinius {
#else
pthread_kill(os_thread_, SIGVTALRM);
#endif
UNSYNC;
interrupt_lock_.unlock();
// Wakeup any locks hanging around with contention
om->release_contention(state, gct, call_frame);
return true;
} else if(!wait->nil_p()) {
// We shouldn't hold the VM lock and the IH lock at the same time,
// other threads can grab them and deadlock.
InflatedHeader* ih = wait->inflated_header(state);
UNSYNC;
interrupt_lock_.unlock();
ih->wakeup(state, gct, call_frame, wait);
return true;
} else {
Channel* chan = waiting_channel_.get();

if(!chan->nil_p()) {
UNSYNC;
interrupt_lock_.unlock();
om->release_contention(state, gct, call_frame);
chan->send(state, gct, cNil, call_frame);
return true;
} else if(custom_wakeup_) {
UNSYNC;
interrupt_lock_.unlock();
om->release_contention(state, gct, call_frame);
(*custom_wakeup_)(custom_wakeup_data_);
return true;
@@ -425,7 +430,7 @@ namespace rubinius {
}

void VM::wait_on_channel(Channel* chan) {
utilities::thread::SpinLock::LockGuard guard(shared.wait_lock());
utilities::thread::SpinLock::LockGuard guard(interrupt_lock_);

thread->sleep(this, cTrue);
waiting_channel_.set(chan);
@@ -457,13 +462,13 @@ namespace rubinius {
}

void VM::register_raise(STATE, Exception* exc) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(interrupt_lock_);
interrupted_exception_.set(exc);
set_check_local_interrupts();
}

void VM::register_kill(STATE) {
SYNC(state);
utilities::thread::SpinLock::LockGuard guard(interrupt_lock_);
set_interrupt_by_kill();
set_check_local_interrupts();
}
8 changes: 8 additions & 0 deletions vm/vm.hpp
Original file line number Diff line number Diff line change
@@ -100,6 +100,8 @@ namespace rubinius {
uintptr_t root_stack_start_;
uintptr_t root_stack_size_;

utilities::thread::SpinLock interrupt_lock_;

VMJIT vm_jit_;

MethodMissingReason method_missing_reason_;
@@ -148,6 +150,10 @@ namespace rubinius {
return id_;
}

utilities::thread::SpinLock& interrupt_lock() {
return interrupt_lock_;
}

void set_zombie();

bool zombie_p() {
@@ -246,6 +252,8 @@ namespace rubinius {
constant_missing_reason_ = reason;
}

void after_fork_child(STATE);

bool thread_step() const {
return vm_jit_.thread_step_;
}

0 comments on commit 19e3174

Please sign in to comment.