2010-04-03 05:58:14 +01:00
|
|
|
/************************************************************************
|
|
|
|
** **
|
|
|
|
** 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 **
|
|
|
|
** **
|
|
|
|
************************************************************************/
|
2005-05-31 09:24:24 +01:00
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
/* -------------------------------- **
|
|
|
|
** Scheduler instructions **
|
|
|
|
** -------------------------------- */
|
|
|
|
|
|
|
|
PBOp(getwork_first_time,e)
|
|
|
|
/* wait for a new parallel goal */
|
2014-02-13 10:13:45 +00:00
|
|
|
while (BITMAP_same(GLOBAL_bm_present_workers,GLOBAL_bm_finished_workers));
|
2001-04-09 20:54:03 +01:00
|
|
|
make_root_choice_point();
|
|
|
|
SCHEDULER_GET_WORK();
|
|
|
|
shared_end:
|
|
|
|
PUT_IN_FINISHED(worker_id);
|
|
|
|
/* wait until everyone else is finished! */
|
2014-02-13 10:13:45 +00:00
|
|
|
while (! BITMAP_same(GLOBAL_bm_present_workers,GLOBAL_bm_finished_workers));
|
|
|
|
PUT_OUT_ROOT_NODE(worker_id);
|
2001-04-09 20:54:03 +01:00
|
|
|
if (worker_id == 0) {
|
|
|
|
finish_yapor();
|
|
|
|
free_root_choice_point();
|
|
|
|
/* wait until no one is executing */
|
2014-02-13 10:13:45 +00:00
|
|
|
while (! BITMAP_empty(GLOBAL_bm_root_cp_workers));
|
2001-04-09 20:54:03 +01:00
|
|
|
goto fail;
|
|
|
|
} else {
|
|
|
|
PREG = GETWORK_FIRST_TIME;
|
|
|
|
PREFETCH_OP(PREG);
|
|
|
|
GONext();
|
|
|
|
}
|
|
|
|
ENDPBOp();
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-13 10:13:45 +00:00
|
|
|
|
2008-09-05 05:22:19 +01:00
|
|
|
PBOp(getwork,Otapl)
|
2001-04-09 20:54:03 +01:00
|
|
|
#ifdef TABLING
|
2010-01-14 15:58:19 +00:00
|
|
|
if (DepFr_leader_cp(LOCAL_top_dep_fr) == Get_LOCAL_top_cp()) {
|
2001-04-09 20:54:03 +01:00
|
|
|
/* 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);
|
2005-04-07 18:56:58 +01:00
|
|
|
if (OrFr_alternative(LOCAL_top_or_fr) == NULL ||
|
2010-01-14 15:58:19 +00:00
|
|
|
(OrFr_alternative(LOCAL_top_or_fr) == ANSWER_RESOLUTION && B_FZ != Get_LOCAL_top_cp())) {
|
2005-04-07 18:56:58 +01:00
|
|
|
/* 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
|
2010-01-14 15:58:19 +00:00
|
|
|
if (OrFr_alternative(LOCAL_top_or_fr) != ANSWER_RESOLUTION || B_FZ == Get_LOCAL_top_cp()) {
|
2005-04-07 18:56:58 +01:00
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
PREG = OrFr_alternative(LOCAL_top_or_fr);
|
|
|
|
PREFETCH_OP(PREG);
|
|
|
|
GONext();
|
|
|
|
}
|
|
|
|
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
|
2005-04-07 18:56:58 +01:00
|
|
|
*/
|
2001-04-09 20:54:03 +01:00
|
|
|
}
|
|
|
|
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. */
|
2008-09-05 05:22:19 +01:00
|
|
|
PBOp(getwork_seq,Otapl)
|
2001-04-09 20:54:03 +01:00
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-09-05 05:22:19 +01:00
|
|
|
PBOp(sync,Otapl)
|
2001-04-09 20:54:03 +01:00
|
|
|
CUT_wait_leftmost();
|
2009-06-17 17:14:16 +01:00
|
|
|
PREG = NEXTOP(PREG,Otapl);
|
2001-04-09 20:54:03 +01:00
|
|
|
PREFETCH_OP(PREG);
|
|
|
|
GONext();
|
|
|
|
ENDPBOp();
|