Skip to content

Commit

Permalink
[Spesh] Tear down spesh worker in full_cleanup
Browse files Browse the repository at this point in the history
If the spesh worker is still active the GC can try to free a lock that
is being held, which leads to an abort in libuv. Stopping the thread
makes full-cleanup work (although it still leaks).

Thread is stopped by signalling with VMNull. Ideally we'd unshift this
to the front of the queue, but that is more complicated.
  • Loading branch information
bdw committed Sep 11, 2018
1 parent 8c6088d commit 95d851f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
3 changes: 3 additions & 0 deletions src/core/instance.h
Expand Up @@ -269,6 +269,9 @@ struct MVMInstance {
/* Mutex taken when install specializations. */
uv_mutex_t mutex_spesh_install;

/* The thread object representing the spesh thread */
MVMObject *spesh_thread;

/* The concurrent queue used to send logs to spesh_thread, provided it
* is enabled. */
MVMObject *spesh_queue;
Expand Down
5 changes: 5 additions & 0 deletions src/core/interp.c
Expand Up @@ -91,6 +91,11 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
* program entry point). */
initial_invoke(tc, invoke_data);

/* initial_invoke is supposed to have setup interpreter state; if it hasn't,
* it wasn't a 'real' thread. */
if (!cur_op)
goto return_label;

/* Set jump point, for if we arrive back in the interpreter from an
* exception thrown from C code. */
setjmp(tc->interp_jump);
Expand Down
2 changes: 2 additions & 0 deletions src/moar.c
Expand Up @@ -500,6 +500,8 @@ static void cleanup_callsite_interns(MVMInstance *instance) {
* should clear up all resources and free all memory; in practice, it falls
* short of this goal at the moment. */
void MVM_vm_destroy_instance(MVMInstance *instance) {
/* Stop spesh worker */
MVM_spesh_worker_teardown(instance->main_thread);
/* Join any foreground threads and flush standard handles. */
MVM_thread_join_foreground(instance->main_thread);
MVM_io_flush_standard_handles(instance->main_thread);
Expand Down
16 changes: 14 additions & 2 deletions src/spesh/worker.c
Expand Up @@ -130,7 +130,10 @@ static void worker(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *arg
}
});
}
else {
else if (MVM_is_null(tc, log_obj)) {
/* This is a stop signal, so quit processing */
break;
} else {
MVM_panic(1, "Unexpected object sent to specialization worker");
}

Expand All @@ -153,6 +156,15 @@ void MVM_spesh_worker_setup(MVMThreadContext *tc) {
tc->instance->spesh_queue = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTQueue);
worker_entry_point = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTCCode);
((MVMCFunction *)worker_entry_point)->body.func = worker;
MVM_thread_run(tc, MVM_thread_new(tc, worker_entry_point, 1));
tc->instance->spesh_thread = MVM_thread_new(tc, worker_entry_point, 1);
MVM_thread_run(tc, tc->instance->spesh_thread);
}
}


void MVM_spesh_worker_teardown(MVMThreadContext *tc) {
/* Send stop sentinel */
MVM_repr_push_o(tc, tc->instance->spesh_queue, tc->instance->VMNull);
/* join thread */
MVM_thread_join(tc, tc->instance->spesh_thread);
}
1 change: 1 addition & 0 deletions src/spesh/worker.h
@@ -1 +1,2 @@
void MVM_spesh_worker_setup(MVMThreadContext *tc);
void MVM_spesh_worker_teardown(MVMThreadContext *tc);

0 comments on commit 95d851f

Please sign in to comment.