/********************************************************************** The OPTYap Prolog system OPTYap extends the Yap Prolog system to support or-parallel tabling Copyright: R. Rocha and NCC - University of Porto, Portugal File: or.insts.i version: $Id: or.insts.i,v 1.4 2005-05-31 08:24:24 ricroc Exp $ **********************************************************************/ /* -------------------------------- ** ** Scheduler instructions ** ** -------------------------------- */ PBOp(getwork_first_time,e) /* wait for a new parallel goal */ 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); if (worker_id == 0) { finish_yapor(); free_root_choice_point(); /* wait until no one is executing */ while (! BITMAP_empty(GLOBAL_bm_executing_workers)); goto fail; } else { PREG = GETWORK_FIRST_TIME; PREFETCH_OP(PREG); GONext(); } ENDPBOp(); PBOp(getwork,ld) #ifdef TABLING if (DepFr_leader_cp(LOCAL_top_dep_fr) == 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 != 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 == 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,ld) 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,ld) CUT_wait_leftmost(); PREG = NEXTOP(PREG, ld); PREFETCH_OP(PREG); GONext(); ENDPBOp();