4
4
#include " builtin/fiber.hpp"
5
5
#include " builtin/fixnum.hpp"
6
6
#include " builtin/float.hpp"
7
+ #include " builtin/jit.hpp"
7
8
#include " builtin/location.hpp"
8
9
#include " builtin/lookup_table.hpp"
9
10
#include " builtin/native_method.hpp"
11
+ #include " builtin/string.hpp"
12
+ #include " builtin/symbol.hpp"
10
13
#include " builtin/thread.hpp"
11
14
#include " builtin/tuple.hpp"
12
- # include " builtin/symbol.hpp "
15
+
13
16
#include " call_frame.hpp"
14
- #include " dtrace/dtrace.h"
15
17
#include " environment.hpp"
16
- #include " instruments/tooling .hpp"
18
+ #include " metrics .hpp"
17
19
#include " object_utils.hpp"
18
- #include " ontology.hpp"
19
20
#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
+
21
28
#include " util/logger.hpp"
22
29
23
30
#include " missing/gettid.h"
@@ -82,9 +89,15 @@ namespace rubinius {
82
89
return thr;
83
90
}
84
91
92
+ Thread* Thread::create (STATE, VM* vm, ThreadFunction function) {
93
+ return Thread::create (state, G (thread), vm, function);
94
+ }
95
+
85
96
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
+ }
87
99
100
+ Thread* Thread::create (STATE, Object* self, VM* vm, ThreadFunction function) {
88
101
Thread* thr = Thread::create (state, as<Class>(self), vm);
89
102
90
103
thr->function_ = function;
@@ -235,28 +248,88 @@ namespace rubinius {
235
248
return cFalse;
236
249
}
237
250
238
- int Thread::start_thread (STATE, const pthread_attr_t &attrs ) {
251
+ int Thread::start_thread (STATE, void * (*function)( void *) ) {
239
252
Thread* self = this ;
240
253
OnStack<1 > os (state, self);
241
254
242
255
self->init_lock_ .lock ();
243
256
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) {
246
270
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 ;
247
283
}
284
+ }
248
285
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;
253
288
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 );
258
290
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 ;
260
333
}
261
334
262
335
void * Thread::run (void * ptr) {
@@ -277,8 +350,8 @@ namespace rubinius {
277
350
vm->thread_id (), (unsigned int )thread_debug_self ());
278
351
}
279
352
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);
282
355
283
356
NativeMethod::init_thread (state);
284
357
@@ -305,13 +378,7 @@ namespace rubinius {
305
378
vm->thread ->join_lock_ .lock ();
306
379
vm->thread ->stopped ();
307
380
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 ();
315
382
for (LockedObjects::iterator i = los.begin ();
316
383
i != los.end ();
317
384
++i) {
@@ -330,7 +397,11 @@ namespace rubinius {
330
397
shared.clear_critical (state);
331
398
shared.gc_independent ();
332
399
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
+ }
334
405
335
406
RUBINIUS_THREAD_STOP (
336
407
const_cast <RBX_DTRACE_CHAR_P>(vm->name ().c_str ()), vm->thread_id (), 0 );
@@ -345,19 +416,12 @@ namespace rubinius {
345
416
return Primitives::failure ();
346
417
}
347
418
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)) {
354
420
char buf[RBX_STRERROR_BUFSIZE];
355
421
char * err = RBX_STRERROR (error, buf, RBX_STRERROR_BUFSIZE);
356
422
Exception::thread_error (state, err);
357
423
}
358
424
359
- pthread_attr_destroy (&attrs);
360
-
361
425
return cNil;
362
426
}
363
427
0 commit comments