static void signal_child(MVMThreadContext *tc) { MVMThread *child = tc->thread_obj->body.new_child; /* if we still have it, its state will be UNABLE, so steal it. */ if (child) { /* this will never return nonzero, because the child's status * will always be UNABLE or STOLEN. */ signal_one_thread(tc, child->body.tc); while (!MVM_trycas(&tc->thread_obj->body.new_child, tc->thread_obj->body.new_child, NULL)); } }
static MVMuint32 signal_all_but(MVMThreadContext *tc, MVMThread *t, MVMThread *tail) { MVMInstance *ins = tc->instance; MVMuint32 i; MVMuint32 count = 0; MVMThread *next; if (!t) { return 0; } do { next = t->body.next; switch (t->body.stage) { case MVM_thread_stage_starting: case MVM_thread_stage_waiting: case MVM_thread_stage_started: if (t->body.tc != tc) { count += signal_one_thread(tc, t->body.tc); } break; case MVM_thread_stage_exited: GCORCH_LOG(tc, "Thread %d run %d : queueing to clear nursery of thread %d\n", t->body.tc->thread_id); add_work(tc, t->body.tc); break; case MVM_thread_stage_clearing_nursery: GCORCH_LOG(tc, "Thread %d run %d : queueing to destroy thread %d\n", t->body.tc->thread_id); /* last GC run for this thread */ add_work(tc, t->body.tc); break; case MVM_thread_stage_destroyed: GCORCH_LOG(tc, "Thread %d run %d : found a destroyed thread\n"); /* will be cleaned up (removed from the lists) shortly */ break; default: MVM_panic(MVM_exitcode_gcorch, "Corrupted MVMThread or running threads list: invalid thread stage %d", t->body.stage); } } while (next && (t = next)); if (tail) MVM_WB(tc, t, tail); t->body.next = tail; return count; }
static MVMuint32 signal_all_but(MVMThreadContext *tc, MVMThread *t, MVMThread *tail) { MVMuint32 count = 0; MVMThread *next; if (!t) { return 0; } do { next = t->body.next; switch (MVM_load(&t->body.stage)) { case MVM_thread_stage_starting: case MVM_thread_stage_waiting: case MVM_thread_stage_started: if (t->body.tc != tc) { count += signal_one_thread(tc, t->body.tc); } break; case MVM_thread_stage_exited: GCDEBUG_LOG(tc, MVM_GC_DEBUG_ORCHESTRATE, "Thread %d run %d : queueing to clear nursery of thread %d\n", t->body.tc->thread_id); add_work(tc, t->body.tc); break; case MVM_thread_stage_clearing_nursery: GCDEBUG_LOG(tc, MVM_GC_DEBUG_ORCHESTRATE, "Thread %d run %d : queueing to destroy thread %d\n", t->body.tc->thread_id); /* last GC run for this thread */ add_work(tc, t->body.tc); break; case MVM_thread_stage_destroyed: GCDEBUG_LOG(tc, MVM_GC_DEBUG_ORCHESTRATE, "Thread %d run %d : found a destroyed thread\n"); /* will be cleaned up (removed from the lists) shortly */ break; default: MVM_panic(MVM_exitcode_gcorch, "Corrupted MVMThread or running threads list: invalid thread stage %"MVM_PRSz"", MVM_load(&t->body.stage)); } } while (next && (t = next)); if (tail) MVM_gc_write_barrier(tc, (MVMCollectable *)t, (MVMCollectable *)tail); t->body.next = tail; return count; }