Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 52a39ac

Browse files
committedJul 14, 2015
Merge remote-tracking branch 'origin' into 1.8.7
Conflicts: Gemfile.lock spec/ruby/shared/process/exit.rb
2 parents ab87c8c + abab1ad commit 52a39ac

24 files changed

+372
-1671
lines changed
 

‎Rakefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class SpecRunner
9494
end
9595

9696
def self.set_at_exit_status(status)
97-
@at_exit_status = status
97+
@at_exit_status = status || 1
9898
end
9999

100100
def self.flags

‎library/rubinius/configuration.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Rubinius::ConfigurationVariables.define do |c|
55

66
c.section "gc" do |s|
7-
s.vm_variable "young_bytes", (40 * 1024 * 1024),
7+
s.vm_variable "young_bytes", (30 * 1024 * 1024),
88
"The number of bytes the young generation of the GC should use"
99

1010
s.vm_variable "young_lifetime", 2,

‎spec/ruby/shared/process/exit.rb

+5-4
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@
5353
status.exitstatus.should == 1
5454
end
5555

56-
it "exits immediately when called from a thread" do
56+
it "exits when called from a thread" do
5757
pid = Process.fork do
58-
Thread.new { @object.exit!(1) }
59-
sleep 1
60-
Process.exit!(2)
58+
Thread.new { @object.exit!(1) }.join
59+
60+
# Do not let the main thread complete
61+
sleep
6162
end
6263
pid, status = Process.waitpid2(pid)
6364
status.exitstatus.should == 1

‎vm/builtin/native_function.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ namespace rubinius {
333333
GCTokenImpl gct;
334334
VM* vm = 0;
335335

336-
int calculate_stack = 0;
336+
int stack_address = 0;
337337
if(!env) {
338338
// Apparently we're running in a new thread here, setup
339339
// everything we need here.
@@ -345,7 +345,7 @@ namespace rubinius {
345345
pthread_attr_init(&attrs);
346346
pthread_attr_getstacksize (&attrs, &stack_size);
347347
pthread_attr_destroy(&attrs);
348-
vm->set_root_stack(reinterpret_cast<uintptr_t>(&calculate_stack), stack_size);
348+
vm->set_root_stack(reinterpret_cast<uintptr_t>(&stack_address), stack_size);
349349

350350
// Setup nativemethod handles into thread local
351351
State state(vm);

‎vm/builtin/thread.cpp

+100-36
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,27 @@
44
#include "builtin/fiber.hpp"
55
#include "builtin/fixnum.hpp"
66
#include "builtin/float.hpp"
7+
#include "builtin/jit.hpp"
78
#include "builtin/location.hpp"
89
#include "builtin/lookup_table.hpp"
910
#include "builtin/native_method.hpp"
11+
#include "builtin/string.hpp"
12+
#include "builtin/symbol.hpp"
1013
#include "builtin/thread.hpp"
1114
#include "builtin/tuple.hpp"
12-
#include "builtin/symbol.hpp"
15+
1316
#include "call_frame.hpp"
14-
#include "dtrace/dtrace.h"
1517
#include "environment.hpp"
16-
#include "instruments/tooling.hpp"
18+
#include "metrics.hpp"
1719
#include "object_utils.hpp"
18-
#include "ontology.hpp"
1920
#include "on_stack.hpp"
20-
#include "metrics.hpp"
21+
#include "ontology.hpp"
22+
#include "signal.hpp"
23+
24+
#include "dtrace/dtrace.h"
25+
26+
#include "instruments/tooling.hpp"
27+
2128
#include "util/logger.hpp"
2229

2330
#include "missing/gettid.h"
@@ -82,9 +89,15 @@ namespace rubinius {
8289
return thr;
8390
}
8491

92+
Thread* Thread::create(STATE, VM* vm, ThreadFunction function) {
93+
return Thread::create(state, G(thread), vm, function);
94+
}
95+
8596
Thread* Thread::create(STATE, Object* self, ThreadFunction function) {
86-
VM* vm = state->shared().new_vm();
97+
return Thread::create(state, self, state->shared().new_vm(), function);
98+
}
8799

100+
Thread* Thread::create(STATE, Object* self, VM* vm, ThreadFunction function) {
88101
Thread* thr = Thread::create(state, as<Class>(self), vm);
89102

90103
thr->function_ = function;
@@ -235,28 +248,88 @@ namespace rubinius {
235248
return cFalse;
236249
}
237250

238-
int Thread::start_thread(STATE, const pthread_attr_t &attrs) {
251+
int Thread::start_thread(STATE, void* (*function)(void*)) {
239252
Thread* self = this;
240253
OnStack<1> os(state, self);
241254

242255
self->init_lock_.lock();
243256

244-
if(int error = pthread_create(&self->vm_->os_thread(),
245-
&attrs, Thread::run, (void*)self->vm_)) {
257+
pthread_attr_t attrs;
258+
pthread_attr_init(&attrs);
259+
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
260+
pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
261+
262+
int error;
263+
264+
error = pthread_create(&self->vm_->os_thread(), &attrs,
265+
function, (void*)self->vm_);
266+
267+
pthread_attr_destroy(&attrs);
268+
269+
if(error) {
246270
return error;
271+
} else {
272+
// We can't return from here until the new thread completes a minimal
273+
// initialization. After the initialization, it unlocks init_lock_.
274+
// So, wait here until we can lock init_lock_ after that.
275+
self->init_lock_.lock();
276+
277+
// We locked init_lock_. And we are sure that the new thread completed
278+
// the initialization.
279+
// Locking init_lock_ isn't needed anymore, so unlock it.
280+
self->init_lock_.unlock();
281+
282+
return 0;
247283
}
284+
}
248285

249-
// We can't return from here until the new thread completes a minimal
250-
// initialization. After the initialization, it unlocks init_lock_.
251-
// So, wait here until we can lock init_lock_ after that.
252-
self->init_lock_.lock();
286+
Object* Thread::main_thread(STATE) {
287+
GCTokenImpl gct;
253288

254-
// We locked init_lock_. And we are sure that the new thread completed
255-
// the initialization.
256-
// Locking init_lock_ isn't needed anymore, so unlock it.
257-
self->init_lock_.unlock();
289+
state->vm()->thread->hard_unlock(state, gct, 0);
258290

259-
return 0;
291+
std::string& runtime = state->shared().env()->runtime_path();
292+
293+
G(rubinius)->set_const(state, "Signature",
294+
Integer::from(state, state->shared().env()->signature()));
295+
296+
G(rubinius)->set_const(state, "RUNTIME_PATH", String::create(state,
297+
runtime.c_str(), runtime.size()));
298+
299+
state->vm()->thread->pid(state, Fixnum::from(gettid()));
300+
301+
state->shared().env()->load_kernel(state, runtime);
302+
state->shared().env()->run_file(state, runtime + "/loader.rbc");
303+
304+
state->vm()->thread->alive(state, cTrue);
305+
state->vm()->thread_state()->clear();
306+
307+
state->shared().start_console(state);
308+
state->shared().start_metrics(state);
309+
310+
Object* klass = G(rubinius)->get_const(state, state->symbol("Loader"));
311+
if(klass->nil_p()) {
312+
rubinius::bug("unable to find class Rubinius::Loader");
313+
}
314+
315+
Object* instance = 0;
316+
OnStack<1> os(state, instance);
317+
318+
instance = klass->send(state, 0, state->symbol("new"));
319+
if(instance) {
320+
state->shared().env()->set_loader(instance);
321+
} else {
322+
rubinius::bug("unable to instantiate Rubinius::Loader");
323+
}
324+
325+
// Enable the JIT after the core library has loaded
326+
G(jit)->enable(state);
327+
328+
Object* exit = instance->send(state, 0, state->symbol("main"));
329+
330+
state->shared().signals()->system_exit(state->vm()->thread_state()->raise_value());
331+
332+
return exit;
260333
}
261334

262335
void* Thread::run(void* ptr) {
@@ -277,8 +350,8 @@ namespace rubinius {
277350
vm->thread_id(), (unsigned int)thread_debug_self());
278351
}
279352

280-
int calculate_stack = 0;
281-
vm->set_root_stack(reinterpret_cast<uintptr_t>(&calculate_stack), THREAD_STACK_SIZE);
353+
int stack_address = 0;
354+
vm->set_root_stack(reinterpret_cast<uintptr_t>(&stack_address), THREAD_STACK_SIZE);
282355

283356
NativeMethod::init_thread(state);
284357

@@ -305,13 +378,7 @@ namespace rubinius {
305378
vm->thread->join_lock_.lock();
306379
vm->thread->stopped();
307380

308-
if(!ret) {
309-
if(vm->thread_state()->raise_reason() == cExit) {
310-
vm->shared.env()->halt_and_exit(state);
311-
}
312-
}
313-
314-
LockedObjects& los = vm->locked_objects();
381+
LockedObjects& los = state->vm()->locked_objects();
315382
for(LockedObjects::iterator i = los.begin();
316383
i != los.end();
317384
++i) {
@@ -330,7 +397,11 @@ namespace rubinius {
330397
shared.clear_critical(state);
331398
shared.gc_independent();
332399

333-
vm->set_zombie();
400+
if(vm->main_thread_p() || (!ret && vm->thread_state()->raise_reason() == cExit)) {
401+
state->shared().signals()->system_exit(vm->thread_state()->raise_value());
402+
} else {
403+
vm->set_zombie(state);
404+
}
334405

335406
RUBINIUS_THREAD_STOP(
336407
const_cast<RBX_DTRACE_CHAR_P>(vm->name().c_str()), vm->thread_id(), 0);
@@ -345,19 +416,12 @@ namespace rubinius {
345416
return Primitives::failure();
346417
}
347418

348-
pthread_attr_t attrs;
349-
pthread_attr_init(&attrs);
350-
pthread_attr_setstacksize(&attrs, THREAD_STACK_SIZE);
351-
pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
352-
353-
if(int error = start_thread(state, attrs)) {
419+
if(int error = start_thread(state, Thread::run)) {
354420
char buf[RBX_STRERROR_BUFSIZE];
355421
char* err = RBX_STRERROR(error, buf, RBX_STRERROR_BUFSIZE);
356422
Exception::thread_error(state, err);
357423
}
358424

359-
pthread_attr_destroy(&attrs);
360-
361425
return cNil;
362426
}
363427

‎vm/builtin/thread.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,19 @@ namespace rubinius {
280280
*
281281
* @see Thread::allocate().
282282
*/
283-
static Thread* create(STATE, Object* self, ThreadFunction function);
284283
static Thread* create(STATE, VM* vm);
284+
static Thread* create(STATE, VM* vm, ThreadFunction function);
285+
static Thread* create(STATE, Object* self, ThreadFunction function);
286+
static Thread* create(STATE, Object* self, VM* vm, ThreadFunction function);
285287
static Thread* create(STATE, Class* klass, VM* vm);
286288

287289
static void finalize(STATE, Thread* thread);
288290

289-
int start_thread(STATE, const pthread_attr_t &attrs);
291+
int start_thread(STATE, void* (*function)(void*));
290292
static void* run(void*);
291293

294+
static Object* main_thread(STATE);
295+
292296
public: /* TypeInfo */
293297

294298
class Info : public TypeInfo {

‎vm/drivers/cli.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ int main(int argc, char** argv) {
5252
env.load_conf(path);
5353
}
5454

55-
env.run_from_filesystem();
55+
env.boot();
56+
57+
// If we are here, something went wrong. Otherwise, exit(3) will always
58+
// be called explicitly.
59+
exit_code = -1;
5660
} catch(Assertion *e) {
5761
std::cout << "VM Assertion:" << std::endl;
5862
std::cout << " " << e->reason << std::endl << std::endl;
@@ -130,11 +134,6 @@ int main(int argc, char** argv) {
130134
std::cout << "Runtime exception: " << e.what() << std::endl;
131135
exit_code = 1;
132136
}
133-
134-
env.halt(env.state);
135-
if(!exit_code) {
136-
exit_code = env.exit_code(env.state);
137-
}
138137
}
139138

140139
return exit_code;

0 commit comments

Comments
 (0)
Please sign in to comment.