YAP 7.1.0
or.thread_engine.c
1/************************************************************************
2** **
3** The YapTab/YapOr/OPTYap systems **
4** **
5** YapTab extends the Yap Prolog engine to support sequential tabling **
6** YapOr extends the Yap Prolog engine to support or-parallelism **
7** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
8** **
9** **
10** Yap Prolog was developed at University of Porto, Portugal **
11** **
12************************************************************************/
13
14/* ------------------ **
15** Includes **
16** ------------------ */
17
18#include "Yap.h"
19#ifdef YAPOR_THREADS
20#ifdef HAVE_STRING_H
21#include <string.h>
22#endif /* HAVE_STRING_H */
23#include "Yatom.h"
24#include "YapHeap.h"
25#include "or.macros.h"
26#ifdef TABLING
27#include "tab.macros.h"
28#else
29#include "opt.mavar.h"
30#endif /* TABLING */
31
32
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)
41
42/* ------------------------------------- **
43** Local functions declaration **
44** ------------------------------------- */
45
46static void share_private_nodes(int worker_q);
47
48
49/* -------------------------- **
50** Global functions **
51** -------------------------- */
52
53void make_root_choice_point(void) {
54 CACHE_REGS
55 if (worker_id == 0) {
56 SetOrFr_node(GLOBAL_root_or_fr, B);
57 Set_LOCAL_top_cp(B);
58 Set_GLOBAL_root_cp(B);
59 } else {
60 choiceptr imageB;
61
62 Set_LOCAL_top_cp(Get_GLOBAL_root_cp());
63 B = Get_GLOBAL_root_cp();
64 /*
65 this is tricky, we need to get the B from some other stack
66 and convert back to our own stack;
67 */
68 LOCAL_OldLCL0 = LCL0;
69 LCL0 = REMOTE_ThreadHandle(0).current_yaam_regs->LCL0_;
70 imageB = Get_GLOBAL_root_cp();
71 /* we know B */
72 B->cp_tr = TR =
73 (tr_fr_ptr)((CELL)(imageB->cp_tr)+((CELL)LOCAL_OldLCL0-(CELL)LCL0));
74 LCL0 = LOCAL_OldLCL0;
75 }
76 B->cp_h = H0;
77 B->cp_ap = GETWORK;
78 B->cp_or_fr = GLOBAL_root_or_fr;
79 LOCAL_top_or_fr = GLOBAL_root_or_fr;
80 LOCAL_load = 0;
81 Set_LOCAL_prune_request(NULL);
82 BRANCH(worker_id, 0) = 0;
83#ifdef TABLING_INNER_CUTS
84 LOCAL_pruning_scope = NULL;
85#endif /* TABLING_INNER_CUTS */
86#ifdef TABLING
87 Set_LOCAL_top_cp_on_stack(Get_LOCAL_top_cp());
88 adjust_freeze_registers();
89#endif /* TABLING */
90 return;
91}
92
93
94void free_root_choice_point(void) {
95 CACHE_REGS
96 B = Get_LOCAL_top_cp()->cp_b;
97#ifdef TABLING
98 Set_LOCAL_top_cp_on_stack((choiceptr) LOCAL_LocalBase);
99#endif /* TABLING */
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);
103 return;
104}
105
106
107int p_share_work() {
108 CACHE_REGS
109 int worker_q = LOCAL_share_request;
110
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)) {
114 /* refuse sharing request */
115 REMOTE_reply_signal(LOCAL_share_request) = no_sharing;
116 LOCAL_share_request = MAX_WORKERS;
117 PUT_OUT_REQUESTABLE(worker_id);
118 return TRUE;
119 }
120 /* sharing request accepted */
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;
124#ifndef TABLING
125 /* wait for incomplete installations */
126 while (LOCAL_reply_signal != worker_ready);
127#endif /* TABLING */
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);
138
139 return TRUE;
140}
141
142int q_share_work(int worker_p) {
143 CACHE_REGS
144 register tr_fr_ptr aux_tr;
145 register CELL aux_cell;
146
147 LOCK_OR_FRAME(LOCAL_top_or_fr);
148 if (Get_REMOTE_prune_request(worker_p)) {
149 /* worker p with prune request */
150 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
151 return FALSE;
152 }
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));
154 /* there is no pending prune with worker p at right --> safe move to worker p branch */
155 CUT_reset_prune_request();
156 if(Get_LOCAL_prune_request()){
157 UNLOCK_OR_FRAME(LOCAL_top_or_fr);
158 return FALSE;
159 }
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);
162
163 /* unbind variables */
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);
168 /* check for global or local variables */
169 if (IsVarTerm(aux_cell)) {
170 RESET_VARIABLE(aux_cell);
171#ifdef TABLING
172 } else if (IsPairTerm(aux_cell)) {
173 aux_cell = (CELL) RepPair(aux_cell);
174 if (IN_BETWEEN(LOCAL_TrailBase, aux_cell, LOCAL_TrailTop)) {
175 /* avoid frozen segments */
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);
179 }
180#endif /* TABLING */
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);
185 *aux_ptr = aux_val;
186#endif /* MULTI_ASSIGNMENT_VARIABLES */
187 }
188 }
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);
192
193 /* make sharing request */
194 LOCK_WORKER(worker_p);
195 if (BITMAP_member(GLOBAL_bm_idle_workers, worker_p) ||
196 REMOTE_share_request(worker_p) != MAX_WORKERS) {
197 /* worker p is idle or has another request */
198 UNLOCK_WORKER(worker_p);
199 return FALSE;
200 }
201 REMOTE_share_request(worker_p) = worker_id;
202 UNLOCK_WORKER(worker_p);
203
204 /* wait for an answer */
205 while (LOCAL_reply_signal == worker_ready);
206 if (LOCAL_reply_signal == no_sharing) {
207 /* sharing request refused */
208 LOCAL_reply_signal = worker_ready;
209 return FALSE;
210 }
211 while (LOCAL_reply_signal == sharing);
212
213#if INCREMENTAL_COPYING
214 Yap_CopyThreadStacks(worker_id, worker_p, TRUE);
215#else
216 Yap_CopyThreadStacks(worker_id, worker_p, FALSE);
217#endif
218
219 PUT_OUT_ROOT_NODE(worker_id);
220 /* update registers and return */
221#ifndef TABLING
222 REMOTE_reply_signal(worker_p) = worker_ready;
223#endif /* TABLING */
224 LOCAL_reply_signal = worker_ready;
225 PUT_IN_REQUESTABLE(worker_id);
226 return TRUE;
227}
228
229
230
231/* ------------------------- **
232** Local functions **
233** ------------------------- */
234
235static
236void share_private_nodes(int worker_q) {
237 CACHE_REGS
238 choiceptr sharing_node = B;
239
240
241#ifdef DEBUG_OPTYAP
242 OPTYAP_ERROR_CHECKING(share_private_nodes, YOUNGER_CP(Get_LOCAL_top_cp(), Get_LOCAL_top_cp_on_stack()));
243 { choiceptr aux_cp = B;
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;
248 }
249 }
250#endif /* DEBUG_OPTYAP */
251
252#ifdef TABLING
253 /* check if the branch is already shared */
254 if (EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp_on_stack(), sharing_node)) {
256 sg_fr_ptr sg_frame;
257 dep_fr_ptr dep_frame;
258
259#ifdef DEBUG_OPTYAP
260 { or_fr_ptr aux_or_fr;
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);
265 }
266 }
267#endif /* DEBUG_OPTYAP */
268
269 /* update old shared nodes */
270 or_frame = LOCAL_top_or_fr;
271 while (or_frame != REMOTE_top_or_fr(worker_q)) {
272 LOCK_OR_FRAME(or_frame);
273 BRANCH(worker_q, OrFr_depth(or_frame)) = BRANCH(worker_id, OrFr_depth(or_frame));
274 OrFr_owners(or_frame)++;
275 if (BITMAP_member(OrFr_members(or_frame), worker_id))
276 BITMAP_insert(OrFr_members(or_frame), worker_q);
277 UNLOCK_OR_FRAME(or_frame);
278 or_frame = OrFr_next_on_stack(or_frame);
279 }
280
281 /* update worker Q top subgoal frame */
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);
285 }
286 REMOTE_top_sg_fr(worker_q) = sg_frame;
287
288 /* update worker Q top dependency 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);
292 }
293 REMOTE_top_dep_fr(worker_q) = dep_frame;
294
295 /* update worker Q top shared nodes */
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;
299 } else
300#endif /* TABLING */
301 {
302 int depth;
303 bitmap bm_workers;
304 or_fr_ptr or_frame, previous_or_frame;
305#ifdef TABLING
306 choiceptr consumer_cp, next_node_on_branch;
307 dep_fr_ptr dep_frame;
308 sg_fr_ptr sg_frame;
309 CELL *stack, *stack_limit;
310
311 /* find top dependency frame above current choice point */
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);
315 }
316 /* initialize tabling auxiliary variables */
317 consumer_cp = DepFr_cons_cp(dep_frame);
318 next_node_on_branch = NULL;
319 stack_limit = (CELL *)TR;
320 stack = (CELL *)LOCAL_TrailTop;
321#endif /* TABLING */
322
323 /* initialize auxiliary variables */
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);
329
330 /* sharing loop */
331#ifdef TABLING
332 while (YOUNGER_CP(sharing_node, Get_LOCAL_top_cp_on_stack())) {
333#else
334 while (sharing_node != Get_LOCAL_top_cp()) {
335#endif /* TABLING */
336
337#ifdef DEBUG_OPTYAP
338 if (next_node_on_branch) {
339 choiceptr aux_cp = B;
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;
344 }
345 } else {
346 choiceptr aux_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;
350 }
351 }
352#endif /* DEBUG_OPTYAP */
353
354 ALLOC_OR_FRAME(or_frame);
355 if (previous_or_frame) {
356#ifdef TABLING
357 OrFr_next_on_stack(previous_or_frame) =
358#endif /* TABLING */
359 OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame;
360 }
361 previous_or_frame = or_frame;
362 depth++;
363 INIT_LOCK(OrFr_lock(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;
368 OrFr_qg_solutions(or_frame) = NULL;
369#ifdef TABLING_INNER_CUTS
370 OrFr_tg_solutions(or_frame) = NULL;
371#endif /* TABLING_INNER_CUTS */
372#ifdef TABLING
373 OrFr_suspensions(or_frame) = NULL;
374 OrFr_nearest_suspnode(or_frame) = or_frame;
375 OrFr_owners(or_frame) = 2;
376 if (next_node_on_branch)
377 BITMAP_clear(OrFr_members(or_frame));
378 else
379#endif /* TABLING */
380 OrFr_members(or_frame) = bm_workers;
381
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;
385 } else {
386 sharing_node->cp_ap = GETWORK;
387 }
388 sharing_node->cp_or_fr = or_frame;
389 sharing_node = sharing_node->cp_b;
390
391#ifdef TABLING
392 /* when next_node_on_branch is not NULL the **
393 ** sharing_node belongs to a frozen branch. */
394 if (YOUNGER_CP(consumer_cp, sharing_node)) {
395 /* frozen stack segment */
396 if (! next_node_on_branch)
397 next_node_on_branch = sharing_node;
398 STACK_PUSH_UP(or_frame, stack);
399 STACK_CHECK_EXPAND(stack, stack_limit);
400 STACK_PUSH_UP(sharing_node, stack); /* vsc: STACK_PUSH -> STACK_PUSH_UP? */
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);
408 }
409 if (next_node_on_branch == sharing_node)
410 next_node_on_branch = NULL;
411#endif /* TABLING */
412 OPTYAP_ERROR_CHECKING(share_private_nodes, next_node_on_branch && YOUNGER_CP(next_node_on_branch, sharing_node));
413 }
414
415 /* initialize last or-frame pointer */
416 or_frame = sharing_node->cp_or_fr;
417 if (previous_or_frame) {
418#ifdef TABLING
419 OrFr_next_on_stack(previous_or_frame) =
420#endif /* TABLING */
421 OrFr_nearest_livenode(previous_or_frame) = OrFr_next(previous_or_frame) = or_frame;
422 }
423
424#ifdef TABLING
425 /* update or-frames stored in auxiliary stack */
426 while (STACK_NOT_EMPTY(stack, (CELL *)LOCAL_TrailTop)) {
427 next_node_on_branch = (choiceptr) STACK_POP_DOWN(stack);
428 or_frame = (or_fr_ptr) STACK_POP_DOWN(stack);
429 OrFr_nearest_livenode(or_frame) = OrFr_next(or_frame) = next_node_on_branch->cp_or_fr;
430 }
431#endif /* TABLING */
432
433 /* update depth */
434 if (depth >= MAX_BRANCH_DEPTH)
435 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "maximum depth exceded (share_private_nodes)");
436 or_frame = B->cp_or_fr;
437#ifdef TABLING
438 previous_or_frame = Get_LOCAL_top_cp_on_stack()->cp_or_fr;
439 while (or_frame != previous_or_frame) {
440#else
441 while (or_frame != LOCAL_top_or_fr) {
442#endif /* TABLING */
443 unsigned int branch;
444 if (OrFr_alternative(or_frame)) {
445 branch = YAMOP_OR_ARG(OrFr_alternative(or_frame)) + 1;
446 } else {
447 branch = 1;
448 }
449 branch |= YAMOP_CUT_FLAG; /* in doubt, assume cut */
450 BRANCH(worker_id, depth) = BRANCH(worker_q, depth) = branch;
451 OrFr_depth(or_frame) = depth--;
452 or_frame = OrFr_next_on_stack(or_frame);
453 }
454
455 YAPOR_ERROR_CHECKING(share_private_nodes, depth != OrFr_depth(LOCAL_top_or_fr));
456
457#ifdef DEBUG_OPTYAP
458 { or_fr_ptr aux_or_fr = B->cp_or_fr;
459 choiceptr aux_cp;
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);
465 }
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;
473 }
474 aux_or_fr = OrFr_next_on_stack(aux_or_fr);
475 }
476 }
477#endif /* DEBUG_OPTYAP */
478
479 /* update old shared nodes */
480 while (or_frame != REMOTE_top_or_fr(worker_q)) {
481 LOCK_OR_FRAME(or_frame);
482 BRANCH(worker_q, OrFr_depth(or_frame)) = BRANCH(worker_id, OrFr_depth(or_frame));
483#ifdef TABLING
484 OrFr_owners(or_frame)++;
485 if (BITMAP_member(OrFr_members(or_frame), worker_id))
486#endif /* TABLING */
487 BITMAP_insert(OrFr_members(or_frame), worker_q);
488 UNLOCK_OR_FRAME(or_frame);
489 or_frame = OrFr_next_on_stack(or_frame);
490 }
491
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);
495 Set_LOCAL_top_cp(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);
498
499#ifdef TABLING
500 /* update subgoal frames in the maintained private branches */
501 sg_frame = LOCAL_top_sg_fr;
502 while (sg_frame && YOUNGER_CP(SgFr_gen_cp(sg_frame), B)) {
503 choiceptr top_cp_on_branch;
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;
507 }
508 SgFr_gen_top_or_fr(sg_frame) = top_cp_on_branch->cp_or_fr;
509 sg_frame = SgFr_next(sg_frame);
510 }
511 /* update worker Q top subgoal frame */
512 REMOTE_top_sg_fr(worker_q) = sg_frame;
513 /* update subgoal frames in the recently shared branches */
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);
518 }
519
520 /* update dependency frames in the maintained private branches */
521 dep_frame = LOCAL_top_dep_fr;
522 while (YOUNGER_CP(DepFr_cons_cp(dep_frame), B)) {
523 choiceptr top_cp_on_branch;
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;
527 }
528 DepFr_top_or_fr(dep_frame) = top_cp_on_branch->cp_or_fr;
529 dep_frame = DepFr_next(dep_frame);
530 }
531 /* update worker Q top dependency frame */
532 REMOTE_top_dep_fr(worker_q) = dep_frame;
533 /* update dependency frames in the recently shared branches */
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);
537 }
538#endif /* TABLING */
539
540#ifdef DEBUG_OPTYAP
541 { dep_fr_ptr aux_dep_fr = LOCAL_top_dep_fr;
542 while(aux_dep_fr != GLOBAL_root_dep_fr) {
543 choiceptr top_cp_on_branch;
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;
547 }
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);
550 }
551 }
552#endif /* DEBUG_OPTYAP */
553
554 /* update top shared nodes */
555#ifdef TABLING
556 Set_REMOTE_top_cp_on_stack(worker_q,B);
557 Set_LOCAL_top_cp_on_stack( B );
558#endif /* TABLING */
559 Set_REMOTE_top_cp(worker_q,B);
560 Set_LOCAL_top_cp(B);
561 REMOTE_top_or_fr(worker_q) = LOCAL_top_or_fr = Get_LOCAL_top_cp()->cp_or_fr;
562 }
563
564#ifdef TABLING_INNER_CUTS
565 /* update worker Q pruning scope */
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);
569 } else {
570 PUT_OUT_PRUNING(worker_q);
571 REMOTE_pruning_scope(worker_q) = NULL;
572 }
573#endif /* TABLING_INNER_CUTS */
574
575 /* update worker Q prune request */
576 if (Get_LOCAL_prune_request()) {
577 CUT_send_prune_request(worker_q, Get_LOCAL_prune_request());
578 }
579
580 /* update load and return */
581 REMOTE_load(worker_q) = LOCAL_load = 0;
582 return;
583}
584#endif /* YAPOR_THREADS */
Main definitions.