/************************************************************************ ** ** ** The YapTab/YapOr/OPTYap systems ** ** ** ** YapTab extends the Yap Prolog engine to support sequential tabling ** ** YapOr extends the Yap Prolog engine to support or-parallelism ** ** OPTYap extends the Yap Prolog engine to support or-parallel tabling ** ** ** ** ** ** Yap Prolog was developed at University of Porto, Portugal ** ** ** ************************************************************************/ /* -------------------------------- ** ** Scheduler instructions ** ** -------------------------------- */ PBOp(getwork_first_time,e) /* wait for a new parallel goal */ while (BITMAP_same(Yap_bm_present_workers, Yap_bm_finished_workers)); make_root_choice_point(); PUT_IN_EXECUTING(worker_id); /* wait until everyone else is executing! */ while (! BITMAP_same(Yap_bm_present_workers, Yap_bm_executing_workers)); SCHEDULER_GET_WORK(); shared_end: PUT_IN_FINISHED(worker_id); /* wait until everyone else is finished! */ while (! BITMAP_same(Yap_bm_present_workers, Yap_bm_finished_workers)); PUT_OUT_EXECUTING(worker_id); if (worker_id == 0) { finish_yapor(); free_root_choice_point(); /* wait until no one is executing */ while (! BITMAP_empty(Yap_bm_executing_workers)); goto fail; } else { PREG = GETWORK_FIRST_TIME; PREFETCH_OP(PREG); GONext(); } ENDPBOp(); PBOp(getwork,Otapl) #ifdef TABLING if (DepFr_leader_cp(LOCAL_top_dep_fr) == Get_LOCAL_top_cp()) { /* the current top node is a leader node with consumer nodes below */ if (DepFr_leader_dep_is_on_stack(LOCAL_top_dep_fr)) { /* the frozen branch depends on the current top node ** ** this means that the current top node is a generator node */ LOCK_OR_FRAME(LOCAL_top_or_fr); if (OrFr_alternative(LOCAL_top_or_fr) == NULL || (OrFr_alternative(LOCAL_top_or_fr) == ANSWER_RESOLUTION && B_FZ != Get_LOCAL_top_cp())) { /* there are no unexploited alternatives ** ** (NULL if batched scheduling OR ANSWER_RESOLUTION if local scheduling) */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); goto completion; } else { /* there are unexploited alternatives ** ** we should exploit all the available alternatives before execute completion */ PREG = OrFr_alternative(LOCAL_top_or_fr); PREFETCH_OP(PREG); GONext(); } /* ricroc - obsolete #ifdef batched scheduling if (OrFr_alternative(LOCAL_top_or_fr) != NULL) { #else local scheduling if (OrFr_alternative(LOCAL_top_or_fr) != ANSWER_RESOLUTION || B_FZ == Get_LOCAL_top_cp()) { #endif PREG = OrFr_alternative(LOCAL_top_or_fr); PREFETCH_OP(PREG); GONext(); } UNLOCK_OR_FRAME(LOCAL_top_or_fr); */ } goto completion; } #endif /* TABLING */ LOCK_OR_FRAME(LOCAL_top_or_fr); if (OrFr_alternative(LOCAL_top_or_fr)) { PREG = OrFr_alternative(LOCAL_top_or_fr); PREFETCH_OP(PREG); GONext(); } else { UNLOCK_OR_FRAME(LOCAL_top_or_fr); SCHEDULER_GET_WORK(); } ENDPBOp(); /* The idea is to check whether we are the last worker in the node. If we are, we can go ahead, otherwise we should call the scheduler. */ PBOp(getwork_seq,Otapl) LOCK_OR_FRAME(LOCAL_top_or_fr); if (OrFr_alternative(LOCAL_top_or_fr) && BITMAP_alone(OrFr_members(LOCAL_top_or_fr), worker_id)) { PREG = OrFr_alternative(LOCAL_top_or_fr); PREFETCH_OP(PREG); GONext(); } else { UNLOCK_OR_FRAME(LOCAL_top_or_fr); SCHEDULER_GET_WORK(); } ENDPBOp(); PBOp(sync,Otapl) CUT_wait_leftmost(); PREG = NEXTOP(PREG,Otapl); PREFETCH_OP(PREG); GONext(); ENDPBOp();