This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
vsc 8dcee4415b library(system) plus several new support builtins
much improved garbage collector
improvements to compiler
yaptab compiles again


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@34 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
2001-05-21 20:00:05 +00:00

730 lines
24 KiB
C

/* ------------------ **
** Includes **
** ------------------ */
#include "Yap.h"
#ifdef ENV_COPY
#include "Yatom.h"
#include "Heap.h"
#include "or.macros.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef TABLING
#include "tab.macros.h"
#else
#include "opt.mavar.h"
#endif /* TABLING */
/* ------------------------------------- **
** Local functions declaration **
** ------------------------------------- */
static void share_private_nodes(int worker_q);
/* ---------------------- **
** Local macros **
** ---------------------- */
#define COMPUTE_SEGMENTS_TO_COPY_TO(Q) \
REMOTE_start_global_copy(Q) = (CELL) (REMOTE_top_cp(Q)->cp_h); \
REMOTE_end_global_copy(Q) = (CELL) (B->cp_h); \
REMOTE_start_local_copy(Q) = (CELL) (B); \
REMOTE_end_local_copy(Q) = (CELL) (REMOTE_top_cp(Q)); \
REMOTE_start_trail_copy(Q) = (CELL) (REMOTE_top_cp(Q)->cp_tr); \
REMOTE_end_trail_copy(Q) = (CELL) (TR)
#define P_COPY_GLOBAL_TO(Q) \
memcpy((void *) (worker_offset(Q) + REMOTE_start_global_copy(Q)), \
(void *) REMOTE_start_global_copy(Q), \
(size_t) (REMOTE_end_global_copy(Q) - REMOTE_start_global_copy(Q)))
#define Q_COPY_GLOBAL_FROM(P) \
memcpy((void *) LOCAL_start_global_copy, \
(void *) (worker_offset(P) + LOCAL_start_global_copy), \
(size_t) (LOCAL_end_global_copy - LOCAL_start_global_copy))
#define P_COPY_LOCAL_TO(Q) \
memcpy((void *) (worker_offset(Q) + REMOTE_start_local_copy(Q)), \
(void *) REMOTE_start_local_copy(Q), \
(size_t) (REMOTE_end_local_copy(Q) - REMOTE_start_local_copy(Q)))
#define Q_COPY_LOCAL_FROM(P) \
memcpy((void *) LOCAL_start_local_copy, \
(void *) (worker_offset(P) + LOCAL_start_local_copy), \
(size_t) (LOCAL_end_local_copy - LOCAL_start_local_copy))
#define P_COPY_TRAIL_TO(Q) \
memcpy((void *) (worker_offset(Q) + REMOTE_start_trail_copy(Q)), \
(void *) REMOTE_start_trail_copy(Q), \
(size_t) (REMOTE_end_trail_copy(Q) - REMOTE_start_trail_copy(Q)))
#define Q_COPY_TRAIL_FROM(P) \
memcpy((void *) LOCAL_start_trail_copy, \
(void *) (worker_offset(P) + LOCAL_start_trail_copy), \
(size_t) (LOCAL_end_trail_copy - LOCAL_start_trail_copy))
/* -------------------------- **
** Global functions **
** -------------------------- */
void make_root_choice_point(void) {
if (worker_id == 0) {
LOCAL_top_cp = GLOBAL_root_cp = OrFr_node(GLOBAL_root_or_fr) = B;
} else {
B = LOCAL_top_cp = GLOBAL_root_cp;
B->cp_tr = TR = ((choiceptr) (worker_offset(0) + (CELL)(B)))->cp_tr;
}
B->cp_h = H0;
B->cp_ap = GETWORK;
B->cp_or_fr = GLOBAL_root_or_fr;
LOCAL_top_or_fr = GLOBAL_root_or_fr;
LOCAL_load = 0;
LOCAL_prune_request = NULL;
BRANCH(worker_id, 0) = 0;
#ifdef TABLING_INNER_CUTS
LOCAL_pruning_scope = NULL;
#endif /* TABLING_INNER_CUTS */
#ifdef TABLING
LOCAL_top_cp_on_stack = LOCAL_top_cp;
adjust_freeze_registers();
#endif /* TABLING */
}
void free_root_choice_point(void) {
B = LOCAL_top_cp->cp_b;
#ifdef TABLING
LOCAL_top_cp_on_stack =
#endif /* TABLING */
LOCAL_top_cp = GLOBAL_root_cp = OrFr_node(GLOBAL_root_or_fr) = B_BASE;
return;
}
void p_share_work(void) {
int worker_q = LOCAL_share_request;
if (! BITMAP_member(OrFr_members(REMOTE_top_or_fr(worker_q)), worker_id) ||
B == REMOTE_top_cp(worker_q) ||
(LOCAL_load <= DELAYED_RELEASE_LOAD && OrFr_nearest_livenode(LOCAL_top_or_fr) == NULL)) {
/* refuse sharing request */
REMOTE_reply_signal(LOCAL_share_request) = no_sharing;
LOCAL_share_request = MAX_WORKERS;
PUT_OUT_REQUESTABLE(worker_id);
return;
}
/* sharing request accepted */
COMPUTE_SEGMENTS_TO_COPY_TO(worker_q);
REMOTE_q_fase_signal(worker_q) = Q_idle;
REMOTE_p_fase_signal(worker_q) = P_idle;
#ifndef TABLING
/* wait for incomplete installations */
while (LOCAL_reply_signal != ready);
#endif /* TABLING */
LOCAL_reply_signal = sharing;
REMOTE_reply_signal(worker_q) = sharing;
share_private_nodes(worker_q);
REMOTE_reply_signal(worker_q) = nodes_shared;
/* copy local stack ? */
LOCK(REMOTE_lock_signals(worker_q));
if (REMOTE_q_fase_signal(worker_q) < local) {
REMOTE_p_fase_signal(worker_q) = local;
UNLOCK(REMOTE_lock_signals(worker_q));
P_COPY_LOCAL_TO(worker_q);
} else {
UNLOCK(REMOTE_lock_signals(worker_q));
goto sync_with_q;
}
/* copy global stack ? */
LOCK(REMOTE_lock_signals(worker_q));
if (REMOTE_q_fase_signal(worker_q) < global) {
REMOTE_p_fase_signal(worker_q) = global;
UNLOCK(REMOTE_lock_signals(worker_q));
P_COPY_GLOBAL_TO(worker_q);
} else {
UNLOCK(REMOTE_lock_signals(worker_q));
goto sync_with_q;
}
/* copy trail stack ? */
LOCK(REMOTE_lock_signals(worker_q));
if (REMOTE_q_fase_signal(worker_q) < trail) {
REMOTE_p_fase_signal(worker_q) = trail;
UNLOCK(REMOTE_lock_signals(worker_q));
P_COPY_TRAIL_TO(worker_q);
} else UNLOCK(REMOTE_lock_signals(worker_q));
sync_with_q:
REMOTE_reply_signal(worker_q) = copy_done;
while (LOCAL_reply_signal == sharing);
LOCAL_share_request = MAX_WORKERS;
PUT_IN_REQUESTABLE(worker_id);
return;
}
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;
}
#ifdef YAPOR_ERRORS
if (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))
YAPOR_ERROR_MESSAGE("prune ltt > worker_p branch ltt (q_share_work)");
#endif /* YAPOR_ERRORS */
/* there is no pending prune with worker p at right --> safe move to worker p branch */
BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = BRANCH(worker_p, OrFr_depth(LOCAL_top_or_fr));
LOCAL_prune_request = NULL;
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
/* unbind variables */
aux_tr = LOCAL_top_cp->cp_tr;
printf("%d: Starting variable unbinding %p---%p\n", worker_id, TR, aux_tr);
#ifdef TABLING_ERRORS
if (TR < aux_tr)
TABLING_ERROR_MESSAGE("TR < aux_tr (q_share_work)");
#endif /* TABLING_ERRORS */
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)) {
/* avoid frozen segments */
aux_cell = (CELL) RepPair(aux_cell);
if ((ADDR) aux_cell >= TrailBase) {
TR = (tr_fr_ptr) aux_cell;
#ifdef TABLING_ERRORS
if (TR > (tr_fr_ptr) TrailTop)
TABLING_ERROR_MESSAGE("TR > TrailTop (q_share_work)");
if (TR < aux_tr)
TABLING_ERROR_MESSAGE("TR < aux_tr (q_share_work)");
#endif /* TABLING_ERRORS */
}
#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
}
}
#ifdef OPTYAP_ERRORS
if (LOCAL_top_cp != LOCAL_top_cp_on_stack)
OPTYAP_ERROR_MESSAGE("LOCAL_top_cp != LOCAL_top_cp_on_stack (q_share_work)");
if (YOUNGER_CP(B_FZ, LOCAL_top_cp))
OPTYAP_ERROR_MESSAGE("YOUNGER_CP(B_FZ, LOCAL_top_cp) (q_share_work)");
#endif /* OPTYAP_ERRORS */
#ifdef YAPOR_ERRORS
if (LOCAL_reply_signal != ready)
YAPOR_ERROR_MESSAGE("LOCAL_reply_signal != ready (q_share_work)");
#endif /* YAPOR_ERRORS */
/* 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 == ready);
if (LOCAL_reply_signal == no_sharing) {
/* sharing request refused */
LOCAL_reply_signal = 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) = ready;
#else
REMOTE_reply_signal(worker_p) = copy_done;
#endif /* TABLING */
while (LOCAL_reply_signal != copy_done);
/* install fase --> TR and LOCAL_top_cp->cp_tr are equal */
aux_tr = ((choiceptr) LOCAL_start_local_copy)->cp_tr;
NEW_MAHASH((ma_h_inner_struct *)H);
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)) {
#ifdef YAPOR_ERRORS
if ((CELL *)aux_cell < H0)
YAPOR_ERROR_MESSAGE("aux_cell < H0 (q_share_work)");
if ((ADDR)aux_cell > LocalBase)
YAPOR_ERROR_MESSAGE("aux_cell > LocalBase (q_share_work)");
#endif /* YAPOR_ERRORS */
#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)) {
/* avoid frozen segments */
aux_cell = (CELL) RepPair(aux_cell);
if ((ADDR) aux_cell >= TrailBase)
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)) &&
!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
}
}
/* update registers and return */
#ifndef TABLING
REMOTE_reply_signal(worker_p) = ready;
#endif /* TABLING */
LOCAL_reply_signal = ready;
PUT_IN_REQUESTABLE(worker_id);
TR = (tr_fr_ptr) LOCAL_end_trail_copy;
#ifdef TABLING
adjust_freeze_registers();
#endif /* TABLING */
return TRUE;
}
/* ------------------------- **
** Local functions **
** ------------------------- */
static
void share_private_nodes(int worker_q) {
choiceptr sharing_node = B;
#ifdef OPTYAP_ERRORS
if (YOUNGER_CP(LOCAL_top_cp, LOCAL_top_cp_on_stack)) {
OPTYAP_ERROR_MESSAGE("YOUNGER_CP(LOCAL_top_cp, LOCAL_top_cp_on_stack) (share_private_nodes)");
} else {
choiceptr aux_cp = B;
while (aux_cp != LOCAL_top_cp) {
if (YOUNGER_CP(LOCAL_top_cp, aux_cp)) {
OPTYAP_ERROR_MESSAGE("LOCAL_top_cp not in branch (share_private_nodes)");
break;
}
if (EQUAL_OR_YOUNGER_CP(LOCAL_top_cp_on_stack, aux_cp)) {
OPTYAP_ERROR_MESSAGE("shared frozen segments in branch (share_private_nodes)");
break;
}
aux_cp = aux_cp->cp_b;
}
}
#endif /* OPTYAP_ERRORS */
#ifdef TABLING
/* check if the branch is already shared */
if (EQUAL_OR_YOUNGER_CP(LOCAL_top_cp_on_stack, sharing_node)) {
or_fr_ptr or_frame;
sg_fr_ptr sg_frame;
dep_fr_ptr dep_frame;
#ifdef OPTYAP_ERRORS
{ or_fr_ptr aux_or_fr;
aux_or_fr = LOCAL_top_or_fr;
while (aux_or_fr != REMOTE_top_or_fr(worker_q)) {
if (YOUNGER_CP(OrFr_node(REMOTE_top_or_fr(worker_q)), OrFr_node(aux_or_fr))) {
OPTYAP_ERROR_MESSAGE("YOUNGER_CP(OrFr_node(REMOTE_top_or_fr(worker_q)), OrFr_node(aux_or_fr)) (share_private_nodes)");
break;
}
aux_or_fr = OrFr_next_on_stack(aux_or_fr);
}
}
#endif /* OPTYAP_ERRORS */
/* update old shared nodes */
or_frame = LOCAL_top_or_fr;
while (or_frame != REMOTE_top_or_fr(worker_q)) {
LOCK_OR_FRAME(or_frame);
BRANCH(worker_q, OrFr_depth(or_frame)) = BRANCH(worker_id, OrFr_depth(or_frame));
OrFr_owners(or_frame)++;
if (BITMAP_member(OrFr_members(or_frame), worker_id))
BITMAP_insert(OrFr_members(or_frame), worker_q);
UNLOCK_OR_FRAME(or_frame);
or_frame = OrFr_next_on_stack(or_frame);
}
/* update worker Q top subgoal frame */
sg_frame = LOCAL_top_sg_fr;
while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), sharing_node)) {
sg_frame = SgFr_next(sg_frame);
}
REMOTE_top_sg_fr(worker_q) = sg_frame;
/* update worker Q top dependency frame */
dep_frame = LOCAL_top_dep_fr;
while (YOUNGER_CP(DepFr_cons_cp(dep_frame), sharing_node)) {
dep_frame = DepFr_next(dep_frame);
}
REMOTE_top_dep_fr(worker_q) = dep_frame;
/* update worker Q top shared nodes */
REMOTE_top_cp_on_stack(worker_q) = REMOTE_top_cp(worker_q) = LOCAL_top_cp;
REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr;
} else
#endif /* TABLING */
{
int depth;
bitmap bm_workers;
or_fr_ptr or_frame, previous_or_frame;
#ifdef TABLING
choiceptr consumer_cp, next_node_on_branch;
dep_fr_ptr dep_frame;
sg_fr_ptr sg_frame;
CELL *stack, *stack_base, *stack_top;
/* find top dependency frame above current choice point */
dep_frame = LOCAL_top_dep_fr;
while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(dep_frame), sharing_node)) {
dep_frame = DepFr_next(dep_frame);
}
/* initialize tabling auxiliary variables */
consumer_cp = DepFr_cons_cp(dep_frame);
next_node_on_branch = NULL;
stack_top = (CELL *)TrailTop;
stack_base = stack = AuxSp;
#endif /* TABLING */
/* initialize auxiliary variables */
BITMAP_clear(bm_workers);
BITMAP_insert(bm_workers, worker_id);
BITMAP_insert(bm_workers, worker_q);
previous_or_frame = NULL;
depth = OrFr_depth(LOCAL_top_or_fr);
/* sharing loop */
#ifdef TABLING
while (YOUNGER_CP(sharing_node, LOCAL_top_cp_on_stack)) {
#else
while (sharing_node != LOCAL_top_cp) {
#endif /* TABLING */
#ifdef OPTYAP_ERRORS
if (next_node_on_branch) {
choiceptr aux_cp = B;
while (aux_cp != next_node_on_branch) {
if (sharing_node == aux_cp)
OPTYAP_ERROR_MESSAGE("sharing_node on branch (share_private_nodes)");
if (YOUNGER_CP(next_node_on_branch, aux_cp)) {
OPTYAP_ERROR_MESSAGE("next_node_on_branch not in branch (share_private_nodes)");
break;
}
aux_cp = aux_cp->cp_b;
}
} else {
choiceptr aux_cp = B;
while (aux_cp != sharing_node) {
if (YOUNGER_CP(sharing_node, aux_cp)) {
OPTYAP_ERROR_MESSAGE("sharing_node not in branch (share_private_nodes)");
break;
}
aux_cp = aux_cp->cp_b;
}
}
#endif /* OPTYAP_ERRORS */
ALLOC_OR_FRAME(or_frame);
if (previous_or_frame) {
#ifdef TABLING
OrFr_next_on_stack(previous_or_frame) =
#endif /* TABLING */
OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame;
}
previous_or_frame = or_frame;
depth++;
INIT_LOCK(OrFr_lock(or_frame));
OrFr_node(or_frame) = sharing_node;
OrFr_alternative(or_frame) = sharing_node->cp_ap;
OrFr_pend_prune_cp(or_frame) = NULL;
OrFr_nearest_leftnode(or_frame) = LOCAL_top_or_fr;
OrFr_qg_solutions(or_frame) = NULL;
#ifdef TABLING_INNER_CUTS
OrFr_tg_solutions(or_frame) = NULL;
#endif /* TABLING_INNER_CUTS */
#ifdef TABLING
OrFr_suspensions(or_frame) = NULL;
OrFr_nearest_suspnode(or_frame) = or_frame;
OrFr_owners(or_frame) = 2;
if (next_node_on_branch)
BITMAP_clear(OrFr_members(or_frame));
else
#endif /* TABLING */
OrFr_members(or_frame) = bm_workers;
#ifdef YAPOR_ERRORS
if (sharing_node->cp_ap == GETWORK || sharing_node->cp_ap == GETWORK_SEQ)
YAPOR_ERROR_MESSAGE("choicepoint already shared (share_private_nodes)");
#endif /* YAPOR_ERRORS */
if (sharing_node->cp_ap && YAMOP_SEQ(sharing_node->cp_ap)) {
sharing_node->cp_ap = GETWORK_SEQ;
} else {
sharing_node->cp_ap = GETWORK;
}
sharing_node->cp_or_fr = or_frame;
sharing_node = sharing_node->cp_b;
#ifdef TABLING
/* when next_node_on_branch is not NULL the **
** sharing_node belongs to a frozen branch. */
if (YOUNGER_CP(consumer_cp, sharing_node)) {
/* frozen stack segment */
if (! next_node_on_branch)
next_node_on_branch = sharing_node;
STACK_PUSH(or_frame, stack, stack_top, stack_base);
STACK_PUSH(sharing_node, stack, stack_top, stack_base);
sharing_node = consumer_cp;
dep_frame = DepFr_next(dep_frame);
consumer_cp = DepFr_cons_cp(dep_frame);
} else if (consumer_cp == sharing_node) {
dep_frame = DepFr_next(dep_frame);
consumer_cp = DepFr_cons_cp(dep_frame);
}
if (next_node_on_branch == sharing_node)
next_node_on_branch = NULL;
#endif /* TABLING */
#ifdef OPTYAP_ERRORS
if (next_node_on_branch && YOUNGER_CP(next_node_on_branch, sharing_node))
OPTYAP_ERROR_MESSAGE("frozen node greater than next_node_on_branch (share_private_nodes)");
#endif /* OPTYAP_ERRORS */
}
/* initialize last or-frame pointer */
or_frame = sharing_node->cp_or_fr;
if (previous_or_frame) {
#ifdef TABLING
OrFr_next_on_stack(previous_or_frame) =
#endif /* TABLING */
OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame;
}
#ifdef TABLING
/* update or-frames stored in auxiliary stack */
while (STACK_NOT_EMPTY(stack, stack_base)) {
next_node_on_branch = (choiceptr) STACK_POP(stack);
or_frame = (or_fr_ptr) STACK_POP(stack);
OrFr_nearest_livenode(or_frame) = OrFr_next(or_frame) = next_node_on_branch->cp_or_fr;
}
#endif /* TABLING */
/* update depth */
if (depth >= MAX_DEPTH)
abort_optyap("maximum depth exceded (%d/%d) (share_private_nodes)", depth, MAX_DEPTH);
or_frame = B->cp_or_fr;
#ifdef TABLING
previous_or_frame = LOCAL_top_cp_on_stack->cp_or_fr;
while (or_frame != previous_or_frame) {
#else
while (or_frame != LOCAL_top_or_fr) {
#endif /* TABLING */
unsigned int branch;
if (OrFr_alternative(or_frame)) {
branch = YAMOP_OR_ARG(OrFr_alternative(or_frame)) + 1;
} else {
branch = 1;
}
branch |= YAMOP_CUT_FLAG; /* in doubt, assume cut */
BRANCH(worker_id, depth) = BRANCH(worker_q, depth) = branch;
OrFr_depth(or_frame) = depth--;
or_frame = OrFr_next_on_stack(or_frame);
}
#ifdef YAPOR_ERRORS
if (depth != OrFr_depth(LOCAL_top_or_fr))
YAPOR_ERROR_MESSAGE("incorrect depth value (share_private_nodes)");
#endif /* YAPOR_ERRORS */
#ifdef OPTYAP_ERRORS
{ or_fr_ptr aux_or_fr = B->cp_or_fr;
choiceptr aux_cp;
while (aux_or_fr != LOCAL_top_cp_on_stack->cp_or_fr) {
aux_cp = OrFr_node(aux_or_fr);
if (OrFr_next(aux_or_fr) != aux_cp->cp_b->cp_or_fr)
OPTYAP_ERROR_MESSAGE("OrFr_next not in branch (share_private_nodes)");
if (OrFr_nearest_livenode(aux_or_fr) != aux_cp->cp_b->cp_or_fr)
OPTYAP_ERROR_MESSAGE("OrFr_nearest_livenode not in branch (share_private_nodes)");
aux_or_fr = OrFr_next_on_stack(aux_or_fr);
}
aux_or_fr = B->cp_or_fr;
while (aux_or_fr != LOCAL_top_cp_on_stack->cp_or_fr) {
or_fr_ptr nearest_leftnode = OrFr_nearest_leftnode(aux_or_fr);
aux_cp = OrFr_node(aux_or_fr);
while (OrFr_node(nearest_leftnode) != aux_cp) {
if (YOUNGER_CP(OrFr_node(nearest_leftnode), aux_cp)) {
OPTYAP_ERROR_MESSAGE("OrFr_nearest_leftnode not in branch (share_private_nodes)");
break;
}
aux_cp = aux_cp->cp_b;
}
aux_or_fr = OrFr_next_on_stack(aux_or_fr);
}
}
#endif /* OPTYAP_ERRORS */
/* update old shared nodes */
while (or_frame != REMOTE_top_or_fr(worker_q)) {
LOCK_OR_FRAME(or_frame);
BRANCH(worker_q, OrFr_depth(or_frame)) = BRANCH(worker_id, OrFr_depth(or_frame));
#ifdef TABLING
OrFr_owners(or_frame)++;
if (BITMAP_member(OrFr_members(or_frame), worker_id))
#endif /* TABLING */
BITMAP_insert(OrFr_members(or_frame), worker_q);
UNLOCK_OR_FRAME(or_frame);
or_frame = OrFr_next_on_stack(or_frame);
}
#ifdef TABLING
/* update subgoal frames in the maintained private branches */
sg_frame = LOCAL_top_sg_fr;
while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), B)) {
choiceptr top_cp_on_branch;
top_cp_on_branch = SgFr_gen_cp(sg_frame);
while (YOUNGER_CP(top_cp_on_branch, B)) {
top_cp_on_branch = top_cp_on_branch->cp_b;
}
SgFr_gen_top_or_fr(sg_frame) = top_cp_on_branch->cp_or_fr;
sg_frame = SgFr_next(sg_frame);
}
/* update worker Q top subgoal frame */
REMOTE_top_sg_fr(worker_q) = sg_frame;
/* update subgoal frames in the recently shared branches */
while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), LOCAL_top_cp_on_stack)) {
SgFr_gen_worker(sg_frame) = MAX_WORKERS;
SgFr_gen_top_or_fr(sg_frame) = GEN_CP(SgFr_gen_cp(sg_frame))->gcp_or_fr;
sg_frame = SgFr_next(sg_frame);
}
/* update dependency frames in the maintained private branches */
dep_frame = LOCAL_top_dep_fr;
while (YOUNGER_CP(DepFr_cons_cp(dep_frame), B)) {
choiceptr top_cp_on_branch;
top_cp_on_branch = DepFr_cons_cp(dep_frame);
while (YOUNGER_CP(top_cp_on_branch, B)) {
top_cp_on_branch = top_cp_on_branch->cp_b;
}
DepFr_top_or_fr(dep_frame) = top_cp_on_branch->cp_or_fr;
dep_frame = DepFr_next(dep_frame);
}
/* update worker Q top dependency frame */
REMOTE_top_dep_fr(worker_q) = dep_frame;
/* update dependency frames in the recently shared branches */
while (YOUNGER_CP(DepFr_cons_cp(dep_frame), LOCAL_top_cp_on_stack)) {
DepFr_top_or_fr(dep_frame) = CONS_CP(DepFr_cons_cp(dep_frame))->ccp_or_fr;
dep_frame = DepFr_next(dep_frame);
}
#endif /* TABLING */
#ifdef OPTYAP_ERRORS
{ dep_fr_ptr aux_dep_fr = LOCAL_top_dep_fr;
while(aux_dep_fr != GLOBAL_root_dep_fr) {
choiceptr top_cp_on_branch;
top_cp_on_branch = DepFr_cons_cp(aux_dep_fr);
while (YOUNGER_CP(top_cp_on_branch, B)) {
top_cp_on_branch = top_cp_on_branch->cp_b;
}
if (top_cp_on_branch->cp_or_fr != DepFr_top_or_fr(aux_dep_fr))
OPTYAP_ERROR_MESSAGE("Error on DepFr_top_or_fr (share_private_nodes)");
aux_dep_fr = DepFr_next(aux_dep_fr);
}
}
#endif /* OPTYAP_ERRORS */
/* update top shared nodes */
#ifdef TABLING
REMOTE_top_cp_on_stack(worker_q) = LOCAL_top_cp_on_stack =
#endif /* TABLING */
REMOTE_top_cp(worker_q) = LOCAL_top_cp = B;
REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr = LOCAL_top_cp->cp_or_fr;
}
#ifdef TABLING_INNER_CUTS
/* update worker Q pruning scope */
if (LOCAL_pruning_scope && EQUAL_OR_YOUNGER_CP(LOCAL_top_cp, LOCAL_pruning_scope)) {
REMOTE_pruning_scope(worker_q) = LOCAL_pruning_scope;
PUT_IN_PRUNING(worker_q);
} else {
PUT_OUT_PRUNING(worker_q);
REMOTE_pruning_scope(worker_q) = NULL;
}
#endif /* TABLING_INNER_CUTS */
/* update worker Q prune request */
if (LOCAL_prune_request) {
CUT_send_prune_request(worker_q, LOCAL_prune_request);
}
/* update load and return */
REMOTE_load(worker_q) = LOCAL_load = 0;
return;
}
#endif /* ENV_COPY */