diff --git a/runtime/debug.h b/runtime/debug.h index e5cadbf0..ddc55c19 100644 --- a/runtime/debug.h +++ b/runtime/debug.h @@ -93,6 +93,12 @@ CHEETAH_INTERNAL extern const char *const __cilkrts_assertion_failed; : cilkrts_bug("%s: %d: cilk_assertion failed: %s (%p) == %s (%p)", \ __FILE__, __LINE__, #P1, _t1, #P2, _t2);}) +#define CILK_ASSERT_INTEGER_EQUAL(I1, I2) \ + ({ long _t1 = (I1), _t2 = (I2); __builtin_expect(_t1 == _t2, 1) \ + ? (void)0 \ + : cilkrts_bug("%s: %d: cilk_assertion failed: %s (%ld) == %s (%ld)", \ + __FILE__, __LINE__, #I1, _t1, #I2, _t2);}) + #define CILK_ASSERT_INDEX_ZERO(LEFT, I, RIGHT, FMT) \ (__builtin_expect(!(LEFT[I] RIGHT), 1) \ ? (void)0 \ diff --git a/runtime/global.h b/runtime/global.h index c1921bc4..c427541a 100644 --- a/runtime/global.h +++ b/runtime/global.h @@ -63,8 +63,7 @@ struct global_state { // These fields are accessed exclusively by the boss thread. - jmpbuf boss_ctx __attribute__((aligned(CILK_CACHE_LINE))); - void *orig_rsp; + void *orig_rsp __attribute__((aligned(CILK_CACHE_LINE))); bool workers_started; // These fields are shared between the boss thread and a couple workers. diff --git a/runtime/init.c b/runtime/init.c index cb47a7c0..e8c0d01b 100644 --- a/runtime/init.c +++ b/runtime/init.c @@ -564,17 +564,9 @@ void __cilkrts_internal_invoke_cilkified_root(__cilkrts_stack_frame *sf) { __cilkrts_start_workers(g); } - if (__builtin_setjmp(g->boss_ctx) == 0) { - CILK_SWITCH_TIMING(w, INTERVAL_CILKIFY_ENTER, INTERVAL_SCHED); - do_what_it_says_boss(w, root_closure); - } else { - // The stack on which - // __cilkrts_internal_invoke_cilkified_root() was called may - // be corrupted at this point, so we call this helper method, - // marked noinline, to ensure the compiler does not try to use - // any data from the stack. - boss_wait_helper(); - } + // XXX Temporary + CILK_SWITCH_TIMING(w, INTERVAL_CILKIFY_ENTER, INTERVAL_SCHED); + do_what_it_says_boss(w, root_closure); } // Finish the execution of a Cilkified region. Executed by the boss worker. diff --git a/runtime/scheduler.c b/runtime/scheduler.c index 7f07a1dc..7e37fc83 100644 --- a/runtime/scheduler.c +++ b/runtime/scheduler.c @@ -212,10 +212,10 @@ static void setup_for_sync(__cilkrts_worker *w, worker_id self, Closure *t) { } static void resume_boss(__cilkrts_worker *w, worker_id self, Closure *t) { - CILK_ASSERT(t->status == CLOSURE_SUSPENDED); - CILK_ASSERT(!Closure_has_children(t)); // TODO: This should not be on any worker's deque Closure_lock(self, t); + CILK_ASSERT_INTEGER_EQUAL(t->status, CLOSURE_SUSPENDED); + CILK_ASSERT(!Closure_has_children(t)); setup_for_sync(w, self, t); Closure_set_status(t, CLOSURE_RUNNING); Closure_unlock(self, t); @@ -1431,6 +1431,7 @@ void do_what_it_says_boss(__cilkrts_worker *w, Closure *t) { CILK_STOP_TIMING(w, INTERVAL_SCHED); worker_change_state(w, WORKER_IDLE); worker_scheduler(w); + cilkrts_bug("boss worker exited scheduling loop"); } void worker_scheduler(__cilkrts_worker *w) { @@ -1483,10 +1484,16 @@ void worker_scheduler(__cilkrts_worker *w) { CILK_START_TIMING(w, INTERVAL_SCHED); CILK_START_TIMING(w, INTERVAL_IDLE); - if (rts->activate_boss) { + if (is_boss && rts->activate_boss) { t = rts->root_closure; resume_boss(w, self, t); rts->activate_boss = false; + /* bookkeeping */ + fails = maybe_reengage_workers + (rts, self, nworkers, w, fails, + &sample_threshold, &inefficient_history, &efficient_history, + sentinel_count_history, &sentinel_count_history_tail, + &recent_sentinel_count); break; } @@ -1662,9 +1669,6 @@ void worker_scheduler(__cilkrts_worker *w) { CILK_STOP_TIMING(w, INTERVAL_SCHED); worker_change_state(w, WORKER_IDLE); - if (is_boss) { - __builtin_longjmp(rts->boss_ctx, 1); - } } void *scheduler_thread_proc(void *arg) { diff --git a/runtime/worker_sleep.h b/runtime/worker_sleep.h index 644c5a9a..0ea058f0 100644 --- a/runtime/worker_sleep.h +++ b/runtime/worker_sleep.h @@ -467,13 +467,12 @@ handle_failed_steal_attempts(global_state *const rts, worker_id self, #endif if (is_boss) { - if (fails % NAP_THRESHOLD == 0 && !rts->activate_boss) { - // The boss thread should never disengage or - // sleep for a long time. + if (fails % NAP_THRESHOLD == 0) { + // The boss thread should never disengage. Sleep instead. const struct timespec sleeptime = { .tv_sec = 0, - .tv_nsec = 1000 - }; + .tv_nsec = + (fails > SLEEP_THRESHOLD) ? SLEEP_NSEC : NAP_NSEC}; nanosleep(&sleeptime, NULL); } } else {