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 & Prototypes      **
16 ************************************/
17 
18 #include "Yap.h"
19 #if defined(YAPOR) || defined(TABLING)
20 #include <stdio.h>
21 #if HAVE_STRING_H
22 #include <string.h>
23 #endif /* HAVE_STRING_H */
24 #include "Yatom.h"
25 #include "YapHeap.h"
26 #include "yapio.h"
27 #ifdef YAPOR
28 #if HAVE_SYS_TIME_H
29 #include <sys/time.h>
30 #endif /* HAVE_SYS_TIME_H */
31 #include "or.macros.h"
32 #endif /* YAPOR */
33 #ifdef TABLING
34 #include "tab.macros.h"
35 #endif /* TABLING */
36 
37 #ifdef TABLING
38 static Int p_freeze_choice_point(void);
39 static Int p_wake_choice_point(void);
40 static Int p_abolish_frozen_choice_points_until(void);
41 static Int p_abolish_frozen_choice_points_all(void);
42 static Int p_table(void);
43 static Int p_tabling_mode(void);
44 static Int p_abolish_table(void);
45 static Int p_abolish_all_tables(void);
46 static Int p_show_tabled_predicates(void);
47 static Int p_show_table(void);
48 static Int p_show_all_tables(void);
49 static Int p_show_global_trie(void);
50 static Int p_show_statistics_table(void);
51 static Int p_show_statistics_tabling(void);
52 static Int p_show_statistics_global_trie(void);
53 #endif /* TABLING */
54 static Int p_yapor_threads(void);
55 #ifdef YAPOR
56 static Int p_worker(void);
57 static Int p_yapor_on(void);
58 static Int p_start_yapor(void);
59 static Int p_default_sequential(void);
60 static Int p_execution_mode(void);
61 static Int p_performance(void);
62 static Int p_parallel_new_answer(void);
63 static Int p_parallel_yes_answer(void);
64 static Int p_show_statistics_or(void);
65 #endif /* YAPOR */
66 #if defined(YAPOR) && defined(TABLING)
67 static Int p_show_statistics_opt(void);
68 #endif /* YAPOR && TABLING */
69 static Int p_get_optyap_statistics(void);
70 
71 #ifdef YAPOR
72 static inline realtime current_time(void);
73 static inline int parallel_new_answer_putchar(int sno, int ch);
74 static inline void show_answers(void);
75 static inline void answer_to_stdout(char *answer);
76 #endif /* YAPOR */
77 
78 #ifdef TABLING
79 static inline long show_statistics_table_entries(void);
80 static inline long show_statistics_subgoal_frames(void);
81 static inline long show_statistics_dependency_frames(void);
82 static inline long show_statistics_subgoal_trie_nodes(void);
83 static inline long show_statistics_answer_trie_nodes(void);
84 static inline long show_statistics_subgoal_trie_hashes(void);
85 static inline long show_statistics_answer_trie_hashes(void);
86 static inline long show_statistics_global_trie_nodes(void);
87 static inline long show_statistics_global_trie_hashes(void);
88 #endif /* TABLING */
89 #ifdef YAPOR
90 static inline long show_statistics_or_frames(void);
91 static inline long show_statistics_query_goal_solution_frames(void);
92 static inline long show_statistics_query_goal_answer_frames(void);
93 #endif /* YAPOR */
94 #if defined(YAPOR) && defined(TABLING)
95 static inline long show_statistics_suspension_frames(void);
96 #ifdef TABLING_INNER_CUTS
97 static inline long show_statistics_table_subgoal_solution_frames(void);
98 static inline long show_statistics_table_subgoal_answer_frames(void);
99 #endif /* TABLING_INNER_CUTS */
100 #endif /* YAPOR && TABLING */
101 
102 
103 
104 /************************************
105 **      Macros & Declarations      **
106 ************************************/
107 
108 #ifdef YAPOR
109 #define TIME_RESOLUTION 1000000
110 #define NO_ANSWER   0
111 #define YES_ANSWER -1
112 static int length_answer;
113 static qg_ans_fr_ptr actual_answer;
114 #endif /* YAPOR */
115 
116 
117 
118 /*******************************
119 **      Global functions      **
120 *******************************/
121 
Yap_init_optyap_preds(void)122 void Yap_init_optyap_preds(void) {
123 #ifdef TABLING
124   Yap_InitCPred("freeze_choice_point", 1, p_freeze_choice_point, SafePredFlag|SyncPredFlag);
125   Yap_InitCPred("wake_choice_point", 1, p_wake_choice_point, SafePredFlag|SyncPredFlag);
126   Yap_InitCPred("abolish_frozen_choice_points", 1, p_abolish_frozen_choice_points_until, SafePredFlag|SyncPredFlag);
127   Yap_InitCPred("abolish_frozen_choice_points", 0, p_abolish_frozen_choice_points_all, SafePredFlag|SyncPredFlag);
128   Yap_InitCPred("$c_table", 2, p_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
129   Yap_InitCPred("$c_tabling_mode", 3, p_tabling_mode, SafePredFlag|SyncPredFlag|HiddenPredFlag);
130   Yap_InitCPred("$c_abolish_table", 2, p_abolish_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
131   Yap_InitCPred("abolish_all_tables", 0, p_abolish_all_tables, SafePredFlag|SyncPredFlag);
132   Yap_InitCPred("show_tabled_predicates", 0, p_show_tabled_predicates, SafePredFlag|SyncPredFlag);
133   Yap_InitCPred("$c_show_table", 2, p_show_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
134   Yap_InitCPred("show_all_tables", 0, p_show_all_tables, SafePredFlag|SyncPredFlag);
135   Yap_InitCPred("show_global_trie", 0, p_show_global_trie, SafePredFlag|SyncPredFlag);
136   Yap_InitCPred("$c_table_statistics", 2, p_show_statistics_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
137   Yap_InitCPred("tabling_statistics", 0, p_show_statistics_tabling, SafePredFlag|SyncPredFlag);
138   Yap_InitCPred("global_trie_statistics", 0, p_show_statistics_global_trie, SafePredFlag|SyncPredFlag);
139 #endif /* TABLING */
140   Yap_InitCPred("$c_yapor_threads", 1, p_yapor_threads, SafePredFlag|SyncPredFlag|HiddenPredFlag);
141 #ifdef YAPOR
142   Yap_InitCPred("$c_worker", 0, p_worker, SafePredFlag|SyncPredFlag|HiddenPredFlag);
143   Yap_InitCPred("$c_yapor_on", 0, p_yapor_on, SafePredFlag|SyncPredFlag|HiddenPredFlag);
144   Yap_InitCPred("$c_start_yapor", 0, p_start_yapor, SafePredFlag|SyncPredFlag|HiddenPredFlag);
145   Yap_InitCPred("$c_default_sequential", 1, p_default_sequential, SafePredFlag|SyncPredFlag|HiddenPredFlag);
146   Yap_InitCPred("execution_mode", 1, p_execution_mode, SafePredFlag|SyncPredFlag);
147   Yap_InitCPred("performance", 1, p_performance, SafePredFlag|SyncPredFlag);
148   Yap_InitCPred("$c_parallel_new_answer", 1, p_parallel_new_answer, SafePredFlag|SyncPredFlag|HiddenPredFlag);
149   Yap_InitCPred("$c_parallel_yes_answer", 0, p_parallel_yes_answer, SafePredFlag|SyncPredFlag|HiddenPredFlag);
150   Yap_InitCPred("or_statistics", 0, p_show_statistics_or, SafePredFlag|SyncPredFlag);
151 #endif /* YAPOR */
152 #if defined(YAPOR) && defined(TABLING)
153   Yap_InitCPred("opt_statistics", 0, p_show_statistics_opt, SafePredFlag|SyncPredFlag);
154 #endif /* YAPOR && TABLING */
155   Yap_InitCPred("$c_get_optyap_statistics", 3, p_get_optyap_statistics, SafePredFlag|SyncPredFlag|HiddenPredFlag);
156 }
157 
158 
159 #ifdef YAPOR
finish_yapor(void)160 void finish_yapor(void) {
161   GLOBAL_execution_time = current_time() - GLOBAL_execution_time;
162   show_answers();
163   return;
164 }
165 #endif /* YAPOR */
166 
167 
168 
169 /***********************************
170 **      Tabling C Predicates      **
171 ***********************************/
172 
173 #ifdef TABLING
p_freeze_choice_point(void)174 static Int p_freeze_choice_point(void) {
175   if (IsVarTerm(Deref(ARG1))) {
176     Int offset = freeze_current_cp();
177     return Yap_unify(ARG1, MkIntegerTerm(offset));
178   }
179   return (FALSE);
180 }
181 
182 
p_wake_choice_point(void)183 static Int p_wake_choice_point(void) {
184   Term term_offset = Deref(ARG1);
185   if (IsIntegerTerm(term_offset))
186     wake_frozen_cp(IntegerOfTerm(term_offset));
187   return (FALSE);
188 }
189 
190 
p_abolish_frozen_choice_points_until(void)191 static Int p_abolish_frozen_choice_points_until(void) {
192   Term term_offset = Deref(ARG1);
193   if (IsIntegerTerm(term_offset))
194     abolish_frozen_cps_until(IntegerOfTerm(term_offset));
195   return (TRUE);
196 }
197 
198 
p_abolish_frozen_choice_points_all(void)199 static Int p_abolish_frozen_choice_points_all(void) {
200   abolish_frozen_cps_all();
201   return (TRUE);
202 }
203 
204 
p_table(void)205 static Int p_table(void) {
206   Term mod, t;
207   PredEntry *pe;
208   Atom at;
209   int arity;
210   tab_ent_ptr tab_ent;
211 
212   mod = Deref(ARG1);
213   t = Deref(ARG2);
214   if (IsAtomTerm(t)) {
215     at = AtomOfTerm(t);
216     pe = RepPredProp(PredPropByAtom(at, mod));
217     arity = 0;
218   } else if (IsApplTerm(t)) {
219     at = NameOfFunctor(FunctorOfTerm(t));
220     pe = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod));
221     arity = ArityOfFunctor(FunctorOfTerm(t));
222   } else
223     return (FALSE);
224   if (pe->PredFlags & TabledPredFlag)
225     return (TRUE);  /* predicate already tabled */
226   if (pe->cs.p_code.FirstClause)
227     return (FALSE);  /* predicate already compiled */
228   pe->PredFlags |= TabledPredFlag;
229   new_table_entry(tab_ent, pe, at, arity);
230   pe->TableOfPred = tab_ent;
231   return (TRUE);
232 }
233 
234 
p_tabling_mode(void)235 static Int p_tabling_mode(void) {
236   Term mod, t, tvalue;
237   tab_ent_ptr tab_ent;
238 
239   mod = Deref(ARG1);
240   t = Deref(ARG2);
241   if (IsAtomTerm(t))
242     tab_ent = RepPredProp(PredPropByAtom(AtomOfTerm(t), mod))->TableOfPred;
243   else if (IsApplTerm(t))
244     tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
245   else
246     return (FALSE);
247   tvalue = Deref(ARG3);
248   if (IsVarTerm(tvalue)) {
249     t = TermNil;
250     if (IsMode_LocalTrie(TabEnt_flags(tab_ent)))
251       t = MkPairTerm(MkAtomTerm(AtomLocalTrie), t);
252     else if (IsMode_GlobalTrie(TabEnt_flags(tab_ent)))
253       t = MkPairTerm(MkAtomTerm(AtomGlobalTrie), t);
254     if (IsMode_ExecAnswers(TabEnt_flags(tab_ent)))
255       t = MkPairTerm(MkAtomTerm(AtomExecAnswers), t);
256     else if (IsMode_LoadAnswers(TabEnt_flags(tab_ent)))
257       t = MkPairTerm(MkAtomTerm(AtomLoadAnswers), t);
258     if (IsMode_Batched(TabEnt_flags(tab_ent)))
259       t = MkPairTerm(MkAtomTerm(AtomBatched), t);
260     else if (IsMode_Local(TabEnt_flags(tab_ent)))
261       t = MkPairTerm(MkAtomTerm(AtomLocal), t);
262     t = MkPairTerm(MkAtomTerm(AtomDefault), t);
263     t = MkPairTerm(t, TermNil);
264     if (IsMode_LocalTrie(TabEnt_mode(tab_ent)))
265       t = MkPairTerm(MkAtomTerm(AtomLocalTrie), t);
266     else if (IsMode_GlobalTrie(TabEnt_mode(tab_ent)))
267       t = MkPairTerm(MkAtomTerm(AtomGlobalTrie), t);
268     if (IsMode_ExecAnswers(TabEnt_mode(tab_ent)))
269       t = MkPairTerm(MkAtomTerm(AtomExecAnswers), t);
270     else if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)))
271       t = MkPairTerm(MkAtomTerm(AtomLoadAnswers), t);
272     if (IsMode_Batched(TabEnt_mode(tab_ent)))
273       t = MkPairTerm(MkAtomTerm(AtomBatched), t);
274     else if (IsMode_Local(TabEnt_mode(tab_ent)))
275       t = MkPairTerm(MkAtomTerm(AtomLocal), t);
276     Bind((CELL *) tvalue, t);
277     return(TRUE);
278   } else if (IsIntTerm(tvalue)) {
279     Int value = IntOfTerm(tvalue);
280     if (value == 1) {  /* batched */
281       SetMode_Batched(TabEnt_flags(tab_ent));
282       if (! IsMode_Local(yap_flags[TABLING_MODE_FLAG])) {
283 	SetMode_Batched(TabEnt_mode(tab_ent));
284 	return(TRUE);
285       }
286     } else if (value == 2) {  /* local */
287       SetMode_Local(TabEnt_flags(tab_ent));
288       if (! IsMode_Batched(yap_flags[TABLING_MODE_FLAG])) {
289 	SetMode_Local(TabEnt_mode(tab_ent));
290 	return(TRUE);
291       }
292     } else if (value == 3) {  /* exec_answers */
293       SetMode_ExecAnswers(TabEnt_flags(tab_ent));
294       if (! IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) {
295 	SetMode_ExecAnswers(TabEnt_mode(tab_ent));
296 	return(TRUE);
297       }
298     } else if (value == 4) {  /* load_answers */
299       SetMode_LoadAnswers(TabEnt_flags(tab_ent));
300       if (! IsMode_ExecAnswers(yap_flags[TABLING_MODE_FLAG])) {
301 	SetMode_LoadAnswers(TabEnt_mode(tab_ent));
302 	return(TRUE);
303       }
304     } else if (value == 5) {  /* local_trie */
305       SetMode_LocalTrie(TabEnt_flags(tab_ent));
306       if (! IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) {
307 	SetMode_LocalTrie(TabEnt_mode(tab_ent));
308 	return(TRUE);
309       }
310     } else if (value == 6) {  /* global_trie */
311       SetMode_GlobalTrie(TabEnt_flags(tab_ent));
312       if (! IsMode_LocalTrie(yap_flags[TABLING_MODE_FLAG])) {
313 	SetMode_GlobalTrie(TabEnt_mode(tab_ent));
314 	return(TRUE);
315       }
316     }
317   }
318   return (FALSE);
319 }
320 
321 
p_abolish_table(void)322 static Int p_abolish_table(void) {
323   Term mod, t;
324   tab_ent_ptr tab_ent;
325   sg_hash_ptr hash;
326   sg_node_ptr sg_node;
327 
328   mod = Deref(ARG1);
329   t = Deref(ARG2);
330   if (IsAtomTerm(t))
331     tab_ent = RepPredProp(PredPropByAtom(AtomOfTerm(t), mod))->TableOfPred;
332   else if (IsApplTerm(t))
333     tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
334   else
335     return (FALSE);
336   hash = TabEnt_hash_chain(tab_ent);
337   TabEnt_hash_chain(tab_ent) = NULL;
338   free_subgoal_hash_chain(hash);
339   sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
340   TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
341   if (sg_node) {
342     if (TabEnt_arity(tab_ent)) {
343       TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
344       free_subgoal_trie(sg_node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
345     } else {
346       sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(sg_node);
347       FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
348 #ifdef LIMIT_TABLING
349       remove_from_global_sg_fr_list(sg_fr);
350 #endif /* LIMIT_TABLING */
351       FREE_SUBGOAL_FRAME(sg_fr);
352     }
353   }
354   return (TRUE);
355 }
356 
357 
p_abolish_all_tables(void)358 static Int p_abolish_all_tables(void) {
359   tab_ent_ptr tab_ent;
360   sg_hash_ptr hash;
361   sg_node_ptr sg_node;
362 
363   tab_ent = GLOBAL_root_tab_ent;
364   while(tab_ent) {
365     hash = TabEnt_hash_chain(tab_ent);
366     TabEnt_hash_chain(tab_ent) = NULL;
367     free_subgoal_hash_chain(hash);
368     sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
369     TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
370     if (sg_node) {
371       if (TabEnt_arity(tab_ent)) {
372 	TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
373 	free_subgoal_trie(sg_node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
374       } else {
375 	sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(sg_node);
376 	FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
377 #ifdef LIMIT_TABLING
378 	remove_from_global_sg_fr_list(sg_fr);
379 #endif /* LIMIT_TABLING */
380 	FREE_SUBGOAL_FRAME(sg_fr);
381       }
382     }
383     tab_ent = TabEnt_next(tab_ent);
384   }
385   return (TRUE);
386 }
387 
388 
p_show_tabled_predicates(void)389 static Int p_show_tabled_predicates(void) {
390   tab_ent_ptr tab_ent;
391 
392   tab_ent = GLOBAL_root_tab_ent;
393   fprintf(Yap_stdout, "Tabled predicates\n");
394   if (tab_ent == NULL)
395     fprintf(Yap_stdout, "  NONE\n");
396   else
397     while(tab_ent) {
398       fprintf(Yap_stdout, "  %s/%d\n", AtomName(TabEnt_atom(tab_ent)), TabEnt_arity(tab_ent));
399       tab_ent = TabEnt_next(tab_ent);
400     }
401   return (TRUE);
402 }
403 
404 
p_show_table(void)405 static Int p_show_table(void) {
406   Term mod, t;
407   tab_ent_ptr tab_ent;
408 
409   mod = Deref(ARG1);
410   t = Deref(ARG2);
411   if (IsAtomTerm(t))
412     tab_ent = RepPredProp(PredPropByAtom(AtomOfTerm(t), mod))->TableOfPred;
413   else if (IsApplTerm(t))
414     tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
415   else
416     return (FALSE);
417   show_table(tab_ent, SHOW_MODE_STRUCTURE);
418   return (TRUE);
419 }
420 
421 
p_show_all_tables(void)422 static Int p_show_all_tables(void) {
423   tab_ent_ptr tab_ent;
424 
425   tab_ent = GLOBAL_root_tab_ent;
426   while(tab_ent) {
427     show_table(tab_ent, SHOW_MODE_STRUCTURE);
428     tab_ent = TabEnt_next(tab_ent);
429   }
430   return (TRUE);
431 }
432 
433 
p_show_global_trie(void)434 static Int p_show_global_trie(void) {
435   show_global_trie(SHOW_MODE_STRUCTURE);
436   return (TRUE);
437 }
438 
439 
p_show_statistics_table(void)440 static Int p_show_statistics_table(void) {
441   Term mod, t;
442   tab_ent_ptr tab_ent;
443 
444   mod = Deref(ARG1);
445   t = Deref(ARG2);
446   if (IsAtomTerm(t))
447     tab_ent = RepPredProp(PredPropByAtom(AtomOfTerm(t), mod))->TableOfPred;
448   else if (IsApplTerm(t))
449     tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
450   else
451     return (FALSE);
452   show_table(tab_ent, SHOW_MODE_STATISTICS);
453   return (TRUE);
454 }
455 
456 
p_show_statistics_tabling(void)457 static Int p_show_statistics_tabling(void) {
458   long total_bytes = 0, aux_bytes;
459 
460   aux_bytes = 0;
461   fprintf(Yap_stdout, "Execution data structures\n");
462   aux_bytes += show_statistics_table_entries();
463   aux_bytes += show_statistics_subgoal_frames();
464   aux_bytes += show_statistics_dependency_frames();
465   fprintf(Yap_stdout, "  Memory in use (I):               %10ld bytes\n\n", aux_bytes);
466   total_bytes += aux_bytes;
467   aux_bytes = 0;
468   fprintf(Yap_stdout, "Local trie data structures\n");
469   aux_bytes += show_statistics_subgoal_trie_nodes();
470   aux_bytes += show_statistics_answer_trie_nodes();
471   aux_bytes += show_statistics_subgoal_trie_hashes();
472   aux_bytes += show_statistics_answer_trie_hashes();
473   fprintf(Yap_stdout, "  Memory in use (II):              %10ld bytes\n\n", aux_bytes);
474   total_bytes += aux_bytes;
475   aux_bytes = 0;
476   fprintf(Yap_stdout, "Global trie data structures\n");
477   aux_bytes += show_statistics_global_trie_nodes();
478   aux_bytes += show_statistics_global_trie_hashes();
479   fprintf(Yap_stdout, "  Memory in use (III):             %10ld bytes\n\n", aux_bytes);
480   total_bytes += aux_bytes;
481 #ifdef SHM_MEMORY_ALLOC_SCHEME
482   fprintf(Yap_stdout, "Total memory in use (I+II+III):    %10ld bytes (%ld pages in use)\n",
483           total_bytes, Pg_str_in_use(GLOBAL_PAGES_void));
484   fprintf(Yap_stdout, "Total memory allocated:            %10ld bytes (%ld pages in total)\n",
485           Pg_pg_alloc(GLOBAL_PAGES_void) * Yap_page_size, Pg_pg_alloc(GLOBAL_PAGES_void));
486 #else
487   fprintf(Yap_stdout, "Total memory in use (I+II+III):    %10ld bytes\n", total_bytes);
488 #endif /* SHM_MEMORY_ALLOC_SCHEME */
489 
490   return (TRUE);
491 }
492 
p_show_statistics_global_trie(void)493 static Int p_show_statistics_global_trie(void) {
494   show_global_trie(SHOW_MODE_STATISTICS);
495   return (TRUE);
496 }
497 #endif /* TABLING */
498 
499 
500 /*********************************
501 **      YapOr C Predicates      **
502 *********************************/
503 
p_yapor_threads(void)504 static Int p_yapor_threads(void) {
505 #if defined(YAPOR) && defined(THREADS)
506   return Yap_unify(MkIntegerTerm(number_workers),ARG1);
507 #else
508   return FALSE;
509 #endif
510 }
511 
512 
513 #ifdef YAPOR
p_worker(void)514 static Int p_worker(void) {
515   CurrentModule = USER_MODULE;
516   P = GETWORK_FIRST_TIME;
517   return TRUE;
518 }
519 
520 
p_yapor_on(void)521 static Int p_yapor_on(void) {
522   return (PARALLEL_EXECUTION_MODE);
523 }
524 
525 
p_start_yapor(void)526 static Int p_start_yapor(void) {
527 #ifdef TIMESTAMP_CHECK
528   GLOBAL_timestamp = 0;
529 #endif /* TIMESTAMP_CHECK */
530   GLOBAL_answers = NO_ANSWER;
531   BITMAP_delete(GLOBAL_bm_idle_workers, 0);
532   BITMAP_clear(GLOBAL_bm_invisible_workers);
533   BITMAP_clear(GLOBAL_bm_requestable_workers);
534 #ifdef TABLING_INNER_CUTS
535   BITMAP_clear(GLOBAL_bm_pruning_workers);
536 #endif /* TABLING_INNER_CUTS */
537   make_root_choice_point();
538   GLOBAL_performance_mode &= ~PERFORMANCE_IN_EXECUTION;
539   GLOBAL_execution_time = current_time();
540   BITMAP_clear(GLOBAL_bm_finished_workers);
541   PUT_IN_EXECUTING(worker_id);
542   return (TRUE);
543 }
544 
545 
p_default_sequential(void)546 static Int p_default_sequential(void) {
547   Term t;
548   t = Deref(ARG1);
549   if (IsVarTerm(t)) {
550     Term ta;
551     if (SEQUENTIAL_IS_DEFAULT)
552       ta = MkAtomTerm(Yap_LookupAtom("on"));
553     else
554       ta = MkAtomTerm(Yap_LookupAtom("off"));
555     Bind((CELL *)t, ta);
556     return(TRUE);
557   }
558   if (IsAtomTerm(t)) {
559     char *s;
560     s = RepAtom(AtomOfTerm(t))->StrOfAE;
561     if (strcmp(s, "on") == 0) {
562       SEQUENTIAL_IS_DEFAULT = TRUE;
563       return(TRUE);
564     }
565     if (strcmp(s,"off") == 0) {
566       SEQUENTIAL_IS_DEFAULT = FALSE;
567       return(TRUE);
568     }
569   }
570   return(FALSE);
571 }
572 
573 
p_execution_mode(void)574 static Int p_execution_mode(void) {
575   Term t;
576   t = Deref(ARG1);
577   if (IsVarTerm(t)) {
578     Term ta;
579     if (PARALLEL_EXECUTION_MODE)
580       ta = MkAtomTerm(Yap_LookupAtom("parallel"));
581     else
582       ta = MkAtomTerm(Yap_LookupAtom("sequential"));
583     Bind((CELL *)t, ta);
584     return(TRUE);
585   }
586   if (IsAtomTerm(t)) {
587     char *s;
588     s = RepAtom(AtomOfTerm(t))->StrOfAE;
589     if (strcmp(s,"parallel") == 0) {
590       PARALLEL_EXECUTION_MODE = TRUE;
591       return(TRUE);
592     }
593     if (strcmp(s,"sequential") == 0) {
594       PARALLEL_EXECUTION_MODE = FALSE;
595       return(TRUE);
596     }
597   }
598   return(FALSE);
599 }
600 
601 
p_performance(void)602 static Int p_performance(void) {
603   Term t;
604   realtime one_worker_execution_time = 0;
605   int i;
606 
607   GLOBAL_performance_mode |= PERFORMANCE_IN_EXECUTION;
608   t = Deref(ARG1);
609   if (IsVarTerm(t)) {
610     Term ta;
611     if (GLOBAL_performance_mode & PERFORMANCE_ON) {
612       ta = MkAtomTerm(Yap_LookupAtom("on"));
613     } else {
614       ta = MkAtomTerm(Yap_LookupAtom("off"));
615     }
616     Bind((CELL *)t, ta);
617     return(TRUE);
618   }
619   if (IsAtomTerm(t)) {
620     char *s;
621     s = RepAtom(AtomOfTerm(t))->StrOfAE;
622     if (strcmp(s, "on") == 0) {
623       GLOBAL_performance_mode |= PERFORMANCE_ON;
624       return(TRUE);
625     }
626     if (strcmp(s,"off") == 0) {
627       GLOBAL_performance_mode &= ~PERFORMANCE_ON;
628       return(TRUE);
629     }
630     if (strcmp(s,"clear") == 0) {
631       GLOBAL_number_goals = 0;
632       GLOBAL_best_times(0) = 0;
633       return(TRUE);
634     }
635   }
636   if (IsIntTerm(t))
637     one_worker_execution_time = IntOfTerm(t);
638   else if (IsFloatTerm(t))
639     one_worker_execution_time = FloatOfTerm(t);
640   else
641     return(FALSE);
642 
643   if (GLOBAL_number_goals) {
644     fprintf(Yap_stdout, "[\n  Best execution times:\n");
645     for (i = 1; i <= GLOBAL_number_goals; i++) {
646       fprintf(Yap_stdout, "    %d. time: %f seconds", i, GLOBAL_best_times(i));
647       if (one_worker_execution_time != 0)
648         fprintf(Yap_stdout, " --> speedup %f (%6.2f %% )\n",
649                 one_worker_execution_time / GLOBAL_best_times(i),
650                 one_worker_execution_time / GLOBAL_best_times(i) / number_workers * 100 );
651       else fprintf(Yap_stdout, "\n");
652     }
653 
654     fprintf(Yap_stdout, "  Average             : %f seconds",
655             GLOBAL_best_times(0) / GLOBAL_number_goals);
656     if (one_worker_execution_time != 0)
657       fprintf(Yap_stdout, " --> speedup %f (%6.2f %% )",
658               one_worker_execution_time * GLOBAL_number_goals / GLOBAL_best_times(0),
659               one_worker_execution_time * GLOBAL_number_goals / GLOBAL_best_times(0) / number_workers * 100 );
660 
661     if (GLOBAL_number_goals >= 3) {
662       fprintf(Yap_stdout, "\n  Average (best three): %f seconds",
663               (GLOBAL_best_times(1) + GLOBAL_best_times(2) + GLOBAL_best_times(3)) / 3);
664       if (one_worker_execution_time != 0)
665         fprintf(Yap_stdout, " --> speedup %f (%6.2f %% ) ]\n\n",
666                 one_worker_execution_time * 3 / (GLOBAL_best_times(1) + GLOBAL_best_times(2) + GLOBAL_best_times(3)),
667                 one_worker_execution_time * 3 / (GLOBAL_best_times(1) + GLOBAL_best_times(2) + GLOBAL_best_times(3)) / number_workers * 100 );
668       else fprintf(Yap_stdout, "\n]\n\n");
669     } else fprintf(Yap_stdout, "\n]\n\n");
670     return (TRUE);
671   }
672   return (FALSE);
673 }
674 
675 
p_parallel_new_answer(void)676 static Int p_parallel_new_answer(void) {
677   or_fr_ptr leftmost_or_fr;
678 
679   length_answer = 0;
680   ALLOC_QG_ANSWER_FRAME(actual_answer);
681   Yap_plwrite(ARG1, parallel_new_answer_putchar, 4, 1200);
682   AnsFr_answer(actual_answer)[length_answer] = 0;
683   AnsFr_next(actual_answer) = NULL;
684   leftmost_or_fr = CUT_leftmost_or_frame();
685   LOCK_OR_FRAME(leftmost_or_fr);
686   if (Get_LOCAL_prune_request()) {
687     UNLOCK_OR_FRAME(leftmost_or_fr);
688     FREE_QG_ANSWER_FRAME(actual_answer);
689   } else {
690     CUT_store_answer(leftmost_or_fr, actual_answer);
691     UNLOCK_OR_FRAME(leftmost_or_fr);
692   }
693   return (TRUE);
694 }
695 
696 
p_parallel_yes_answer(void)697 static Int p_parallel_yes_answer(void) {
698   GLOBAL_answers = YES_ANSWER;
699   return (TRUE);
700 }
701 
702 
p_show_statistics_or(void)703 static Int p_show_statistics_or(void) {
704   long total_bytes = 0, aux_bytes;
705 
706   aux_bytes = 0;
707   fprintf(Yap_stdout, "Execution data structures\n");
708   aux_bytes += show_statistics_or_frames();
709   fprintf(Yap_stdout, "  Memory in use (I):               %10ld bytes\n\n", aux_bytes);
710   total_bytes += aux_bytes;
711   aux_bytes = 0;
712   fprintf(Yap_stdout, "Cut support data structures\n");
713   aux_bytes += show_statistics_query_goal_solution_frames();
714   aux_bytes += show_statistics_query_goal_answer_frames();
715   fprintf(Yap_stdout, "  Memory in use (II):              %10ld bytes\n\n", aux_bytes);
716   total_bytes += aux_bytes;
717 #ifdef SHM_MEMORY_ALLOC_SCHEME
718   fprintf(Yap_stdout, "Total memory in use (I+II+III):    %10ld bytes (%ld pages in use)\n",
719           total_bytes, Pg_str_in_use(GLOBAL_PAGES_void));
720   fprintf(Yap_stdout, "Total memory allocated:            %10ld bytes (%ld pages in total)\n",
721           Pg_pg_alloc(GLOBAL_PAGES_void) * Yap_page_size, Pg_pg_alloc(GLOBAL_PAGES_void));
722 #else
723   fprintf(Yap_stdout, "Total memory in use (I+II+III):    %10ld bytes\n", total_bytes);
724 #endif /* SHM_MEMORY_ALLOC_SCHEME */
725 
726   return (TRUE);
727 }
728 #endif /* YAPOR */
729 
730 
731 
732 /**********************************
733 **      OPTYap C Predicates      **
734 **********************************/
735 
736 #if defined(YAPOR) && defined(TABLING)
p_show_statistics_opt(void)737 static Int p_show_statistics_opt(void) {
738   long total_bytes = 0, aux_bytes;
739 
740   aux_bytes = 0;
741   fprintf(Yap_stdout, "Execution data structures\n");
742   aux_bytes += show_statistics_table_entries();
743   aux_bytes += show_statistics_subgoal_frames();
744   aux_bytes += show_statistics_dependency_frames();
745   aux_bytes += show_statistics_or_frames();
746   aux_bytes += show_statistics_suspension_frames();
747   fprintf(Yap_stdout, "  Memory in use (I):               %10ld bytes\n\n", aux_bytes);
748   total_bytes += aux_bytes;
749   aux_bytes = 0;
750   fprintf(Yap_stdout, "Local trie data structures\n");
751   aux_bytes += show_statistics_subgoal_trie_nodes();
752   aux_bytes += show_statistics_answer_trie_nodes();
753   aux_bytes += show_statistics_subgoal_trie_hashes();
754   aux_bytes += show_statistics_answer_trie_hashes();
755   fprintf(Yap_stdout, "  Memory in use (II):              %10ld bytes\n\n", aux_bytes);
756   total_bytes += aux_bytes;
757   aux_bytes = 0;
758   fprintf(Yap_stdout, "Global trie data structures\n");
759   aux_bytes += show_statistics_global_trie_nodes();
760   aux_bytes += show_statistics_global_trie_hashes();
761   fprintf(Yap_stdout, "  Memory in use (III):             %10ld bytes\n\n", aux_bytes);
762   total_bytes += aux_bytes;
763   aux_bytes = 0;
764   fprintf(Yap_stdout, "Cut support data structures\n");
765   aux_bytes += show_statistics_query_goal_solution_frames();
766   aux_bytes += show_statistics_query_goal_answer_frames();
767 #ifdef TABLING_INNER_CUTS
768   aux_bytes += show_statistics_table_subgoal_solution_frames();
769   aux_bytes += show_statistics_table_subgoal_answer_frames();
770 #endif /* TABLING_INNER_CUTS */
771   fprintf(Yap_stdout, "  Memory in use (IV):              %10ld bytes\n\n", aux_bytes);
772   total_bytes += aux_bytes;
773 #ifdef SHM_MEMORY_ALLOC_SCHEME
774   fprintf(Yap_stdout, "Total memory in use (I+II+III+IV): %10ld bytes (%ld pages in use)\n",
775           total_bytes, Pg_str_in_use(GLOBAL_PAGES_void));
776   fprintf(Yap_stdout, "Total memory allocated:            %10ld bytes (%ld pages in total)\n",
777           Pg_pg_alloc(GLOBAL_PAGES_void) * Yap_page_size, Pg_pg_alloc(GLOBAL_PAGES_void));
778 #else
779   fprintf(Yap_stdout, "Total memory in use (I+II+III+IV): %10ld bytes\n", total_bytes);
780 #endif /* SHM_MEMORY_ALLOC_SCHEME */
781 
782   return (TRUE);
783 }
784 #endif /* YAPOR && TABLING */
785 
786 
p_get_optyap_statistics(void)787 static Int p_get_optyap_statistics(void) {
788   Term tbytes, tstructs;
789   Int value, bytes = -1, structs = -1;
790 
791   value = IntOfTerm(Deref(ARG1));
792   if (value == 0) {  /* total_memory */
793     bytes = 0;
794 #ifdef TABLING
795     bytes += Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry);
796     bytes += Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame);
797     bytes += Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame);
798     bytes += Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node);
799     bytes += Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node);
800     bytes += Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_trie_hash);
801     bytes += Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_trie_hash);
802     bytes += Pg_str_in_use(GLOBAL_PAGES_gt_node) * sizeof(struct global_trie_node);
803     bytes += Pg_str_in_use(GLOBAL_PAGES_gt_hash) * sizeof(struct global_trie_hash);
804 #endif /* TABLING */
805 #ifdef YAPOR
806     bytes += Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame);
807     bytes += Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame);
808     bytes += Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame);
809 #endif /* YAPOR */
810 #if defined(YAPOR) && defined(TABLING)
811     bytes += Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame);
812 #ifdef TABLING_INNER_CUTS
813     bytes += Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame);
814     bytes += Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame);
815 #endif /* TABLING_INNER_CUTS */
816 #endif /* YAPOR && TABLING */
817 #ifdef SHM_MEMORY_ALLOC_SCHEME
818     structs = Pg_pg_alloc(GLOBAL_PAGES_void) * Yap_page_size;
819 #else
820     structs = bytes;
821 #endif /* SHM_MEMORY_ALLOC_SCHEME */
822   }
823 #ifdef TABLING
824   if (value == 1) {  /* table_entries */
825     bytes = Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry);
826     structs = Pg_str_in_use(GLOBAL_PAGES_tab_ent);
827   }
828   if (value == 2) {  /* subgoal_frames */
829     bytes = Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame);
830     structs = Pg_str_in_use(GLOBAL_PAGES_sg_fr);
831   }
832   if (value == 3) {  /* dependency_frames */
833     bytes = Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame);
834     structs = Pg_str_in_use(GLOBAL_PAGES_dep_fr);
835   }
836   if (value == 6) {  /* subgoal_trie_nodes */
837     bytes = Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node);
838     structs = Pg_str_in_use(GLOBAL_PAGES_sg_node);
839   }
840   if (value == 7) {  /* answer_trie_nodes */
841     bytes = Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node);
842     structs = Pg_str_in_use(GLOBAL_PAGES_ans_node);
843   }
844   if (value == 8) {  /* subgoal_trie_hashes */
845     bytes = Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_trie_hash);
846     structs = Pg_str_in_use(GLOBAL_PAGES_sg_hash);
847   }
848   if (value == 9) {  /* answer_trie_hashes */
849     bytes = Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_trie_hash);
850     structs = Pg_str_in_use(GLOBAL_PAGES_ans_hash);
851   }
852   if (value == 10) {  /* global_trie_nodes */
853     bytes = Pg_str_in_use(GLOBAL_PAGES_gt_node) * sizeof(struct global_trie_node);
854     structs = Pg_str_in_use(GLOBAL_PAGES_gt_node);
855   }
856   if (value == 11) {  /* global_trie_hashes */
857     bytes = Pg_str_in_use(GLOBAL_PAGES_gt_hash) * sizeof(struct global_trie_hash);
858     structs = Pg_str_in_use(GLOBAL_PAGES_gt_hash);
859   }
860 #endif /* TABLING */
861 #ifdef YAPOR
862   if (value == 4) {  /* or_frames */
863     bytes = Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame);
864     structs = Pg_str_in_use(GLOBAL_PAGES_or_fr);
865   }
866   if (value == 12) {  /* query_goal_solution_frames */
867     bytes = Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame);
868     structs = Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr);
869   }
870   if (value == 13) {  /* query_goal_answer_frames */
871     bytes = Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame);
872     structs = Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr);
873   }
874 #endif /* YAPOR */
875 #if defined(YAPOR) && defined(TABLING)
876   if (value == 5) {  /* suspension_frames */
877     bytes = Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame);
878     structs = Pg_str_in_use(GLOBAL_PAGES_susp_fr);
879   }
880 #ifdef TABLING_INNER_CUTS
881   if (value == 14) {  /* table_subgoal_solution_frames */
882     bytes = Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame);
883     structs = Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr);
884   }
885   if (value == 15) {  /* table_subgoal_answer_frames */
886     bytes = Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame);
887     structs = Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr);
888   }
889 #endif /* TABLING_INNER_CUTS */
890 #endif /* YAPOR && TABLING */
891   if (bytes == -1)
892     return (FALSE);
893   tbytes = Deref(ARG2);
894   tstructs = Deref(ARG3);
895   if (IsVarTerm(tbytes)) {
896     Bind((CELL *) tbytes, MkIntTerm(bytes));
897   } else if (IsIntTerm(tbytes) &&  IntOfTerm(tbytes) != bytes)
898     return (FALSE);
899   if (IsVarTerm(tstructs)) {
900     Bind((CELL *) tstructs, MkIntTerm(structs));
901   } else if (IsIntTerm(tstructs) &&  IntOfTerm(tstructs) != structs)
902     return (FALSE);
903   return (TRUE);
904 }
905 
906 
907 
908 /******************************
909 **      Local functions      **
910 ******************************/
911 
912 #ifdef YAPOR
current_time(void)913 static inline realtime current_time(void) {
914   /* to get time as Yap */
915   /*
916   double now, interval;
917   Yap_cputime_interval(&now, &interval);
918   return ((realtime)now);
919   */
920   struct timeval tempo;
921   gettimeofday(&tempo, NULL);
922   return ((realtime)tempo.tv_sec + (realtime)tempo.tv_usec / TIME_RESOLUTION);
923 }
924 
parallel_new_answer_putchar(int sno,int ch)925 static inline int parallel_new_answer_putchar(int sno, int ch) {
926   AnsFr_answer(actual_answer)[length_answer++] = ch;
927   return ch;
928 }
929 
930 
show_answers(void)931 static inline void show_answers(void) {
932   int i;
933   if (OrFr_qg_solutions(LOCAL_top_or_fr)) {
934     qg_ans_fr_ptr aux_answer1, aux_answer2;
935     aux_answer1 = SolFr_first(OrFr_qg_solutions(LOCAL_top_or_fr));
936     while (aux_answer1) {
937       answer_to_stdout(AnsFr_answer(aux_answer1));
938       aux_answer2 = aux_answer1;
939       aux_answer1 = AnsFr_next(aux_answer1);
940       FREE_QG_ANSWER_FRAME(aux_answer2);
941       GLOBAL_answers++;
942     }
943     FREE_QG_SOLUTION_FRAME(OrFr_qg_solutions(LOCAL_top_or_fr));
944     OrFr_qg_solutions(LOCAL_top_or_fr) = NULL;
945   }
946   switch(GLOBAL_answers) {
947     case YES_ANSWER:
948       fprintf(Yap_stderr, "[ yes");
949       break;
950     case NO_ANSWER:
951       fprintf(Yap_stderr, "[ no");
952       break;
953     case 1:
954       fprintf(Yap_stderr, "[ 1 answer found");
955       break;
956     default:
957          fprintf(Yap_stderr, "[ %d answers found", GLOBAL_answers);
958       break;
959   }
960   fprintf(Yap_stderr, " (in %f seconds) ]\n\n", GLOBAL_execution_time);
961 
962   if (GLOBAL_performance_mode == PERFORMANCE_ON) {
963     for (i = GLOBAL_number_goals; i > 0; i--) {
964       if (GLOBAL_best_times(i) > GLOBAL_execution_time) {
965         if (i + 1 < MAX_BEST_TIMES)
966           GLOBAL_best_times(i + 1) = GLOBAL_best_times(i);
967         else {
968           GLOBAL_best_times(0) -= GLOBAL_best_times(i);
969         }
970       }
971       else break;
972     }
973     if (i + 1 < MAX_BEST_TIMES) {
974       GLOBAL_best_times(0) += GLOBAL_execution_time;
975       GLOBAL_best_times(i + 1) = GLOBAL_execution_time;
976       if (GLOBAL_number_goals + 1 < MAX_BEST_TIMES)
977         GLOBAL_number_goals++;
978     }
979   }
980 
981   return;
982 }
983 
984 
answer_to_stdout(char * answer)985 static inline void answer_to_stdout(char *answer) {
986   int length_answer = 0, length_output = 0, caracter, list, par_rectos;
987   char output[MAX_LENGTH_ANSWER];
988   while (1) {
989     length_answer += 2;
990     while (answer[length_answer] != ']') {
991       length_answer++;
992       caracter = 0;
993       while (answer[length_answer] != ',' && answer[length_answer] != ']')
994 	caracter = caracter * 10 + answer[length_answer++] - '0';
995       output[length_output++] = caracter;
996     }
997     length_answer++;
998     output[length_output++] = ' ';
999     output[length_output++] = '=';
1000     output[length_output++] = ' ';
1001     if (answer[length_answer++] == ',') {
1002       list = 1;
1003       output[length_output++] = '[';
1004     } else list = 0;
1005     par_rectos = 1;
1006     while (1) {
1007       if (answer[length_answer] == '[') par_rectos++;
1008       else if (answer[length_answer] == ']' && --par_rectos == 0) break;
1009       output[length_output++] = answer[length_answer++];
1010     }
1011     if (list) output[length_output++] = ']';
1012     if (answer[++length_answer] != ']') {
1013       output[length_output++] = ' ';
1014       output[length_output++] = ';';
1015       output[length_output++] = ' ';
1016     }
1017     else break;
1018   }
1019   output[length_output] = 0;
1020   fprintf(Yap_stderr, "  %s\n", output);
1021   return;
1022 }
1023 #endif /* YAPOR */
1024 
1025 
1026 #ifdef TABLING
show_statistics_table_entries(void)1027 static inline long show_statistics_table_entries(void) {
1028 #ifdef SHM_MEMORY_ALLOC_SCHEME
1029 #ifdef DEBUG_TABLING
1030   pg_hd_ptr pg_hd;
1031   tab_ent_ptr aux_ptr;
1032   long cont = 0;
1033 
1034   pg_hd = Pg_free_pg(GLOBAL_PAGES_tab_ent);
1035   while (pg_hd) {
1036     aux_ptr = PgHd_free_str(pg_hd);
1037     while (aux_ptr) {
1038       cont++;
1039       aux_ptr = TabEnt_next(aux_ptr);
1040     }
1041     pg_hd = PgHd_next(pg_hd);
1042   }
1043   TABLING_ERROR_CHECKING(statistics_table_entries, Pg_str_free(GLOBAL_PAGES_tab_ent) != cont);
1044 #endif /* DEBUG_TABLING */
1045   fprintf(Yap_stdout, "  Table entries:                   %10ld bytes (%ld pages and %ld structs in use)\n",
1046           Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry), Pg_pg_alloc(GLOBAL_PAGES_tab_ent), Pg_str_in_use(GLOBAL_PAGES_tab_ent));
1047 #else
1048   fprintf(Yap_stdout, "  Table entries:                   %10ld bytes (%ld structs in use)\n",
1049           Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry), Pg_str_in_use(GLOBAL_PAGES_tab_ent));
1050 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1051   return Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry);
1052 }
1053 
1054 
show_statistics_subgoal_frames(void)1055 static inline long show_statistics_subgoal_frames(void) {
1056 #ifdef SHM_MEMORY_ALLOC_SCHEME
1057 #ifdef DEBUG_TABLING
1058   pg_hd_ptr pg_hd;
1059   sg_fr_ptr aux_ptr;
1060   long cont = 0;
1061 
1062   pg_hd = Pg_free_pg(GLOBAL_PAGES_sg_fr);
1063   while (pg_hd) {
1064     aux_ptr = PgHd_free_str(pg_hd);
1065     while (aux_ptr) {
1066       cont++;
1067       aux_ptr = SgFr_next(aux_ptr);
1068     }
1069     pg_hd = PgHd_next(pg_hd);
1070   }
1071   TABLING_ERROR_CHECKING(statistics_subgoal_frames, Pg_str_free(GLOBAL_PAGES_sg_fr) != cont);
1072 #endif /* DEBUG_TABLING */
1073   fprintf(Yap_stdout, "  Subgoal frames:                  %10ld bytes (%ld pages and %ld structs in use)\n",
1074           Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame), Pg_pg_alloc(GLOBAL_PAGES_sg_fr), Pg_str_in_use(GLOBAL_PAGES_sg_fr));
1075 #else
1076   fprintf(Yap_stdout, "  Subgoal frames:                  %10ld bytes (%ld structs in use)\n",
1077           Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame), Pg_str_in_use(GLOBAL_PAGES_sg_fr));
1078 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1079   return Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame);
1080 }
1081 
1082 
show_statistics_dependency_frames(void)1083 static inline long show_statistics_dependency_frames(void) {
1084 #ifdef SHM_MEMORY_ALLOC_SCHEME
1085 #ifdef DEBUG_TABLING
1086   pg_hd_ptr pg_hd;
1087   dep_fr_ptr aux_ptr;
1088   long cont = 0;
1089 
1090   pg_hd = Pg_free_pg(GLOBAL_PAGES_dep_fr);
1091   while (pg_hd) {
1092     aux_ptr = PgHd_free_str(pg_hd);
1093     while (aux_ptr) {
1094       cont++;
1095       aux_ptr = DepFr_next(aux_ptr);
1096     }
1097     pg_hd = PgHd_next(pg_hd);
1098   }
1099   TABLING_ERROR_CHECKING(statistics_dependency_frames, Pg_str_free(GLOBAL_PAGES_dep_fr) != cont);
1100 #endif /* DEBUG_TABLING */
1101   fprintf(Yap_stdout, "  Dependency frames:               %10ld bytes (%ld pages and %ld structs in use)\n",
1102           Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame), Pg_pg_alloc(GLOBAL_PAGES_dep_fr), Pg_str_in_use(GLOBAL_PAGES_dep_fr));
1103 #else
1104   fprintf(Yap_stdout, "  Dependency frames:               %10ld bytes (%ld structs in use)\n",
1105           Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame), Pg_str_in_use(GLOBAL_PAGES_dep_fr));
1106 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1107   return Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame);
1108 }
1109 
1110 
show_statistics_subgoal_trie_nodes(void)1111 static inline long show_statistics_subgoal_trie_nodes(void) {
1112 #ifdef SHM_MEMORY_ALLOC_SCHEME
1113 #ifdef DEBUG_TABLING
1114   pg_hd_ptr pg_hd;
1115   sg_node_ptr aux_ptr;
1116   long cont = 0;
1117 
1118   pg_hd = Pg_free_pg(GLOBAL_PAGES_sg_node);
1119   while (pg_hd) {
1120     aux_ptr = PgHd_free_str(pg_hd);
1121     while (aux_ptr) {
1122       cont++;
1123       aux_ptr = TrNode_next(aux_ptr);
1124     }
1125     pg_hd = PgHd_next(pg_hd);
1126   }
1127   TABLING_ERROR_CHECKING(statistics_subgoal_trie_nodes, Pg_str_free(GLOBAL_PAGES_sg_node) != cont);
1128 #endif /* DEBUG_TABLING */
1129   fprintf(Yap_stdout, "  Subgoal trie nodes:              %10ld bytes (%ld pages and %ld structs in use)\n",
1130           Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node), Pg_pg_alloc(GLOBAL_PAGES_sg_node), Pg_str_in_use(GLOBAL_PAGES_sg_node));
1131 #else
1132   fprintf(Yap_stdout, "  Subgoal trie nodes:              %10ld bytes (%ld structs in use)\n",
1133           Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node), Pg_str_in_use(GLOBAL_PAGES_sg_node));
1134 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1135   return Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node);
1136 }
1137 
1138 
show_statistics_answer_trie_nodes(void)1139 static inline long show_statistics_answer_trie_nodes(void) {
1140 #ifdef SHM_MEMORY_ALLOC_SCHEME
1141 #ifdef DEBUG_TABLING
1142   pg_hd_ptr pg_hd;
1143   ans_node_ptr aux_ptr;
1144   long cont = 0;
1145 
1146   pg_hd = Pg_free_pg(GLOBAL_PAGES_ans_node);
1147   while (pg_hd) {
1148     aux_ptr = PgHd_free_str(pg_hd);
1149     while (aux_ptr) {
1150       cont++;
1151       aux_ptr = TrNode_next(aux_ptr);
1152     }
1153     pg_hd = PgHd_next(pg_hd);
1154   }
1155   TABLING_ERROR_CHECKING(statistics_answer_trie_nodes, Pg_str_free(GLOBAL_PAGES_ans_node) != cont);
1156 #endif /* DEBUG_TABLING */
1157   fprintf(Yap_stdout, "  Answer trie nodes:               %10ld bytes (%ld pages and %ld structs in use)\n",
1158           Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node), Pg_pg_alloc(GLOBAL_PAGES_ans_node), Pg_str_in_use(GLOBAL_PAGES_ans_node));
1159 #else
1160   fprintf(Yap_stdout, "  Answer trie nodes:               %10ld bytes (%ld structs in use)\n",
1161           Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node), Pg_str_in_use(GLOBAL_PAGES_ans_node));
1162 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1163   return Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node);
1164 }
1165 
1166 
show_statistics_subgoal_trie_hashes(void)1167 static inline long show_statistics_subgoal_trie_hashes(void) {
1168 #ifdef SHM_MEMORY_ALLOC_SCHEME
1169 #ifdef DEBUG_TABLING
1170   pg_hd_ptr pg_hd;
1171   sg_hash_ptr aux_ptr;
1172   long cont = 0;
1173 
1174   pg_hd = Pg_free_pg(GLOBAL_PAGES_sg_hash);
1175   while (pg_hd) {
1176     aux_ptr = PgHd_free_str(pg_hd);
1177     while (aux_ptr) {
1178       cont++;
1179       aux_ptr = Hash_next(aux_ptr);
1180     }
1181     pg_hd = PgHd_next(pg_hd);
1182   }
1183   TABLING_ERROR_CHECKING(statistics_subgoal_trie_hashes, Pg_str_free(GLOBAL_PAGES_sg_hash) != cont);
1184 #endif /* DEBUG_TABLING */
1185   fprintf(Yap_stdout, "  Subgoal trie hashes:             %10ld bytes (%ld pages and %ld structs in use)\n",
1186           Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_trie_hash), Pg_pg_alloc(GLOBAL_PAGES_sg_hash), Pg_str_in_use(GLOBAL_PAGES_sg_hash));
1187 #else
1188   fprintf(Yap_stdout, "  Subgoal trie hashes:             %10ld bytes (%ld structs in use)\n",
1189           Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_trie_hash), Pg_str_in_use(GLOBAL_PAGES_sg_hash));
1190 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1191   return Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_trie_hash);
1192 }
1193 
1194 
show_statistics_answer_trie_hashes(void)1195 static inline long show_statistics_answer_trie_hashes(void) {
1196 #ifdef SHM_MEMORY_ALLOC_SCHEME
1197 #ifdef DEBUG_TABLING
1198   pg_hd_ptr pg_hd;
1199   ans_hash_ptr aux_ptr;
1200   long cont = 0;
1201 
1202   pg_hd = Pg_free_pg(GLOBAL_PAGES_ans_hash);
1203   while (pg_hd) {
1204     aux_ptr = PgHd_free_str(pg_hd);
1205     while (aux_ptr) {
1206       cont++;
1207       aux_ptr = Hash_next(aux_ptr);
1208     }
1209     pg_hd = PgHd_next(pg_hd);
1210   }
1211   TABLING_ERROR_CHECKING(statistics_answer_trie_hashes, Pg_str_free(GLOBAL_PAGES_ans_hash) != cont);
1212 #endif /* DEBUG_TABLING */
1213   fprintf(Yap_stdout, "  Answer trie hashes:              %10ld bytes (%ld pages and %ld structs in use)\n",
1214           Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_trie_hash), Pg_pg_alloc(GLOBAL_PAGES_ans_hash), Pg_str_in_use(GLOBAL_PAGES_ans_hash));
1215 #else
1216   fprintf(Yap_stdout, "  Answer trie hashes:              %10ld bytes (%ld structs in use)\n",
1217           Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_trie_hash), Pg_str_in_use(GLOBAL_PAGES_ans_hash));
1218 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1219   return Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_trie_hash);
1220 }
1221 
1222 
show_statistics_global_trie_nodes(void)1223 static inline long show_statistics_global_trie_nodes(void) {
1224 #ifdef SHM_MEMORY_ALLOC_SCHEME
1225 #ifdef DEBUG_TABLING
1226   pg_hd_ptr pg_hd;
1227   gt_node_ptr aux_ptr;
1228   long cont = 0;
1229 
1230   pg_hd = Pg_free_pg(GLOBAL_PAGES_gt_node);
1231   while (pg_hd) {
1232     aux_ptr = PgHd_free_str(pg_hd);
1233     while (aux_ptr) {
1234       cont++;
1235       aux_ptr = TrNode_next(aux_ptr);
1236     }
1237     pg_hd = PgHd_next(pg_hd);
1238   }
1239   TABLING_ERROR_CHECKING(statistics_global_trie_nodes, Pg_str_free(GLOBAL_PAGES_gt_node) != cont);
1240 #endif /* DEBUG_TABLING */
1241   fprintf(Yap_stdout, "  Global trie nodes:               %10ld bytes (%ld pages and %ld structs in use)\n",
1242 	  Pg_str_in_use(GLOBAL_PAGES_gt_node) * sizeof(struct global_trie_node), Pg_pg_alloc(GLOBAL_PAGES_gt_node), Pg_str_in_use(GLOBAL_PAGES_gt_node));
1243 #else
1244   fprintf(Yap_stdout, "  Global trie nodes:               %10ld bytes (%ld structs in use)\n",
1245 	  Pg_str_in_use(GLOBAL_PAGES_gt_node) * sizeof(struct global_trie_node), Pg_str_in_use(GLOBAL_PAGES_gt_node));
1246 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1247   return Pg_str_in_use(GLOBAL_PAGES_gt_node) * sizeof(struct global_trie_node);
1248 }
1249 
1250 
show_statistics_global_trie_hashes(void)1251 static inline long show_statistics_global_trie_hashes(void) {
1252 #ifdef SHM_MEMORY_ALLOC_SCHEME
1253 #ifdef DEBUG_TABLING
1254   pg_hd_ptr pg_hd;
1255   gt_hash_ptr aux_ptr;
1256   long cont = 0;
1257 
1258   pg_hd = Pg_free_pg(GLOBAL_PAGES_gt_hash);
1259   while (pg_hd) {
1260     aux_ptr = PgHd_free_str(pg_hd);
1261     while (aux_ptr) {
1262       cont++;
1263       aux_ptr = Hash_next(aux_ptr);
1264     }
1265     pg_hd = PgHd_next(pg_hd);
1266   }
1267   TABLING_ERROR_CHECKING(statistics_global_trie_hashes, Pg_str_free(GLOBAL_PAGES_gt_hash) != cont);
1268 #endif /* DEBUG_TABLING */
1269   fprintf(Yap_stdout, "  Global trie hashes:              %10ld bytes (%ld pages and %ld structs in use)\n",
1270           Pg_str_in_use(GLOBAL_PAGES_gt_hash) * sizeof(struct global_trie_hash), Pg_pg_alloc(GLOBAL_PAGES_gt_hash), Pg_str_in_use(GLOBAL_PAGES_gt_hash));
1271 #else
1272   fprintf(Yap_stdout, "  Global trie hashes:              %10ld bytes (%ld structs in use)\n",
1273           Pg_str_in_use(GLOBAL_PAGES_gt_hash) * sizeof(struct global_trie_hash), Pg_str_in_use(GLOBAL_PAGES_gt_hash));
1274 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1275   return Pg_str_in_use(GLOBAL_PAGES_gt_hash) * sizeof(struct global_trie_hash);
1276 }
1277 #endif /* TABLING */
1278 
1279 
1280 #ifdef YAPOR
show_statistics_or_frames(void)1281 static inline long show_statistics_or_frames(void) {
1282 #ifdef SHM_MEMORY_ALLOC_SCHEME
1283 #ifdef DEBUG_YAPOR
1284   pg_hd_ptr pg_hd;
1285   or_fr_ptr aux_ptr;
1286   long cont = 0;
1287 
1288   pg_hd = Pg_free_pg(GLOBAL_PAGES_or_fr);
1289   while (pg_hd) {
1290     aux_ptr = PgHd_free_str(pg_hd);
1291     while (aux_ptr) {
1292       cont++;
1293       aux_ptr = OrFr_next(aux_ptr);
1294     }
1295     pg_hd = PgHd_next(pg_hd);
1296   }
1297   YAPOR_ERROR_CHECKING(statistics_or_frames, Pg_str_free(GLOBAL_PAGES_or_fr) != cont);
1298 #endif /* DEBUG_YAPOR */
1299   fprintf(Yap_stdout, "  Or-frames:                       %10ld bytes (%ld pages and %ld structs in use)\n",
1300           Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame), Pg_pg_alloc(GLOBAL_PAGES_or_fr), Pg_str_in_use(GLOBAL_PAGES_or_fr));
1301 #else
1302   fprintf(Yap_stdout, "  Or-frames:                       %10ld bytes (%ld structs in use)\n",
1303           Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame), Pg_str_in_use(GLOBAL_PAGES_or_fr));
1304 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1305   return Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame);
1306 }
1307 
1308 
show_statistics_query_goal_solution_frames(void)1309 static inline long show_statistics_query_goal_solution_frames(void) {
1310 #ifdef SHM_MEMORY_ALLOC_SCHEME
1311 #ifdef DEBUG_YAPOR
1312   pg_hd_ptr pg_hd;
1313   qg_sol_fr_ptr aux_ptr;
1314   long cont = 0;
1315 
1316   pg_hd = Pg_free_pg(GLOBAL_PAGES_qg_sol_fr);
1317   while (pg_hd) {
1318     aux_ptr = PgHd_free_str(pg_hd);
1319     while (aux_ptr) {
1320       cont++;
1321       aux_ptr = SolFr_next(aux_ptr);
1322     }
1323     pg_hd = PgHd_next(pg_hd);
1324   }
1325   YAPOR_ERROR_CHECKING(statistics_query_goal_solution_frames, Pg_str_free(GLOBAL_PAGES_qg_sol_fr) != cont);
1326 #endif /* DEBUG_YAPOR */
1327   fprintf(Yap_stdout, "  Query goal solution frames:      %10ld bytes (%ld pages and %ld structs in use)\n",
1328           Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame), Pg_pg_alloc(GLOBAL_PAGES_qg_sol_fr), Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr));
1329 #else
1330   fprintf(Yap_stdout, "  Query goal solution frames:      %10ld bytes (%ld structs in use)\n",
1331           Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame), Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr));
1332 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1333   return Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame);
1334 }
1335 
1336 
show_statistics_query_goal_answer_frames(void)1337 static inline long show_statistics_query_goal_answer_frames(void) {
1338 #ifdef SHM_MEMORY_ALLOC_SCHEME
1339 #ifdef DEBUG_YAPOR
1340   pg_hd_ptr pg_hd;
1341   qg_ans_fr_ptr aux_ptr;
1342   long cont = 0;
1343 
1344   pg_hd = Pg_free_pg(GLOBAL_PAGES_qg_ans_fr);
1345   while (pg_hd) {
1346     aux_ptr = PgHd_free_str(pg_hd);
1347     while (aux_ptr) {
1348       cont++;
1349       aux_ptr = AnsFr_next(aux_ptr);
1350     }
1351     pg_hd = PgHd_next(pg_hd);
1352   }
1353   YAPOR_ERROR_CHECKING(statistics_query_goal_answer_frames, Pg_str_free(GLOBAL_PAGES_qg_ans_fr) != cont);
1354 #endif /* DEBUG_YAPOR */
1355   fprintf(Yap_stdout, "  Query goal answer frames:        %10ld bytes (%ld pages and %ld structs in use)\n",
1356           Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame), Pg_pg_alloc(GLOBAL_PAGES_qg_ans__fr), Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr));
1357 #else
1358   fprintf(Yap_stdout, "  Query goal answer frames:        %10ld bytes (%ld structs in use)\n",
1359           Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame), Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr));
1360 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1361   return Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame);
1362 }
1363 #endif /* YAPOR */
1364 
1365 
1366 #if defined(YAPOR) && defined(TABLING)
show_statistics_suspension_frames(void)1367 static inline long show_statistics_suspension_frames(void) {
1368 #ifdef SHM_MEMORY_ALLOC_SCHEME
1369 #ifdef DEBUG_OPTYAP
1370   pg_hd_ptr pg_hd;
1371   susp_fr_ptr aux_ptr;
1372   long cont = 0;
1373 
1374   pg_hd = Pg_free_pg(GLOBAL_PAGES_susp_fr);
1375   while (pg_hd) {
1376     aux_ptr = PgHd_free_str(pg_hd);
1377     while (aux_ptr) {
1378       cont++;
1379       aux_ptr = SuspFr_next(aux_ptr);
1380     }
1381     pg_hd = PgHd_next(pg_hd);
1382   }
1383   OPTYAP_ERROR_CHECKING(statistics_suspension_frames, Pg_str_free(GLOBAL_PAGES_susp_fr) != cont);
1384 #endif /* DEBUG_OPTYAP */
1385   fprintf(Yap_stdout, "  Suspension frames:               %10ld bytes (%ld pages and %ld structs in use)\n",
1386           Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame), Pg_pg_alloc(GLOBAL_PAGES_susp_fr), Pg_str_in_use(GLOBAL_PAGES_susp_fr));
1387 #else
1388   fprintf(Yap_stdout, "  Suspension frames:               %10ld bytes (%ld structs in use)\n",
1389           Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame), Pg_str_in_use(GLOBAL_PAGES_susp_fr));
1390 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1391   return Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame);
1392 }
1393 
1394 
1395 #ifdef TABLING_INNER_CUTS
show_statistics_table_subgoal_solution_frames(void)1396 static inline long show_statistics_table_subgoal_solution_frames(void) {
1397 #ifdef SHM_MEMORY_ALLOC_SCHEME
1398 #ifdef DEBUG_OPTYAP
1399   pg_hd_ptr pg_hd;
1400   tg_sol_fr_ptr aux_ptr;
1401   long cont = 0;
1402 
1403   pg_hd = Pg_free_pg(GLOBAL_PAGES_tg_sol_fr);
1404   while (pg_hd) {
1405     aux_ptr = PgHd_free_str(pg_hd);
1406     while (aux_ptr) {
1407       cont++;
1408       aux_ptr = SolFr_next(aux_ptr);
1409     }
1410     pg_hd = PgHd_next(pg_hd);
1411   }
1412   OPTYAP_ERROR_CHECKING(statistics_table_subgoal_solution_frames, Pg_str_free(GLOBAL_PAGES_tg_sol_fr) != cont);
1413 #endif /* DEBUG_OPTYAP */
1414   fprintf(Yap_stdout, "  Table subgoal solution frames:   %10ld bytes (%ld pages and %ld structs in use)\n",
1415           Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame), Pg_pg_alloc(GLOBAL_PAGES_tg_sol_fr), Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr));
1416 #else
1417   fprintf(Yap_stdout, "  Table subgoal solution frames:   %10ld bytes (%ld structs in use)\n",
1418           Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame), Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr));
1419 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1420   return Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame);
1421 }
1422 
1423 
show_statistics_table_subgoal_answer_frames(void)1424 static inline long show_statistics_table_subgoal_answer_frames(void) {
1425 #ifdef SHM_MEMORY_ALLOC_SCHEME
1426 #ifdef DEBUG_OPTYAP
1427   pg_hd_ptr pg_hd;
1428   tg_ans_fr_ptr aux_ptr;
1429   long cont = 0;
1430 
1431   pg_hd = Pg_free_pg(GLOBAL_PAGES_tg_ans_fr);
1432   while (pg_hd) {
1433     aux_ptr = PgHd_free_str(pg_hd);
1434     while (aux_ptr) {
1435       cont++;
1436       aux_ptr = AnsFr_next(aux_ptr);
1437     }
1438     pg_hd = PgHd_next(pg_hd);
1439   }
1440   OPTYAP_ERROR_CHECKING(statistics_table_subgoal_answer_frames, Pg_str_free(GLOBAL_PAGES_tg_ans_fr) != cont);
1441 #endif /* DEBUG_OPTYAP */
1442   fprintf(Yap_stdout, "  Table subgoal answer frames:     %10ld bytes (%ld pages and %ld structs in use)\n",
1443           Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame), Pg_pg_alloc(GLOBAL_PAGES_tg_ans_fr), Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr));
1444 #else
1445   fprintf(Yap_stdout, "  Table subgoal answer frames:     %10ld bytes (%ld structs in use)\n",
1446           Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame), Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr));
1447 #endif /* SHM_MEMORY_ALLOC_SCHEME */
1448   return Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame);
1449 }
1450 #endif /* TABLING_INNER_CUTS */
1451 #endif /* YAPOR && TABLING */
1452 #endif /* YAPOR || TABLING */
1453