int q_share_work(int worker_p) { register tr_fr_ptr aux_tr; register CELL aux_cell; LOCK_OR_FRAME(LOCAL_top_or_fr); if (REMOTE_prune_request(worker_p)) { /* worker p with prune request */ UNLOCK_OR_FRAME(LOCAL_top_or_fr); return FALSE; } YAPOR_ERROR_CHECKING(q_share_work, Get_OrFr_pend_prune_cp(LOCAL_top_or_fr) && BRANCH_LTT(worker_p, OrFr_depth(LOCAL_top_or_fr)) < OrFr_pend_prune_ltt(LOCAL_top_or_fr)); /* there is no pending prune with worker p at right --> safe move to worker p branch */ CUT_reset_prune_request(); if(Get_LOCAL_prune_request()){ UNLOCK_OR_FRAME(LOCAL_top_or_fr); return FALSE; } BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = BRANCH(worker_p, OrFr_depth(LOCAL_top_or_fr)); UNLOCK_OR_FRAME(LOCAL_top_or_fr); /* unbind variables */ aux_tr = LOCAL_top_cp->cp_tr; TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr); while (aux_tr != TR) { aux_cell = TrailTerm(--TR); /* check for global or local variables */ if (IsVarTerm(aux_cell)) { RESET_VARIABLE(aux_cell); #ifdef TABLING } else if (IsPairTerm(aux_cell)) { aux_cell = (CELL) RepPair(aux_cell); if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) { /* avoid frozen segments */ TR = (tr_fr_ptr) aux_cell; TABLING_ERROR_CHECKING(q_share_work, TR > (tr_fr_ptr) LOCAL_TrailTop); TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr); } #endif /* TABLING */ #ifdef MULTI_ASSIGNMENT_VARIABLES } else if (IsApplTerm(aux_cell)) { CELL *aux_ptr = RepAppl(aux_cell); Term aux_val = TrailTerm(--aux_tr); *aux_ptr = aux_val; #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } OPTYAP_ERROR_CHECKING(q_share_work, LOCAL_top_cp != LOCAL_top_cp_on_stack); OPTYAP_ERROR_CHECKING(q_share_work, YOUNGER_CP(B_FZ, LOCAL_top_cp)); YAPOR_ERROR_CHECKING(q_share_work, LOCAL_reply_signal != worker_ready); /* make sharing request */ LOCK_WORKER(worker_p); if (BITMAP_member(GLOBAL_bm_idle_workers, worker_p) || REMOTE_share_request(worker_p) != MAX_WORKERS) { /* worker p is idle or has another request */ UNLOCK_WORKER(worker_p); return FALSE; } REMOTE_share_request(worker_p) = worker_id; UNLOCK_WORKER(worker_p); /* wait for an answer */ while (LOCAL_reply_signal == worker_ready); if (LOCAL_reply_signal == no_sharing) { /* sharing request refused */ LOCAL_reply_signal = worker_ready; return FALSE; } /* copy trail stack ? */ LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > trail) { LOCAL_q_fase_signal = trail; UNLOCK(LOCAL_lock_signals); Q_COPY_TRAIL_FROM(worker_p); } else { UNLOCK(LOCAL_lock_signals); goto sync_with_p; } /* copy global stack ? */ LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > global) { LOCAL_q_fase_signal = global; UNLOCK(LOCAL_lock_signals); Q_COPY_GLOBAL_FROM(worker_p); } else { UNLOCK(LOCAL_lock_signals); goto sync_with_p; } /* copy local stack ? */ while (LOCAL_reply_signal < nodes_shared); LOCK(LOCAL_lock_signals); if (LOCAL_p_fase_signal > local) { LOCAL_q_fase_signal = local; UNLOCK(LOCAL_lock_signals); Q_COPY_LOCAL_FROM(worker_p); } else UNLOCK(LOCAL_lock_signals); sync_with_p: #ifdef TABLING REMOTE_reply_signal(worker_p) = worker_ready; #else REMOTE_reply_signal(worker_p) = copy_done; #endif /* TABLING */ while (LOCAL_reply_signal != copy_done); #if INCREMENTAL_COPY /* install fase --> TR and LOCAL_top_cp->cp_tr are equal */ aux_tr = ((choiceptr) LOCAL_start_local_copy)->cp_tr; TR = ((choiceptr) LOCAL_end_local_copy)->cp_tr; Yap_NEW_MAHASH((ma_h_inner_struct *)HR); while (TR != aux_tr) { aux_cell = TrailTerm(--aux_tr); if (IsVarTerm(aux_cell)) { if (aux_cell < LOCAL_start_global_copy || EQUAL_OR_YOUNGER_CP((choiceptr)LOCAL_end_local_copy, (choiceptr)aux_cell)) { YAPOR_ERROR_CHECKING(q_share_work, (CELL *)aux_cell < H0); YAPOR_ERROR_CHECKING(q_share_work, (ADDR)aux_cell > LOCAL_LocalBase); #ifdef TABLING *((CELL *) aux_cell) = TrailVal(aux_tr); #else *((CELL *) aux_cell) = *((CELL *) (worker_offset(worker_p) + aux_cell)); #endif /* TABLING */ } #ifdef TABLING } else if (IsPairTerm(aux_cell)) { aux_cell = (CELL) RepPair(aux_cell); if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) { /* avoid frozen segments */ aux_tr = (tr_fr_ptr) aux_cell; } #endif /* TABLING */ #ifdef MULTI_ASSIGNMENT_VARIABLES } else if (IsApplTerm(aux_cell)) { CELL *cell_ptr = RepAppl(aux_cell); if (((CELL *)aux_cell < LOCAL_top_cp->cp_h || EQUAL_OR_YOUNGER_CP(LOCAL_top_cp, (choiceptr)aux_cell)) && !Yap_lookup_ma_var(cell_ptr)) { /* first time we found the variable, let's put the new value */ #ifdef TABLING *cell_ptr = TrailVal(aux_tr); #else *cell_ptr = *((CELL *) (worker_offset(worker_p) + (CELL)cell_ptr)); #endif /* TABLING */ } /* skip the old value */ aux_tr--; #endif /* MULTI_ASSIGNMENT_VARIABLES */ } } #endif /* incremental */ /* update registers and return */ PUT_OUT_ROOT_NODE(worker_id); #ifndef TABLING REMOTE_reply_signal(worker_p) = worker_ready; #endif /* TABLING */ TR = (tr_fr_ptr) LOCAL_end_trail_copy; LOCAL_reply_signal = worker_ready; PUT_IN_REQUESTABLE(worker_id); #ifdef TABLING adjust_freeze_registers(); #endif /* TABLING */ return TRUE; }
static size_t save_clauses(FILE *stream, PredEntry *pp) { yamop *FirstC, *LastC; FirstC = pp->cs.p_code.FirstClause; LastC = pp->cs.p_code.LastClause; if (FirstC == NULL && LastC == NULL) { return 1; } if (pp->PredFlags & LogUpdatePredFlag) { LogUpdClause *cl = ClauseCodeToLogUpdClause(FirstC); while (cl != NULL) { if (IN_BETWEEN(cl->ClTimeStart, pp->TimeStampOfPred, cl->ClTimeEnd)) { UInt size = cl->ClSize; CHECK(save_tag(stream, QLY_START_LU_CLAUSE)); CHECK(save_UInt(stream, (UInt)cl)); CHECK(save_UInt(stream, size)); CHECK(save_bytes(stream, cl, size)); } cl = cl->ClNext; } CHECK(save_tag(stream, QLY_END_LU_CLAUSES)); } else if (pp->PredFlags & MegaClausePredFlag) { MegaClause *cl = ClauseCodeToMegaClause(FirstC); UInt size = cl->ClSize; CHECK(save_UInt(stream, (UInt)cl)); CHECK(save_UInt(stream, (UInt)(cl->ClFlags))); CHECK(save_UInt(stream, size)); CHECK(save_bytes(stream, cl, size)); } else if (pp->PredFlags & DynamicPredFlag) { yamop *cl = FirstC; do { DynamicClause *dcl = ClauseCodeToDynamicClause(cl); UInt size = dcl->ClSize; CHECK(save_UInt(stream, (UInt)cl)); CHECK(save_UInt(stream, size)); CHECK(save_bytes(stream, dcl, size)); if (cl == LastC) return 1; cl = NextDynamicClause(cl); } while (TRUE); } else { StaticClause *cl = ClauseCodeToStaticClause(FirstC); if (pp->PredFlags & SYSTEM_PRED_FLAGS) { return 1; } do { UInt size = cl->ClSize; CHECK(save_UInt(stream, (UInt)cl)); CHECK(save_UInt(stream, size)); CHECK(save_bytes(stream, cl, size)); if (cl->ClCode == LastC) return 1; cl = cl->ClNext; } while (TRUE); } return 1; }