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: b048f883f0b2
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a34762653a9e
Choose a head ref
  • 3 commits
  • 11 files changed
  • 1 contributor

Commits on May 2, 2016

  1. Fixed setting internal thread size.

    On FreeBSD, setting the stack to 4096 bytes for threads like the Console
    Listener was not sufficient. This resulted in a SEGV while booting Rubinius,
    which happens before the signal handler has been set up, so nothing is shown
    in the logs. This also causes Rubinius to abort while trying to build
    Melbourne, leaving Rubinius in a very difficult to debug configuration.
    brixen committed May 2, 2016
    Copy the full SHA
    4b2a14b View commit details
  2. Copy the full SHA
    ac40cb7 View commit details

Commits on May 3, 2016

  1. Added diagnostics emitter.

    brixen committed May 3, 2016
    Copy the full SHA
    a347626 View commit details
2 changes: 2 additions & 0 deletions machine/builtin/thread.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "memory.hpp"
#include "call_frame.hpp"
#include "environment.hpp"
#include "diagnostics.hpp"
#include "metrics.hpp"
#include "object_utils.hpp"
#include "on_stack.hpp"
@@ -328,6 +329,7 @@ namespace rubinius {

state->shared().start_console(state);
state->shared().start_metrics(state);
state->shared().start_diagnostics(state);

Object* klass = G(rubinius)->get_const(state, state->symbol("Loader"));
if(klass->nil_p()) {
57 changes: 57 additions & 0 deletions machine/diagnostics.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,61 @@
#include "vm.hpp"
#include "state.hpp"
#include "diagnostics.hpp"
#include "environment.hpp"
#include "logger.hpp"

#include <rapidjson/writer.h>

#include <unistd.h>
#include <fcntl.h>

namespace rubinius {
namespace diagnostics {
DiagnosticsData::~DiagnosticsData() {
if(document_) delete document_;
}

void DiagnosticsData::to_string(rapidjson::StringBuffer buffer) {
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);

document_->Accept(writer);
}

FileEmitter::FileEmitter(STATE, std::string path)
: DiagnosticsEmitter()
, path_(path)
, fd_(-1)
{
// TODO: Make this a proper feature of the config facility.
state->shared().env()->expand_config_value(
path_, "$PID", state->shared().pid.c_str());

if((fd_ = ::open(path_.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0660)) < 0) {
logger::error("%s: unable to open diagnostics file: %s",
strerror(errno), path_.c_str());
}
}

void FileEmitter::send_diagnostics(DiagnosticsData* data) {
rapidjson::StringBuffer buffer;
size_t size = buffer.GetSize();

if(::write(fd_, buffer.GetString(), size) < size) {
logger::error("%s: writing diagnostics failed", strerror(errno));
}
}

Diagnostics::Diagnostics(STATE)
: InternalThread(state, "rbx.diagnostics", InternalThread::eSmall)
, list_()
, emitter_(NULL)
, diagnostics_lock_()
, diagnostics_condition_()
{
if(state->shared().config.system_diagnostics_target.value.compare("none")) {
emitter_ = new FileEmitter(state,
state->shared().config.system_diagnostics_target.value);
}
}

void Diagnostics::initialize(STATE) {
@@ -20,12 +66,22 @@ namespace rubinius {

void Diagnostics::wakeup(STATE) {
InternalThread::wakeup(state);

diagnostics_condition_.signal();
}

void Diagnostics::after_fork_child(STATE) {
InternalThread::after_fork_child(state);
}

void Diagnostics::report(DiagnosticsData* data) {
utilities::thread::Mutex::LockGuard guard(diagnostics_lock_);

list_.push_front(data);

diagnostics_condition_.signal();
}

void Diagnostics::run(STATE) {
state->vm()->become_unmanaged();

@@ -44,6 +100,7 @@ namespace rubinius {
}

// Emit data
if(emitter_) emitter_->send_diagnostics(data);
}
}
}
33 changes: 32 additions & 1 deletion machine/diagnostics.hpp
Original file line number Diff line number Diff line change
@@ -5,16 +5,26 @@

#include "util/thread.hpp"

#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>

#include <stdint.h>
#include <list>

namespace rubinius {
namespace diagnostics {
class DiagnosticsData {
rapidjson::Document* document_;

bool modified_;

public:
DiagnosticsData() : modified_(false) { }
DiagnosticsData()
: document_(NULL)
, modified_(false)
{ }
virtual ~DiagnosticsData();


bool modified_p() {
return modified_;
@@ -26,6 +36,8 @@ namespace rubinius {

void log() {
}

void to_string(rapidjson::StringBuffer buffer);
};

class MemoryDiagnostics : public DiagnosticsData {
@@ -40,18 +52,37 @@ namespace rubinius {
{ }
};

class DiagnosticsEmitter {
public:
virtual void send_diagnostics(DiagnosticsData*) = 0;
};

class FileEmitter : public DiagnosticsEmitter {
std::string path_;
int fd_;

public:
FileEmitter(STATE, std::string path);

void send_diagnostics(DiagnosticsData* data);
};

typedef std::list<DiagnosticsData*> DiagnosticsList;

class Diagnostics : public InternalThread {
DiagnosticsList list_;

DiagnosticsEmitter* emitter_;

utilities::thread::Mutex diagnostics_lock_;
utilities::thread::Condition diagnostics_condition_;

public:
Diagnostics(STATE);
virtual ~Diagnostics() { }

void report(DiagnosticsData* data);

void initialize(STATE);
void run(STATE);
void wakeup(STATE);
5 changes: 2 additions & 3 deletions machine/internal_threads.hpp
Original file line number Diff line number Diff line change
@@ -26,9 +26,8 @@ namespace rubinius {
public:

enum StackSize {
eSmall = 0x1000,
eLarge = 0x10000,
eXLarge = 0x100000,
eSmall = 0x10000,
eLarge = 0x100000,
};

InternalThread(STATE, std::string name, StackSize stack_size=eLarge);
2 changes: 1 addition & 1 deletion machine/jit/llvm/state.cpp
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ namespace rubinius {
static const bool debug_search = false;

LLVMState::LLVMState(STATE)
: InternalThread(state, "rbx.jit", InternalThread::eXLarge)
: InternalThread(state, "rbx.jit", InternalThread::eLarge)
, state_(0)
, config_(state->shared().config)
, compile_list_(state)
4 changes: 4 additions & 0 deletions machine/memory.hpp
Original file line number Diff line number Diff line change
@@ -161,6 +161,10 @@ namespace rubinius {
return vm_;
}

SharedState& shared() {
return shared_;
}

Memory* memory() {
return this;
}
2 changes: 1 addition & 1 deletion machine/memory/finalizer.cpp
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ namespace memory {
}

FinalizerThread::FinalizerThread(STATE)
: InternalThread(state, "rbx.finalizer", InternalThread::eXLarge)
: InternalThread(state, "rbx.finalizer", InternalThread::eLarge)
, lists_(NULL)
, live_list_(NULL)
, process_list_(NULL)
5 changes: 4 additions & 1 deletion machine/memory/immix_collector.cpp
Original file line number Diff line number Diff line change
@@ -357,7 +357,10 @@ namespace memory {
(double)diagnostics_.bytes_ / (double)diagnostics_.total_bytes_;

diagnostics_.collections_++;
diagnostics_.modify();

if(memory_->shared().diagnostics()) {
memory_->shared().diagnostics()->report(&diagnostics_);
}
}

allocator_.restart(diagnostics_.percentage_,
2 changes: 1 addition & 1 deletion machine/metrics.cpp
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ namespace rubinius {
}

void FileEmitter::initialize() {
if(!(fd_ = ::open(path_.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0660))) {
if((fd_ = ::open(path_.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0660)) < 0) {
logger::error("%s: unable to open metrics file", strerror(errno));
}

11 changes: 11 additions & 0 deletions machine/shared_state.cpp
Original file line number Diff line number Diff line change
@@ -152,6 +152,17 @@ namespace rubinius {
if(metrics_) metrics_->disable(state);
}

diagnostics::Diagnostics* SharedState::start_diagnostics(STATE) {
if(state->shared().config.system_diagnostics_target.value.compare("none")) {
if(!diagnostics_) {
diagnostics_ = new diagnostics::Diagnostics(state);
diagnostics_->start(state);
}
}

return diagnostics_;
}

void SharedState::after_fork_child(STATE) {
// For now, we disable inline debugging here. This makes inspecting
// it much less confusing.
11 changes: 11 additions & 0 deletions machine/shared_state.hpp
Original file line number Diff line number Diff line change
@@ -47,6 +47,10 @@ namespace rubinius {
class Metrics;
}

namespace diagnostics_ {
class Diagnostics;
}

namespace memory {
class FinalizerThread;
class ManagedThread;
@@ -90,6 +94,7 @@ namespace rubinius {
memory::FinalizerThread* finalizer_thread_;
console::Console* console_;
metrics::Metrics* metrics_;
diagnostics::Diagnostics* diagnostics_;

CApiConstantNameMap capi_constant_name_map_;
CApiConstantHandleMap capi_constant_handle_map_;
@@ -215,6 +220,12 @@ namespace rubinius {
metrics::Metrics* start_metrics(STATE);
void disable_metrics(STATE);

diagnostics::Diagnostics* diagnostics() const {
return diagnostics_;
}

diagnostics::Diagnostics* start_diagnostics(STATE);

Environment* env() const {
return env_;
}