diff --git a/OPTYap/opt.init.c b/OPTYap/opt.init.c index d7407158d..aee3ab6b3 100644 --- a/OPTYap/opt.init.c +++ b/OPTYap/opt.init.c @@ -122,13 +122,11 @@ void Yap_init_global_optyap_data(int max_table_size, int n_workers, int sch_loop BITMAP_clear(GLOBAL_bm_root_cp_workers); BITMAP_clear(GLOBAL_bm_invisible_workers); BITMAP_clear(GLOBAL_bm_requestable_workers); - BITMAP_clear(GLOBAL_bm_executing_workers); BITMAP_copy(GLOBAL_bm_finished_workers, GLOBAL_bm_present_workers); INIT_LOCK(GLOBAL_locks_bm_idle_workers); INIT_LOCK(GLOBAL_locks_bm_root_cp_workers); INIT_LOCK(GLOBAL_locks_bm_invisible_workers); INIT_LOCK(GLOBAL_locks_bm_requestable_workers); - INIT_LOCK(GLOBAL_locks_bm_executing_workers); INIT_LOCK(GLOBAL_locks_bm_finished_workers); #ifdef TABLING_INNER_CUTS INIT_LOCK(GLOBAL_locks_bm_pruning_workers); diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 25b71a3e5..49520fcdd 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -735,7 +735,6 @@ static Int p_yapor_start( USES_REGS1 ) { GLOBAL_parallel_mode = PARALLEL_MODE_RUNNING; GLOBAL_execution_time = current_time(); BITMAP_clear(GLOBAL_bm_finished_workers); - PUT_IN_EXECUTING(worker_id); return (TRUE); } diff --git a/OPTYap/opt.structs.h b/OPTYap/opt.structs.h index 92d310c1a..566aa4907 100644 --- a/OPTYap/opt.structs.h +++ b/OPTYap/opt.structs.h @@ -235,7 +235,6 @@ struct global_optyap_locks { lockvar bitmap_root_cp_workers; lockvar bitmap_invisible_workers; lockvar bitmap_requestable_workers; - lockvar bitmap_executing_workers; lockvar bitmap_finished_workers; #ifdef TABLING_INNER_CUTS lockvar bitmap_pruning_workers; @@ -309,7 +308,6 @@ struct global_optyap_data { volatile bitmap root_cp_workers; volatile bitmap invisible_workers; volatile bitmap requestable_workers; - volatile bitmap executing_workers; volatile bitmap finished_workers; #ifdef TABLING_INNER_CUTS volatile bitmap pruning_workers; @@ -384,14 +382,12 @@ struct global_optyap_data { #define GLOBAL_bm_root_cp_workers (GLOBAL_optyap_data.root_cp_workers) #define GLOBAL_bm_invisible_workers (GLOBAL_optyap_data.invisible_workers) #define GLOBAL_bm_requestable_workers (GLOBAL_optyap_data.requestable_workers) -#define GLOBAL_bm_executing_workers (GLOBAL_optyap_data.executing_workers) #define GLOBAL_bm_finished_workers (GLOBAL_optyap_data.finished_workers) #define GLOBAL_bm_pruning_workers (GLOBAL_optyap_data.pruning_workers) #define GLOBAL_locks_bm_idle_workers (GLOBAL_optyap_data.locks.bitmap_idle_workers) #define GLOBAL_locks_bm_root_cp_workers (GLOBAL_optyap_data.locks.bitmap_root_cp_workers) #define GLOBAL_locks_bm_invisible_workers (GLOBAL_optyap_data.locks.bitmap_invisible_workers) #define GLOBAL_locks_bm_requestable_workers (GLOBAL_optyap_data.locks.bitmap_requestable_workers) -#define GLOBAL_locks_bm_executing_workers (GLOBAL_optyap_data.locks.bitmap_executing_workers) #define GLOBAL_locks_bm_finished_workers (GLOBAL_optyap_data.locks.bitmap_finished_workers) #define GLOBAL_locks_bm_pruning_workers (GLOBAL_optyap_data.locks.bitmap_pruning_workers) #define GLOBAL_locks_who_locked_heap (GLOBAL_optyap_data.locks.who_locked_heap) diff --git a/OPTYap/or.copy_engine.c b/OPTYap/or.copy_engine.c index 037d2f1d9..0fe4c4c12 100644 --- a/OPTYap/or.copy_engine.c +++ b/OPTYap/or.copy_engine.c @@ -353,6 +353,7 @@ sync_with_p: #endif /* incremental */ /* update registers and return */ + PUT_OUT_ROOT_NODE(worker_id); #ifndef TABLING REMOTE_reply_signal(worker_p) = worker_ready; #endif /* TABLING */ diff --git a/OPTYap/or.insts.i b/OPTYap/or.insts.i index e918e75cd..6e3091540 100644 --- a/OPTYap/or.insts.i +++ b/OPTYap/or.insts.i @@ -17,22 +17,19 @@ PBOp(getwork_first_time,e) /* wait for a new parallel goal */ - while (BITMAP_same(GLOBAL_bm_present_workers, GLOBAL_bm_finished_workers)); + while (BITMAP_same(GLOBAL_bm_present_workers,GLOBAL_bm_finished_workers)); make_root_choice_point(); - PUT_IN_EXECUTING(worker_id); - /* wait until everyone else is executing! */ - while (! BITMAP_same(GLOBAL_bm_present_workers, GLOBAL_bm_executing_workers)); SCHEDULER_GET_WORK(); shared_end: PUT_IN_FINISHED(worker_id); /* wait until everyone else is finished! */ - while (! BITMAP_same(GLOBAL_bm_present_workers, GLOBAL_bm_finished_workers)); - PUT_OUT_EXECUTING(worker_id); + while (! BITMAP_same(GLOBAL_bm_present_workers,GLOBAL_bm_finished_workers)); + PUT_OUT_ROOT_NODE(worker_id); if (worker_id == 0) { finish_yapor(); free_root_choice_point(); /* wait until no one is executing */ - while (! BITMAP_empty(GLOBAL_bm_executing_workers)); + while (! BITMAP_empty(GLOBAL_bm_root_cp_workers)); goto fail; } else { PREG = GETWORK_FIRST_TIME; @@ -43,6 +40,7 @@ + PBOp(getwork,Otapl) #ifdef TABLING if (DepFr_leader_cp(LOCAL_top_dep_fr) == Get_LOCAL_top_cp()) { diff --git a/OPTYap/or.macros.h b/OPTYap/or.macros.h index 60fed95d7..8fe15b034 100644 --- a/OPTYap/or.macros.h +++ b/OPTYap/or.macros.h @@ -18,8 +18,8 @@ /* get a def for NULL */ #include -static inline void PUT_IN_EXECUTING(int); -static inline void PUT_OUT_EXECUTING(int); +static inline void PUT_IN_ROOT_NODE(int); +static inline void PUT_OUT_ROOT_NODE(int); static inline void PUT_IN_FINISHED(int); #ifdef TABLING_INNER_CUTS static inline void PUT_IN_PRUNING(int); @@ -213,25 +213,23 @@ static inline qg_sol_fr_ptr CUT_prune_solution_frames(qg_sol_fr_ptr, int); /* ---------------------- ** ** Engine Stuff ** ** ---------------------- */ - -static inline -void PUT_IN_EXECUTING(int w) { - LOCK(GLOBAL_locks_bm_executing_workers); - BITMAP_insert(GLOBAL_bm_executing_workers, w); - UNLOCK(GLOBAL_locks_bm_executing_workers); +static inline +void PUT_IN_ROOT_NODE(int worker_num) { + LOCK(GLOBAL_locks_bm_root_cp_workers); + BITMAP_insert(GLOBAL_bm_root_cp_workers, worker_num); + UNLOCK(GLOBAL_locks_bm_root_cp_workers); return; } -static inline -void PUT_OUT_EXECUTING(int w) { - LOCK(GLOBAL_locks_bm_executing_workers); - BITMAP_delete(GLOBAL_bm_executing_workers, w); - UNLOCK(GLOBAL_locks_bm_executing_workers); +static inline +void PUT_OUT_ROOT_NODE(int worker_num) { + LOCK(GLOBAL_locks_bm_root_cp_workers); + BITMAP_delete(GLOBAL_bm_root_cp_workers, worker_num); + UNLOCK(GLOBAL_locks_bm_root_cp_workers); return; } - static inline void PUT_IN_FINISHED(int w) { LOCK(GLOBAL_locks_bm_finished_workers); diff --git a/OPTYap/or.scheduler.c b/OPTYap/or.scheduler.c index 023433e1e..4d1302c3f 100644 --- a/OPTYap/or.scheduler.c +++ b/OPTYap/or.scheduler.c @@ -45,8 +45,6 @@ static int search_for_hidden_shared_work(bitmap stable_busy); static inline void PUT_NO_WORK_IN_UPPER_NODES(void); static inline void PUT_IDLE(int); static inline void PUT_BUSY(int); -static inline void PUT_IN_ROOT_NODE(int); -static inline void PUT_OUT_ROOT_NODE(int); static inline void move_up_to_prune_request(void); @@ -81,24 +79,6 @@ void PUT_BUSY(int worker_num) { } -static inline -void PUT_IN_ROOT_NODE(int worker_num) { - LOCK(GLOBAL_locks_bm_root_cp_workers); - BITMAP_insert(GLOBAL_bm_root_cp_workers, worker_num); - UNLOCK(GLOBAL_locks_bm_root_cp_workers); - return; -} - - -static inline -void PUT_OUT_ROOT_NODE(int worker_num) { - LOCK(GLOBAL_locks_bm_root_cp_workers); - BITMAP_delete(GLOBAL_bm_root_cp_workers, worker_num); - UNLOCK(GLOBAL_locks_bm_root_cp_workers); - return; -} - - static inline void move_up_to_prune_request(void) { CACHE_REGS @@ -216,7 +196,7 @@ int get_work(void) { counter = 0; BITMAP_difference(stable_busy, OrFr_members(LOCAL_top_or_fr), GLOBAL_bm_idle_workers); - while (1) { + while (1) { while (BITMAP_subset(GLOBAL_bm_idle_workers, OrFr_members(LOCAL_top_or_fr)) && Get_LOCAL_top_cp() != Get_GLOBAL_root_cp()) { /* no busy workers here and below */ @@ -227,13 +207,17 @@ int get_work(void) { } if (Get_LOCAL_top_cp() == Get_GLOBAL_root_cp()) { if (! BITMAP_member(GLOBAL_bm_root_cp_workers, worker_id)) + /* We need this extra bitmap because the GLOBAL_bm_idle_workers bitmap + is not enough to deal with sequential predicates. The condition of + all workers being idle is not sufficient to ensure that there is no + available computation since a sequential predicate can still be resumed. + Only when all workers are idle and in the root choicepoint it is safe to + finish execution. */ PUT_IN_ROOT_NODE(worker_id); - if (BITMAP_same(GLOBAL_bm_idle_workers, GLOBAL_bm_root_cp_workers) && - BITMAP_same(GLOBAL_bm_idle_workers, GLOBAL_bm_present_workers)) { - /* All workers are idle in root choicepoint. Execution + if (BITMAP_same(GLOBAL_bm_root_cp_workers, GLOBAL_bm_present_workers)) + /* All workers are idle in the root choicepoint. Execution must finish as there is no available computation. */ return FALSE; - } } if (get_work_below()) { PUT_BUSY(worker_id); diff --git a/OPTYap/or.thread_engine.c b/OPTYap/or.thread_engine.c index e5143e7ea..c9a95574b 100644 --- a/OPTYap/or.thread_engine.c +++ b/OPTYap/or.thread_engine.c @@ -216,7 +216,7 @@ int q_share_work(int worker_p) { Yap_CopyThreadStacks(worker_id, worker_p, FALSE); #endif - + PUT_OUT_ROOT_NODE(worker_id); /* update registers and return */ #ifndef TABLING REMOTE_reply_signal(worker_p) = worker_ready;