Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 09e3275d16de
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 3d7d1b72116c
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Aug 29, 2015

  1. Copy the full SHA
    123fd1e View commit details
  2. Delay tracking VM objects until Thread is running.

    In the case of `Thread.new`, the OS thread will never run because a
    ThreadError exception is raised when no block is passed. If we track the VM
    object that would ultimately contain the reference to the OS thread, we either
    need a way to remove the VM object when eg `Thread.new` raises an exception or
    we will leak these objects. Instead of tracking and then untracking the VM
    object, we create the object untracked and track it if the OS thread starts
    executing.
    brixen committed Aug 29, 2015
    Copy the full SHA
    3d7d1b7 View commit details
Showing with 34 additions and 6 deletions.
  1. +2 −1 vm/builtin/thread.cpp
  2. +2 −0 vm/ontology.cpp
  3. +18 −5 vm/thread_nexus.cpp
  4. +2 −0 vm/thread_nexus.hpp
  5. +1 −0 vm/vm.cpp
  6. +9 −0 vm/vm.hpp
3 changes: 2 additions & 1 deletion vm/builtin/thread.cpp
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ namespace rubinius {

Thread* Thread::create(STATE, Object* self, ThreadFunction function) {
return Thread::create(state, self,
state->shared().thread_nexus()->new_vm(&state->shared()), function);
state->shared().thread_nexus()->new_vm_solo(&state->shared()), function);
}

Thread* Thread::create(STATE, Object* self, VM* vm, ThreadFunction function) {
@@ -328,6 +328,7 @@ namespace rubinius {
State state_obj(vm), *state = &state_obj;

vm->set_current_thread();
state->shared().thread_nexus()->add_vm(vm);

RUBINIUS_THREAD_START(
const_cast<RBX_DTRACE_CHAR_P>(vm->name().c_str()), vm->thread_id(), 0);
2 changes: 2 additions & 0 deletions vm/ontology.cpp
Original file line number Diff line number Diff line change
@@ -122,6 +122,8 @@ namespace rubinius {
Module::bootstrap(state, G(array), G(object), "Array");
Module::bootstrap(state, G(cls_weakref), G(object), "WeakRef");

G(basicobject)->set_const(state, "BasicObject", G(basicobject));

// Create the namespace for various implementation classes
GO(rubinius).set(state->memory()->new_module<Module>(state, "Rubinius"));
GO(runtime).set(state->memory()->new_module<Module>(state, G(rubinius), "Runtime"));
23 changes: 18 additions & 5 deletions vm/thread_nexus.cpp
Original file line number Diff line number Diff line change
@@ -15,23 +15,36 @@ namespace rubinius {
return (vm->thread_phase() & cYielding) == cYielding;
}

VM* ThreadNexus::new_vm(SharedState* shared, const char* name) {
VM* ThreadNexus::new_vm_solo(SharedState* shared, const char* name) {
utilities::thread::SpinLock::LockGuard guard(threads_lock_);

uint32_t max_id = thread_ids_;
uint32_t id = atomic::fetch_and_add(&thread_ids_,
static_cast<uint32_t>(1));
uint32_t id = ++thread_ids_;

if(id < max_id) {
rubinius::bug("exceeded maximum number of threads");
}

VM* vm = new VM(id, *shared, name);
threads_.push_back(vm);
return new VM(id, *shared, name);
}

VM* ThreadNexus::new_vm(SharedState* shared, const char* name) {
VM* vm = new_vm_solo(shared, name);

add_vm(vm);

return vm;
}

void ThreadNexus::add_vm(VM* vm) {
utilities::thread::SpinLock::LockGuard guard(threads_lock_);

if(vm->tracked_p()) return;

vm->set_tracked();
threads_.push_back(vm);
}

void ThreadNexus::delete_vm(VM* vm) {
utilities::thread::SpinLock::LockGuard guard(threads_lock_);

2 changes: 2 additions & 0 deletions vm/thread_nexus.hpp
Original file line number Diff line number Diff line change
@@ -74,6 +74,8 @@ namespace rubinius {
void yielding(VM* vm);
bool locking(VM* vm);
VM* new_vm(SharedState* shared, const char* name = NULL);
VM* new_vm_solo(SharedState* shared, const char* name = NULL);
void add_vm(VM* vm);
void delete_vm(VM* vm);
void after_fork_child(STATE);
void become_managed(VM* vm);
1 change: 1 addition & 0 deletions vm/vm.cpp
Original file line number Diff line number Diff line change
@@ -81,6 +81,7 @@ namespace rubinius {
, constant_missing_reason_(vFound)
, zombie_(false)
, main_thread_(false)
, tracked_(false)
, thread_phase_(ThreadNexus::Phase::cManaged)
, shared(shared)
, waiting_channel_(this, nil<Channel>())
9 changes: 9 additions & 0 deletions vm/vm.hpp
Original file line number Diff line number Diff line change
@@ -113,6 +113,7 @@ namespace rubinius {
bool tooling_;
bool allocation_tracking_;
bool main_thread_;
bool tracked_;

ThreadNexus::Phase thread_phase_;

@@ -158,6 +159,14 @@ namespace rubinius {
return thread_phase_;
}

void set_tracked(bool tracked = true) {
tracked_ = tracked;
}

bool tracked_p() {
return tracked_;
}

void set_thread_phase(ThreadNexus::Phase thread_phase) {
thread_phase_ = thread_phase;
}