27#include "tab.macros.h"
33#define INCREMENTAL_COPYING 1
34#define COMPUTE_SEGMENTS_TO_COPY_TO(Q) \
35 REMOTE_start_global_copy(Q) = (CELL) (REMOTE_top_cp(Q)->cp_h); \
36 REMOTE_end_global_copy(Q) = (CELL) (B->cp_h); \
37 REMOTE_start_local_copy(Q) = (CELL) (B); \
38 REMOTE_end_local_copy(Q) = (CELL) (REMOTE_top_cp(Q)); \
39 REMOTE_start_trail_copy(Q) = (CELL) (REMOTE_top_cp(Q)->cp_tr); \
40 REMOTE_end_trail_copy(Q) = (CELL) (TR)
46static void share_private_nodes(
int worker_q);
53void make_root_choice_point(
void) {
56 SetOrFr_node(GLOBAL_root_or_fr, B);
58 Set_GLOBAL_root_cp(B);
62 Set_LOCAL_top_cp(Get_GLOBAL_root_cp());
63 B = Get_GLOBAL_root_cp();
69 LCL0 = REMOTE_ThreadHandle(0).current_yaam_regs->LCL0_;
70 imageB = Get_GLOBAL_root_cp();
73 (tr_fr_ptr)((CELL)(imageB->cp_tr)+((CELL)LOCAL_OldLCL0-(CELL)LCL0));
78 B->cp_or_fr = GLOBAL_root_or_fr;
79 LOCAL_top_or_fr = GLOBAL_root_or_fr;
81 Set_LOCAL_prune_request(NULL);
82 BRANCH(worker_id, 0) = 0;
83#ifdef TABLING_INNER_CUTS
84 LOCAL_pruning_scope = NULL;
87 Set_LOCAL_top_cp_on_stack(Get_LOCAL_top_cp());
88 adjust_freeze_registers();
94void free_root_choice_point(
void) {
96 B = Get_LOCAL_top_cp()->cp_b;
98 Set_LOCAL_top_cp_on_stack((
choiceptr) LOCAL_LocalBase);
100 Set_GLOBAL_root_cp((
choiceptr) LOCAL_LocalBase);
101 Set_LOCAL_top_cp((
choiceptr) LOCAL_LocalBase);
102 SetOrFr_node(GLOBAL_root_or_fr, (
choiceptr) LOCAL_LocalBase);
109 int worker_q = LOCAL_share_request;
111 if (! BITMAP_member(OrFr_members(REMOTE_top_or_fr(worker_q)), worker_id) ||
112 B == REMOTE_top_cp(worker_q) ||
113 (LOCAL_load <= GLOBAL_delayed_release_load && OrFr_nearest_livenode(LOCAL_top_or_fr) == NULL)) {
115 REMOTE_reply_signal(LOCAL_share_request) = no_sharing;
116 LOCAL_share_request = MAX_WORKERS;
117 PUT_OUT_REQUESTABLE(worker_id);
121 COMPUTE_SEGMENTS_TO_COPY_TO(worker_q);
122 REMOTE_q_fase_signal(worker_q) = Q_idle;
123 REMOTE_p_fase_signal(worker_q) = P_idle;
126 while (LOCAL_reply_signal != worker_ready);
128 LOCAL_reply_signal = sharing;
129 REMOTE_reply_signal(worker_q) = sharing;
130 share_private_nodes(worker_q);
131 if(Get_LOCAL_prune_request())
132 CUT_send_prune_request(worker_q, Get_LOCAL_prune_request());
133 REMOTE_reply_signal(worker_q) = nodes_shared;
134 while (LOCAL_reply_signal == sharing);
135 while (REMOTE_reply_signal(worker_q) != worker_ready);
136 LOCAL_share_request = MAX_WORKERS;
137 PUT_IN_REQUESTABLE(worker_id);
142int q_share_work(
int worker_p) {
144 register tr_fr_ptr aux_tr;
145 register CELL aux_cell;
147 LOCK_OR_FRAME(LOCAL_top_or_fr);
148 if (Get_REMOTE_prune_request(worker_p)) {
150 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
153 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));
155 CUT_reset_prune_request();
156 if(Get_LOCAL_prune_request()){
157 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
160 BRANCH(worker_id, OrFr_depth(LOCAL_top_or_fr)) = BRANCH(worker_p, OrFr_depth(LOCAL_top_or_fr));
161 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
164 aux_tr = Get_LOCAL_top_cp()->cp_tr;
165 TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr);
166 while (aux_tr != TR) {
167 aux_cell = TrailTerm(--TR);
169 if (IsVarTerm(aux_cell)) {
170 RESET_VARIABLE(aux_cell);
172 }
else if (IsPairTerm(aux_cell)) {
173 aux_cell = (CELL) RepPair(aux_cell);
174 if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) {
176 TR = (tr_fr_ptr) aux_cell;
177 TABLING_ERROR_CHECKING(q_share_work, TR > (tr_fr_ptr) LOCAL_TrailTop);
178 TABLING_ERROR_CHECKING(q_share_work, TR < aux_tr);
181#ifdef MULTI_ASSIGNMENT_VARIABLES
182 }
else if (IsApplTerm(aux_cell)) {
183 CELL *aux_ptr = RepAppl(aux_cell);
184 Term aux_val = TrailTerm(--aux_tr);
189 OPTYAP_ERROR_CHECKING(q_share_work, Get_LOCAL_top_cp() != Get_LOCAL_top_cp_on_stack());
190 OPTYAP_ERROR_CHECKING(q_share_work, YOUNGER_CP(B_FZ, Get_LOCAL_top_cp()));
191 YAPOR_ERROR_CHECKING(q_share_work, LOCAL_reply_signal != worker_ready);
194 LOCK_WORKER(worker_p);
195 if (BITMAP_member(GLOBAL_bm_idle_workers, worker_p) ||
196 REMOTE_share_request(worker_p) != MAX_WORKERS) {
198 UNLOCK_WORKER(worker_p);
201 REMOTE_share_request(worker_p) = worker_id;
202 UNLOCK_WORKER(worker_p);
205 while (LOCAL_reply_signal == worker_ready);
206 if (LOCAL_reply_signal == no_sharing) {
208 LOCAL_reply_signal = worker_ready;
211 while (LOCAL_reply_signal == sharing);
213#if INCREMENTAL_COPYING
214 Yap_CopyThreadStacks(worker_id, worker_p, TRUE);
216 Yap_CopyThreadStacks(worker_id, worker_p, FALSE);
219 PUT_OUT_ROOT_NODE(worker_id);
222 REMOTE_reply_signal(worker_p) = worker_ready;
224 LOCAL_reply_signal = worker_ready;
225 PUT_IN_REQUESTABLE(worker_id);
236void share_private_nodes(
int worker_q) {
242 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack()));
244 while (aux_cp != Get_LOCAL_top_cp()) {
245 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(Get_LOCAL_top_cp(), aux_cp));
246 OPTYAP_ERROR_CHECKING(share_private_nodes, EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), aux_cp));
247 aux_cp = aux_cp->cp_b;
254 if (EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), sharing_node)) {
261 aux_or_fr = LOCAL_top_or_fr;
262 while (aux_or_fr != REMOTE_top_or_fr(worker_q)) {
263 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(GetOrFr_node(REMOTE_top_or_fr(worker_q)), GetOrFr_node(aux_or_fr)));
264 aux_or_fr = OrFr_next_on_stack(aux_or_fr);
271 while (
or_frame != REMOTE_top_or_fr(worker_q)) {
273 BRANCH(worker_q, OrFr_depth(
or_frame)) = BRANCH(worker_id, OrFr_depth(
or_frame));
275 if (BITMAP_member(OrFr_members(
or_frame), worker_id))
276 BITMAP_insert(OrFr_members(
or_frame), worker_q);
282 sg_frame = LOCAL_top_sg_fr;
283 while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), sharing_node)) {
284 sg_frame = SgFr_next(sg_frame);
286 REMOTE_top_sg_fr(worker_q) = sg_frame;
289 dep_frame = LOCAL_top_dep_fr;
290 while (YOUNGER_CP(DepFr_cons_cp(dep_frame), sharing_node)) {
291 dep_frame = DepFr_next(dep_frame);
293 REMOTE_top_dep_fr(worker_q) = dep_frame;
296 Set_REMOTE_top_cp_on_stack(worker_q, Get_LOCAL_top_cp());
297 Set_REMOTE_top_cp(worker_q, Get_LOCAL_top_cp());
298 REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr;
306 choiceptr consumer_cp, next_node_on_branch;
309 CELL *stack, *stack_limit;
312 dep_frame = LOCAL_top_dep_fr;
313 while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(dep_frame), sharing_node)) {
314 dep_frame = DepFr_next(dep_frame);
317 consumer_cp = DepFr_cons_cp(dep_frame);
318 next_node_on_branch = NULL;
319 stack_limit = (CELL *)TR;
320 stack = (CELL *)LOCAL_TrailTop;
324 BITMAP_clear(bm_workers);
325 BITMAP_insert(bm_workers, worker_id);
326 BITMAP_insert(bm_workers, worker_q);
327 previous_or_frame = NULL;
328 depth = OrFr_depth(LOCAL_top_or_fr);
332 while (YOUNGER_CP(sharing_node, Get_LOCAL_top_cp_on_stack())) {
334 while (sharing_node != Get_LOCAL_top_cp()) {
338 if (next_node_on_branch) {
340 while (aux_cp != next_node_on_branch) {
341 OPTYAP_ERROR_CHECKING(share_private_nodes, sharing_node == aux_cp);
342 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(next_node_on_branch, aux_cp));
343 aux_cp = aux_cp->cp_b;
347 while (aux_cp != sharing_node) {
348 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(sharing_node, aux_cp));
349 aux_cp = aux_cp->cp_b;
355 if (previous_or_frame) {
357 OrFr_next_on_stack(previous_or_frame) =
359 OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) =
or_frame;
364 SetOrFr_node(
or_frame, sharing_node);
365 OrFr_alternative(
or_frame) = sharing_node->cp_ap;
366 Set_OrFr_pend_prune_cp(
or_frame, NULL);
367 OrFr_nearest_leftnode(
or_frame) = LOCAL_top_or_fr;
369#ifdef TABLING_INNER_CUTS
376 if (next_node_on_branch)
377 BITMAP_clear(OrFr_members(
or_frame));
380 OrFr_members(
or_frame) = bm_workers;
382 YAPOR_ERROR_CHECKING(share_private_nodes, sharing_node->cp_ap == GETWORK || sharing_node->cp_ap == GETWORK_SEQ);
383 if (sharing_node->cp_ap && YAMOP_SEQ(sharing_node->cp_ap)) {
384 sharing_node->cp_ap = GETWORK_SEQ;
386 sharing_node->cp_ap = GETWORK;
389 sharing_node = sharing_node->cp_b;
394 if (YOUNGER_CP(consumer_cp, sharing_node)) {
396 if (! next_node_on_branch)
397 next_node_on_branch = sharing_node;
399 STACK_CHECK_EXPAND(stack, stack_limit);
400 STACK_PUSH_UP(sharing_node, stack);
401 STACK_CHECK_EXPAND(stack, stack_limit);
402 sharing_node = consumer_cp;
403 dep_frame = DepFr_next(dep_frame);
404 consumer_cp = DepFr_cons_cp(dep_frame);
405 }
else if (consumer_cp == sharing_node) {
406 dep_frame = DepFr_next(dep_frame);
407 consumer_cp = DepFr_cons_cp(dep_frame);
409 if (next_node_on_branch == sharing_node)
410 next_node_on_branch = NULL;
412 OPTYAP_ERROR_CHECKING(share_private_nodes, next_node_on_branch && YOUNGER_CP(next_node_on_branch, sharing_node));
417 if (previous_or_frame) {
419 OrFr_next_on_stack(previous_or_frame) =
421 OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) =
or_frame;
426 while (STACK_NOT_EMPTY(stack, (CELL *)LOCAL_TrailTop)) {
427 next_node_on_branch = (
choiceptr) STACK_POP_DOWN(stack);
429 OrFr_nearest_livenode(
or_frame) = OrFr_next(
or_frame) = next_node_on_branch->cp_or_fr;
434 if (depth >= MAX_BRANCH_DEPTH)
435 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
"maximum depth exceded (share_private_nodes)");
438 previous_or_frame = Get_LOCAL_top_cp_on_stack()->cp_or_fr;
439 while (
or_frame != previous_or_frame) {
441 while (
or_frame != LOCAL_top_or_fr) {
450 BRANCH(worker_id, depth) = BRANCH(worker_q, depth) =
branch;
455 YAPOR_ERROR_CHECKING(share_private_nodes, depth != OrFr_depth(LOCAL_top_or_fr));
460 while (aux_or_fr != Get_LOCAL_top_cp_on_stack()->cp_or_fr) {
461 aux_cp = GetOrFr_node(aux_or_fr);
462 OPTYAP_ERROR_CHECKING(share_private_nodes, OrFr_next(aux_or_fr) != aux_cp->cp_b->cp_or_fr);
463 OPTYAP_ERROR_CHECKING(share_private_nodes, OrFr_nearest_livenode(aux_or_fr) != aux_cp->cp_b->cp_or_fr);
464 aux_or_fr = OrFr_next_on_stack(aux_or_fr);
466 aux_or_fr = B->cp_or_fr;
467 while (aux_or_fr != Get_LOCAL_top_cp_on_stack()->cp_or_fr) {
468 or_fr_ptr nearest_leftnode = OrFr_nearest_leftnode(aux_or_fr);
469 aux_cp = GetOrFr_node(aux_or_fr);
470 while (GetOrFr_node(nearest_leftnode) != aux_cp) {
471 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(GetOrFr_node(nearest_leftnode), aux_cp));
472 aux_cp = aux_cp->cp_b;
474 aux_or_fr = OrFr_next_on_stack(aux_or_fr);
480 while (
or_frame != REMOTE_top_or_fr(worker_q)) {
482 BRANCH(worker_q, OrFr_depth(
or_frame)) = BRANCH(worker_id, OrFr_depth(
or_frame));
485 if (BITMAP_member(OrFr_members(
or_frame), worker_id))
487 BITMAP_insert(OrFr_members(
or_frame), worker_q);
492 LOCK_OR_FRAME(REMOTE_top_or_fr(worker_q));
493 or_fr_ptr old_top = REMOTE_top_or_fr(worker_q);
494 Set_REMOTE_top_cp(worker_q,B);
496 REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr = Get_LOCAL_top_cp()->cp_or_fr;
497 UNLOCK_OR_FRAME(old_top);
501 sg_frame = LOCAL_top_sg_fr;
502 while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), B)) {
504 top_cp_on_branch = SgFr_gen_cp(sg_frame);
505 while (YOUNGER_CP(top_cp_on_branch, B)) {
506 top_cp_on_branch = top_cp_on_branch->cp_b;
508 SgFr_gen_top_or_fr(sg_frame) = top_cp_on_branch->cp_or_fr;
509 sg_frame = SgFr_next(sg_frame);
512 REMOTE_top_sg_fr(worker_q) = sg_frame;
514 while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), Get_LOCAL_top_cp_on_stack())) {
515 SgFr_gen_worker(sg_frame) = MAX_WORKERS;
516 SgFr_gen_top_or_fr(sg_frame) = SgFr_gen_cp(sg_frame)->cp_or_fr;
517 sg_frame = SgFr_next(sg_frame);
521 dep_frame = LOCAL_top_dep_fr;
522 while (YOUNGER_CP(DepFr_cons_cp(dep_frame), B)) {
524 top_cp_on_branch = DepFr_cons_cp(dep_frame);
525 while (YOUNGER_CP(top_cp_on_branch, B)) {
526 top_cp_on_branch = top_cp_on_branch->cp_b;
528 DepFr_top_or_fr(dep_frame) = top_cp_on_branch->cp_or_fr;
529 dep_frame = DepFr_next(dep_frame);
532 REMOTE_top_dep_fr(worker_q) = dep_frame;
534 while (YOUNGER_CP(DepFr_cons_cp(dep_frame), Get_LOCAL_top_cp_on_stack())) {
535 DepFr_top_or_fr(dep_frame) = DepFr_cons_cp(dep_frame)->cp_or_fr;
536 dep_frame = DepFr_next(dep_frame);
542 while(aux_dep_fr != GLOBAL_root_dep_fr) {
544 top_cp_on_branch = DepFr_cons_cp(aux_dep_fr);
545 while (YOUNGER_CP(top_cp_on_branch, B)) {
546 top_cp_on_branch = top_cp_on_branch->cp_b;
548 OPTYAP_ERROR_CHECKING(share_private_nodes, top_cp_on_branch->cp_or_fr != DepFr_top_or_fr(aux_dep_fr));
549 aux_dep_fr = DepFr_next(aux_dep_fr);
556 Set_REMOTE_top_cp_on_stack(worker_q,B);
557 Set_LOCAL_top_cp_on_stack( B );
559 Set_REMOTE_top_cp(worker_q,B);
561 REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr = Get_LOCAL_top_cp()->cp_or_fr;
564#ifdef TABLING_INNER_CUTS
566 if (LOCAL_pruning_scope && EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), LOCAL_pruning_scope)) {
567 REMOTE_pruning_scope(worker_q) = LOCAL_pruning_scope;
568 PUT_IN_PRUNING(worker_q);
570 PUT_OUT_PRUNING(worker_q);
571 REMOTE_pruning_scope(worker_q) = NULL;
576 if (Get_LOCAL_prune_request()) {
577 CUT_send_prune_request(worker_q, Get_LOCAL_prune_request());
581 REMOTE_load(worker_q) = LOCAL_load = 0;