diff --git a/C/absmi.c b/C/absmi.c index dd4bc4c0a..12e483778 100644 --- a/C/absmi.c +++ b/C/absmi.c @@ -1878,7 +1878,12 @@ Yap_absmi(int inp) case _table_retry: case _table_trust: case _table_completion: - low_level_trace(retry_table_generator, GEN_CP(B)->cp_pred_entry, (CELL *)(GEN_CP(B) + 1)); +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(B)) + low_level_trace(retry_table_generator, DET_GEN_CP(B)->cp_pred_entry, NULL); + else +#endif /* DETERMINISTIC_TABLING */ + low_level_trace(retry_table_generator, GEN_CP(B)->cp_pred_entry, (CELL *)(GEN_CP(B) + 1)); break; case _table_answer_resolution: low_level_trace(retry_table_consumer, CONS_CP(B)->cp_pred_entry, NULL); diff --git a/C/cdmgr.c b/C/cdmgr.c index f20f144bb..42b095e66 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -5420,8 +5420,16 @@ p_choicepoint_info(void) case _table_trust: case _table_completion: #ifdef LOW_LEVEL_TRACER - pe = GEN_CP(cptr)->cp_pred_entry; - t = BuildActivePred(pe, (CELL *)(GEN_CP(B) + 1)); +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(cptr)) { + pe = DET_GEN_CP(cptr)->cp_pred_entry; + t = MkVarTerm(); + } else +#endif /* DETERMINISTIC_TABLING */ + { + pe = GEN_CP(cptr)->cp_pred_entry; + t = BuildActivePred(pe, (CELL *)(GEN_CP(B) + 1)); + } #else pe = UndefCode; t = MkVarTerm(); diff --git a/C/gprof.c b/C/gprof.c index 44819276b..bcf811821 100644 --- a/C/gprof.c +++ b/C/gprof.c @@ -52,6 +52,7 @@ static char SccsId[] = "%W% %G%"; #endif #include "absmi.h" +#include #if HAVE_STRING_H #include diff --git a/C/heapgc.c b/C/heapgc.c index b8b8818ea..a3107873f 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -361,7 +361,7 @@ gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp) { gc_ma_hash_table[i].loc = trp; gc_ma_hash_table[i].more = gc_ma_h_list; gc_ma_h_list = gc_ma_hash_table+i; -#endif +#endif /* TABLING */ gc_ma_hash_table[i].next = NULL; return NULL; } @@ -375,7 +375,7 @@ gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp) { has the correct new value */ TrailVal(nptr->loc+1) = TrailVal(trp+1); -#endif +#endif /* TABLING */ return nptr; } nptr = nptr->next; @@ -386,7 +386,7 @@ gc_lookup_ma_var(CELL *addr, tr_fr_ptr trp) { #if TABLING nptr->loc = trp; nptr->more = gc_ma_h_list; -#endif +#endif /* TABLING */ nptr->next = NULL; gc_ma_h_list = nptr; return NULL; @@ -1748,7 +1748,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B #else trail_base++; mark_external_reference(&(TrailTerm(trail_base))); -#endif +#endif /* TABLING */ trail_base ++; if (HEAP_PTR(trail_cell)) { /* fool the gc into thinking this is a variable */ @@ -1771,7 +1771,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B #ifdef FROZEN_STACKS RESET_VARIABLE(&TrailVal(trail_base)); #endif -#endif /* TABLING */ +#endif /* !TABLING */ trail_base++; RESET_VARIABLE(&TrailTerm(trail_base)); #ifdef FROZEN_STACKS @@ -1794,7 +1794,7 @@ mark_trail(tr_fr_ptr trail_ptr, tr_fr_ptr trail_base, CELL *gc_H, choiceptr gc_B gl = gl->more; } } -#endif +#endif /* TABLING */ #ifdef EASY_SHUNTING sTR = (tr_fr_ptr)old_cont_top0; while (begsTR != NULL) { @@ -1877,7 +1877,7 @@ youngest_cp(choiceptr gc_B, dep_fr_ptr *depfrp) } return min; } -#endif +#endif /* TABLING */ static void @@ -1899,14 +1899,17 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) #ifdef TABLING gc_B = youngest_cp(gc_B, &depfr); -#endif +#endif /* TABLING */ while (gc_B != NULL) { op_numbers opnum; register OPCODE op; yamop *rtp = gc_B->cp_ap; mark_db_fixed((CELL *)rtp); - mark_db_fixed((CELL *)(gc_B->cp_cp)); +#ifdef DETERMINISTIC_TABLING + if (!IS_DET_GEN_CP(gc_B)) +#endif /* DETERMINISTIC_TABLING */ + mark_db_fixed((CELL *)(gc_B->cp_cp)); #ifdef EASY_SHUNTING current_B = gc_B; prev_HB = HB; @@ -1933,7 +1936,7 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) { aux_sg_fr = SgFr_next(aux_sg_fr); } -#endif +#endif /* TABLING */ if (very_verbose) { PredEntry *pe = Yap_PredForChoicePt(gc_B); #if defined(ANALYST) || defined(DEBUG) @@ -1975,9 +1978,12 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) EnvSizeInCells, NULL); else if (opnum != _trust_fail) - mark_environments((CELL_PTR) gc_B->cp_env, - EnvSize((yamop *) (gc_B->cp_cp)), - EnvBMap((yamop *) (gc_B->cp_cp))); +#ifdef DETERMINISTIC_TABLING + if (!IS_DET_GEN_CP(gc_B)) +#endif /* DETERMINISTIC_TABLING */ + mark_environments((CELL_PTR) gc_B->cp_env, + EnvSize((yamop *) (gc_B->cp_cp)), + EnvBMap((yamop *) (gc_B->cp_cp))); /* extended choice point */ restart_cp: switch (opnum) { @@ -2061,11 +2067,18 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) case _table_completion: { CELL *vars_ptr, vars; - vars_ptr = (CELL *)(GEN_CP(gc_B) + 1); - nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr); - while (nargs--) { - mark_external_reference(vars_ptr); - vars_ptr++; +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(gc_B)) + vars_ptr = (CELL *)(DET_GEN_CP(gc_B) + 1); + else +#endif /* DETERMINISTIC_TABLING */ + { + vars_ptr = (CELL *)(GEN_CP(gc_B) + 1); + nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr); + while (nargs--) { + mark_external_reference(vars_ptr); + vars_ptr++; + } } vars = *vars_ptr++; while (vars--) { @@ -2138,8 +2151,8 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) vars_ptr -= 2; if (heap_arity) { while (heap_arity--) { - if (*vars_ptr == 0) - break; /* term extension mark: float/longint */ + if (*vars_ptr == 0) /* float/longint extension mark */ + break; mark_external_reference(vars_ptr); vars_ptr--; } @@ -2270,7 +2283,7 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose) gc_B = youngest_cp(gc_B->cp_b, &depfr); #else gc_B = gc_B->cp_b; -#endif +#endif /* TABLING */ } } @@ -2820,7 +2833,7 @@ sweep_choicepoints(choiceptr gc_B) #ifdef TABLING gc_B = youngest_cp(gc_B, &depfr); -#endif +#endif /* TABLING */ while (gc_B != NULL) { yamop *rtp = gc_B->cp_ap; register OPCODE op; @@ -2844,7 +2857,7 @@ sweep_choicepoints(choiceptr gc_B) if (aux_sg_fr && gc_B == SgFr_gen_cp(aux_sg_fr)) { aux_sg_fr = SgFr_next(aux_sg_fr); } -#endif +#endif /* TABLING */ restart_cp: /* @@ -2941,18 +2954,25 @@ sweep_choicepoints(choiceptr gc_B) { int nargs; CELL *vars_ptr, vars; - sweep_environments(gc_B->cp_env, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp)); - vars_ptr = (CELL *)(GEN_CP(gc_B) + 1); - nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr); - while(nargs--) { - CELL cp_cell = *vars_ptr; - if (MARKED_PTR(vars_ptr)) { - UNMARK(vars_ptr); - if (HEAP_PTR(cp_cell)) { - into_relocation_chain(vars_ptr, GET_NEXT(cp_cell)); +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(gc_B)) + vars_ptr = (CELL *)(DET_GEN_CP(gc_B) + 1); + else +#endif /* DETERMINISTIC_TABLING */ + { + sweep_environments(gc_B->cp_env, EnvSize(gc_B->cp_cp), EnvBMap(gc_B->cp_cp)); + vars_ptr = (CELL *)(GEN_CP(gc_B) + 1); + nargs = SgFr_arity(GEN_CP(gc_B)->cp_sg_fr); + while(nargs--) { + CELL cp_cell = *vars_ptr; + if (MARKED_PTR(vars_ptr)) { + UNMARK(vars_ptr); + if (HEAP_PTR(cp_cell)) { + into_relocation_chain(vars_ptr, GET_NEXT(cp_cell)); + } } + vars_ptr++; } - vars_ptr++; } vars = *vars_ptr++; while (vars--) { @@ -3050,8 +3070,8 @@ sweep_choicepoints(choiceptr gc_B) if (heap_arity) { while (heap_arity--) { CELL cp_cell = *vars_ptr; - if (*vars_ptr == 0) - break; /* term extension mark: float/longint */ + if (*vars_ptr == 0) /* float/longint extension mark */ + break; if (MARKED_PTR(vars_ptr)) { UNMARK(vars_ptr); if (HEAP_PTR(cp_cell)) { @@ -3113,7 +3133,7 @@ sweep_choicepoints(choiceptr gc_B) gc_B = youngest_cp(gc_B->cp_b, &depfr); #else gc_B = gc_B->cp_b; -#endif +#endif /* TABLING */ } } @@ -3146,14 +3166,14 @@ static inline choiceptr update_B_H( choiceptr gc_B, CELL *current, CELL *dest, CELL *odest #ifdef TABLING , dep_fr_ptr *depfrp -#endif +#endif /* TABLING */ ) { /* also make the value of H in a choicepoint coherent with the new global */ #ifdef TABLING dep_fr_ptr depfr = *depfrp; -#endif +#endif /* TABLING */ while (gc_B && current <= gc_B->cp_h) { if (gc_B->cp_h == current) { @@ -3214,14 +3234,14 @@ compact_heap(void) gc_B = DepFr_cons_cp(depfr); depfr = DepFr_next(depfr); } -#endif +#endif /* TABLING */ next_hb = set_next_hb(gc_B); dest = H0 + total_marked - 1; gc_B = update_B_H(gc_B, H, dest+1, dest+2 #ifdef TABLING , &depfr -#endif +#endif /* TABLING */ ); for (current = H - 1; current >= start_from; current--) { if (MARKED_PTR(current)) { @@ -3236,7 +3256,7 @@ compact_heap(void) gc_B = update_B_H(gc_B, current, dest, dest+1 #ifdef TABLING , &depfr -#endif +#endif /* TABLING */ ); next_hb = set_next_hb(gc_B); } @@ -3397,13 +3417,13 @@ icompact_heap(void) gc_B = DepFr_cons_cp(depfr); depfr = DepFr_next(depfr); } -#endif +#endif /* TABLING */ next_hb = set_next_hb(gc_B); dest = (CELL_PTR) H0 + total_marked - 1; gc_B = update_B_H(gc_B, H, dest+1, dest+2 #ifdef TABLING , &depfr -#endif +#endif /* TABLING */ ); for (iptr = iptop - 1; iptr >= ibase; iptr--) { CELL ccell; @@ -3415,7 +3435,7 @@ icompact_heap(void) gc_B = update_B_H(gc_B, current, dest, dest+1 #ifdef TABLING , &depfr -#endif +#endif /* TABLING */ ); next_hb = set_next_hb(gc_B); } diff --git a/C/iopreds.c b/C/iopreds.c old mode 100644 new mode 100755 index b501ff9b1..23f084177 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -2311,7 +2311,7 @@ p_open (void) return FALSE; encoding = IntegerOfTerm(tenc); #ifdef _WIN32 - if (st->status & Binary_Stream_f) { + if (opts & 2) { strncat(io_mode, "b", 8); } else { strncat(io_mode, "t", 8); @@ -4525,7 +4525,7 @@ p_put (void) return (FALSE); if (Stream[sno].status & Binary_Stream_f) { UNLOCK(Stream[sno].streamlock); - Yap_Error(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "get0/2"); + Yap_Error(PERMISSION_ERROR_OUTPUT_BINARY_STREAM, ARG1, "put/2"); return(FALSE); } Stream[sno].stream_wputc (sno, (int) IntegerOfTerm (Deref (ARG2))); diff --git a/H/amidefs.h b/H/amidefs.h index ac92af3bf..0b1d88122 100644 --- a/H/amidefs.h +++ b/H/amidefs.h @@ -816,6 +816,7 @@ struct deterministic_choicept { int cp_lub; /* local untried branches */ struct or_frame *cp_or_fr; /* or-frame pointer */ #endif /* YAPOR */ + CELL *cp_h; /* necessary, otherwise we get in trouble */ }; typedef struct choicept { diff --git a/OPTYap/opt.config.h b/OPTYap/opt.config.h index 7361cbf6d..79aad1ebf 100644 --- a/OPTYap/opt.config.h +++ b/OPTYap/opt.config.h @@ -31,14 +31,29 @@ /* ----------------------- ** ** default sizes ** ** ----------------------- */ -#define MAX_TABLE_VARS 100 +#define MAX_TABLE_VARS 1000 /* ------------------------------------------ ** ** trail freeze scheme (define one) ** ** ------------------------------------------ */ -#define BFZ_TRAIL_SCHEME 1 +#define BFZ_TRAIL_SCHEME 1 /* #define BBREG_TRAIL_SCHEME 1 */ +/* ----------------------------------------------- ** +** support early completion ? (optional) ** +** ----------------------------------------------- */ +#define TABLING_EARLY_COMPLETION 1 + +/* ------------------------------------------------ ** +** support trie compact pairs? (optional) ** +** ------------------------------------------------ */ +#define TRIE_COMPACT_PAIRS 1 + +/* --------------------------------------------------- ** +** support deterministic tabling? (optional) ** +** --------------------------------------------------- */ +/* #define DETERMINISTIC_TABLING 1 */ + /* ------------------------------------------------ ** ** limit the table space size? (optional) ** ** ------------------------------------------------ */ @@ -49,16 +64,6 @@ ** ------------------------------------------------ */ /* #define INCOMPLETE_TABLING 1 */ -/* ------------------------------------------------ ** -** support trie compact pairs? (optional) ** -** ------------------------------------------------ */ -/* #define TRIE_COMPACT_PAIRS 1 */ - -/* --------------------------------------------------- ** -** support deterministic tabling? (optional) ** -** --------------------------------------------------- */ -/* #define DETERMINISTIC_TABLING 1 */ - /* ---------------------------------------- -- ** ** enable error checking? (optional) ** ** ------------------------------------------- */ @@ -220,10 +225,11 @@ #ifndef TABLING #undef BFZ_TRAIL_SCHEME #undef BBREG_TRAIL_SCHEME +#undef TRIE_COMPACT_PAIRS +#undef TABLING_EARLY_COMPLETION +#undef DETERMINISTIC_TABLING #undef LIMIT_TABLING #undef INCOMPLETE_TABLING -#undef TRIE_COMPACT_PAIRS -#undef DETERMINISTIC_TABLING #undef TABLING_ERRORS #endif /* !TABLING */ diff --git a/OPTYap/opt.macros.h b/OPTYap/opt.macros.h index 254178178..dd1c1bf19 100644 --- a/OPTYap/opt.macros.h +++ b/OPTYap/opt.macros.h @@ -52,335 +52,335 @@ extern int Yap_page_size; #define UPDATE_STATS(STAT, VALUE) STAT += VALUE -#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */ -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \ +#ifdef MALLOC_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------------------- */ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + if ((STR = (STR_TYPE *)malloc(sizeof(STR_TYPE))) == NULL) \ Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)") -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ free(STR) -#elif YAP_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ - if (ptr) { \ - *ptr = 'y'; \ - ptr += sizeof(CELL); \ - STR = (STR_TYPE *)ptr; \ - } else { \ - ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \ - if (ptr) { \ - *ptr = 'm'; \ - ptr += sizeof(CELL); \ - STR = (STR_TYPE *)ptr; \ - } else { \ - Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \ - STR = NULL; \ - } \ - } \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ +#elif YAP_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { char *ptr = Yap_AllocCodeSpace(sizeof(STR_TYPE) + sizeof(CELL)); \ + if (ptr) { \ + *ptr = 'y'; \ + ptr += sizeof(CELL); \ + STR = (STR_TYPE *)ptr; \ + } else { \ + ptr = (char *)malloc(sizeof(STR_TYPE) + sizeof(CELL)); \ + if (ptr) { \ + *ptr = 'm'; \ + ptr += sizeof(CELL); \ + STR = (STR_TYPE *)ptr; \ + } else { \ + Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_STRUCT)"); \ + STR = NULL; \ + } \ + } \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ } -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { char *ptr = (char *)(STR) - sizeof(CELL); \ - if (ptr[0] == 'y') { \ - Yap_FreeCodeSpace(ptr); \ - } else \ - free(ptr); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { char *ptr = (char *)(STR) - sizeof(CELL); \ + if (ptr[0] == 'y') { \ + Yap_FreeCodeSpace(ptr); \ + } else \ + free(ptr); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ } -#elif SHM_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ +#elif SHM_MEMORY_ALLOC_SCHEME /* -------------------------------------------------------------------- */ #ifdef LIMIT_TABLING -#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ - { int i; \ - STR_TYPE *aux_str; \ - PgHd_str_in_use(PG_HD) = 0; \ - PgHd_previous(PG_HD) = NULL; \ - aux_str = (STR_TYPE *) (PG_HD + 1); \ - PgHd_free_str(PG_HD) = (void *) aux_str; \ - for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \ - STRUCT_NEXT(aux_str) = aux_str + 1; \ - aux_str++; \ - } \ - STRUCT_NEXT(aux_str) = NULL; \ - LOCK(Pg_lock(STR_PAGES)); \ - if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \ - Pg_free_pg(STR_PAGES) = PG_HD; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ +#define INIT_PAGE(PG_HD, STR_PAGES, STR_TYPE) \ + { int i; \ + STR_TYPE *aux_str; \ + PgHd_str_in_use(PG_HD) = 0; \ + PgHd_previous(PG_HD) = NULL; \ + aux_str = (STR_TYPE *) (PG_HD + 1); \ + PgHd_free_str(PG_HD) = (void *) aux_str; \ + for (i = 1; i < Pg_str_per_pg(STR_PAGES); i++) { \ + STRUCT_NEXT(aux_str) = aux_str + 1; \ + aux_str++; \ + } \ + STRUCT_NEXT(aux_str) = NULL; \ + LOCK(Pg_lock(STR_PAGES)); \ + if ((PgHd_next(PG_HD) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(PG_HD)) = PG_HD; \ + Pg_free_pg(STR_PAGES) = PG_HD; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ } -#define ALLOC_PAGE(PG_HD) \ - { int i, shmid; \ - pg_hd_ptr aux_pg_hd; \ - if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ - if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ - if (shmctl(shmid, IPC_RMID, 0) != 0) \ - Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ - aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \ - Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \ - for (i = 2; i < SHMMAX / Yap_page_size; i++) { \ - PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \ - aux_pg_hd = PgHd_next(aux_pg_hd); \ - } \ - PgHd_next(aux_pg_hd) = NULL; \ - UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ +#define ALLOC_PAGE(PG_HD) \ + { int i, shmid; \ + pg_hd_ptr aux_pg_hd; \ + if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ + if ((PG_HD = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ + if (shmctl(shmid, IPC_RMID, 0) != 0) \ + Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ + aux_pg_hd = (pg_hd_ptr)(((void *)PG_HD) + Yap_page_size); \ + Pg_free_pg(GLOBAL_PAGES_void) = aux_pg_hd; \ + for (i = 2; i < SHMMAX / Yap_page_size; i++) { \ + PgHd_next(aux_pg_hd) = (pg_hd_ptr)(((void *)aux_pg_hd) + Yap_page_size); \ + aux_pg_hd = PgHd_next(aux_pg_hd); \ + } \ + PgHd_next(aux_pg_hd) = NULL; \ + UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ } -#define RECOVER_UNUSED_SPACE(STR_PAGES) \ - { sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \ - do { \ - if (sg_fr) \ - sg_fr = SgFr_next(sg_fr); \ - else \ - sg_fr = GLOBAL_first_sg_fr; \ - if (sg_fr == NULL) \ - Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \ - /* see function 'InteractSIGINT' in file 'sysbits.c' */ \ - /* Yap_Error(PURE_ABORT, TermNil, ""); */ \ - /* restore_absmi_regs(&Yap_standard_regs); */ \ - /* siglongjmp (Yap_RestartEnv, 1); */ \ - if (SgFr_first_answer(sg_fr) && \ - SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \ - SgFr_state(sg_fr) = ready; \ - free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \ - SgFr_hash_chain(sg_fr) = NULL; \ - SgFr_first_answer(sg_fr) = NULL; \ - SgFr_last_answer(sg_fr) = NULL; \ - free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr))); \ - TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ - } \ - } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ - GLOBAL_check_sg_fr = sg_fr; \ +#define RECOVER_UNUSED_SPACE(STR_PAGES) \ + { sg_fr_ptr sg_fr = GLOBAL_check_sg_fr; \ + do { \ + if (sg_fr) \ + sg_fr = SgFr_next(sg_fr); \ + else \ + sg_fr = GLOBAL_first_sg_fr; \ + if (sg_fr == NULL) \ + Yap_Error(FATAL_ERROR, TermNil, "no space left (RECOVER_UNUSED_SPACE)"); \ + /* see function 'InteractSIGINT' in file 'sysbits.c' */ \ + /* Yap_Error(PURE_ABORT, TermNil, ""); */ \ + /* restore_absmi_regs(&Yap_standard_regs); */ \ + /* siglongjmp (Yap_RestartEnv, 1); */ \ + if (SgFr_first_answer(sg_fr) && \ + SgFr_first_answer(sg_fr) != SgFr_answer_trie(sg_fr)) { \ + SgFr_state(sg_fr) = ready; \ + free_answer_hash_chain(SgFr_hash_chain(sg_fr)); \ + SgFr_hash_chain(sg_fr) = NULL; \ + SgFr_first_answer(sg_fr) = NULL; \ + SgFr_last_answer(sg_fr) = NULL; \ + free_answer_trie_branch(TrNode_child(SgFr_answer_trie(sg_fr)), TRAVERSE_POSITION_FIRST); \ + TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; \ + } \ + } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ + GLOBAL_check_sg_fr = sg_fr; \ } -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - while (pg_hd == NULL) { \ - UNLOCK(Pg_lock(STR_PAGES)); \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void)) { \ - pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ - ALLOC_PAGE(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else { \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - RECOVER_UNUSED_SPACE(STR_PAGES); \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - } \ - } \ - PgHd_str_in_use(pg_hd)++; \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + while (pg_hd == NULL) { \ + UNLOCK(Pg_lock(STR_PAGES)); \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void)) { \ + pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ + ALLOC_PAGE(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else { \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + RECOVER_UNUSED_SPACE(STR_PAGES); \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + } \ + } \ + PgHd_str_in_use(pg_hd)++; \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ } -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - if ((STR = LOCAL_next_free_ans_node) == NULL) { \ - pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - while (pg_hd == NULL) { \ - UNLOCK(Pg_lock(STR_PAGES)); \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void)) { \ - pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ - ALLOC_PAGE(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ - } else { \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ - RECOVER_UNUSED_SPACE(STR_PAGES); \ - LOCK(Pg_lock(STR_PAGES)); \ - pg_hd = Pg_free_pg(STR_PAGES); \ - } \ - } \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - PgHd_free_str(pg_hd) = NULL; \ - Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + if ((STR = LOCAL_next_free_ans_node) == NULL) { \ + pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + while (pg_hd == NULL) { \ + UNLOCK(Pg_lock(STR_PAGES)); \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void)) { \ + pg_hd = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else if (GLOBAL_MAX_PAGES != Pg_pg_alloc(GLOBAL_PAGES_void)) { \ + ALLOC_PAGE(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + INIT_PAGE(pg_hd, STR_PAGES, STR_TYPE); \ + } else { \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)); \ + RECOVER_UNUSED_SPACE(STR_PAGES); \ + LOCK(Pg_lock(STR_PAGES)); \ + pg_hd = Pg_free_pg(STR_PAGES); \ + } \ + } \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + PgHd_free_str(pg_hd) = NULL; \ + Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ LOCAL_next_free_ans_node = STRUCT_NEXT(STR) #else -#define ALLOC_PAGE(PG_HD) \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ - int i, shmid; \ - pg_hd_ptr pg_hd, aux_pg_hd; \ - if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ - if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ - Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ - if (shmctl(shmid, IPC_RMID, 0) != 0) \ - Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ - Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \ - for (i = 1; i < SHMMAX / Yap_page_size; i++) { \ - aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \ - PgHd_next(pg_hd) = aux_pg_hd; \ - pg_hd = aux_pg_hd; \ - } \ - PgHd_next(pg_hd) = NULL; \ - UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ - } \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ +#define ALLOC_PAGE(PG_HD) \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ + int i, shmid; \ + pg_hd_ptr pg_hd, aux_pg_hd; \ + if ((shmid = shmget(IPC_PRIVATE, SHMMAX, SHM_R|SHM_W)) == -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmget error (ALLOC_PAGE)"); \ + if ((pg_hd = (pg_hd_ptr) shmat(shmid, NULL, 0)) == (void *) -1) \ + Yap_Error(FATAL_ERROR, TermNil, "shmat error (ALLOC_PAGE)"); \ + if (shmctl(shmid, IPC_RMID, 0) != 0) \ + Yap_Error(FATAL_ERROR, TermNil, "shmctl error (ALLOC_PAGE)"); \ + Pg_free_pg(GLOBAL_PAGES_void) = pg_hd; \ + for (i = 1; i < SHMMAX / Yap_page_size; i++) { \ + aux_pg_hd = (pg_hd_ptr)(((void *)pg_hd) + Yap_page_size); \ + PgHd_next(pg_hd) = aux_pg_hd; \ + pg_hd = aux_pg_hd; \ + } \ + PgHd_next(pg_hd) = NULL; \ + UPDATE_STATS(Pg_pg_alloc(GLOBAL_PAGES_void), SHMMAX / Yap_page_size); \ + } \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ + PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)) -#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - if (Pg_free_pg(STR_PAGES)) { \ - pg_hd = Pg_free_pg(STR_PAGES); \ - PgHd_str_in_use(pg_hd)++; \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } else { \ - int i; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - ALLOC_PAGE(pg_hd); \ - PgHd_str_in_use(pg_hd) = 1; \ - PgHd_previous(pg_hd) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - PgHd_free_str(pg_hd) = (void *) ++STR; \ - for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \ - STRUCT_NEXT(STR) = STR + 1; \ - STR++; \ - } \ - STRUCT_NEXT(STR) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - LOCK(Pg_lock(STR_PAGES)); \ - if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ - Pg_free_pg(STR_PAGES) = pg_hd; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + if (Pg_free_pg(STR_PAGES)) { \ + pg_hd = Pg_free_pg(STR_PAGES); \ + PgHd_str_in_use(pg_hd)++; \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + if ((PgHd_free_str(pg_hd) = (void *) STRUCT_NEXT(STR)) == NULL) \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } else { \ + int i; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + ALLOC_PAGE(pg_hd); \ + PgHd_str_in_use(pg_hd) = 1; \ + PgHd_previous(pg_hd) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + PgHd_free_str(pg_hd) = (void *) ++STR; \ + for (i = Pg_str_per_pg(STR_PAGES); i != 2; i--) { \ + STRUCT_NEXT(STR) = STR + 1; \ + STR++; \ + } \ + STRUCT_NEXT(STR) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + LOCK(Pg_lock(STR_PAGES)); \ + if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ + Pg_free_pg(STR_PAGES) = pg_hd; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ } -#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - if ((STR = LOCAL_next_free_ans_node) == NULL) { \ - pg_hd_ptr pg_hd; \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ - if (Pg_free_pg(STR_PAGES)) { \ - pg_hd = Pg_free_pg(STR_PAGES); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ - PgHd_free_str(pg_hd) = NULL; \ - Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } else { \ - int i; \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ - UNLOCK(Pg_lock(STR_PAGES)); \ - ALLOC_PAGE(pg_hd); \ - PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ - PgHd_free_str(pg_hd) = NULL; \ - PgHd_previous(pg_hd) = NULL; \ - PgHd_next(pg_hd) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \ - STRUCT_NEXT(STR) = STR + 1; \ - STR++; \ - } \ - STRUCT_NEXT(STR) = NULL; \ - STR = (STR_TYPE *) (pg_hd + 1); \ - } \ - } \ +#define ALLOC_NEXT_FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + if ((STR = LOCAL_next_free_ans_node) == NULL) { \ + pg_hd_ptr pg_hd; \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), Pg_str_per_pg(STR_PAGES)); \ + if (Pg_free_pg(STR_PAGES)) { \ + pg_hd = Pg_free_pg(STR_PAGES); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -PgHd_str_in_use(pg_hd)); \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + STR = (STR_TYPE *) PgHd_free_str(pg_hd); \ + PgHd_free_str(pg_hd) = NULL; \ + Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } else { \ + int i; \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), 1); \ + UNLOCK(Pg_lock(STR_PAGES)); \ + ALLOC_PAGE(pg_hd); \ + PgHd_str_in_use(pg_hd) = Pg_str_per_pg(STR_PAGES); \ + PgHd_free_str(pg_hd) = NULL; \ + PgHd_previous(pg_hd) = NULL; \ + PgHd_next(pg_hd) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + for (i = Pg_str_per_pg(STR_PAGES); i != 1; i--) { \ + STRUCT_NEXT(STR) = STR + 1; \ + STR++; \ + } \ + STRUCT_NEXT(STR) = NULL; \ + STR = (STR_TYPE *) (pg_hd + 1); \ + } \ + } \ LOCAL_next_free_ans_node = STRUCT_NEXT(STR) #endif /* LIMIT_TABLING */ -#define FREE_PAGE(PG_HD) \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \ - PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \ +#define FREE_PAGE(PG_HD) \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), -1); \ + PgHd_next(PG_HD) = Pg_free_pg(GLOBAL_PAGES_void); \ + Pg_free_pg(GLOBAL_PAGES_void) = PG_HD; \ UNLOCK(Pg_lock(GLOBAL_PAGES_void)) -#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ - { pg_hd_ptr pg_hd; \ - pg_hd = PAGE_HEADER(STR); \ - LOCK(Pg_lock(STR_PAGES)); \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ - if (--PgHd_str_in_use(pg_hd) == 0) { \ - UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \ - if (PgHd_previous(pg_hd)) { \ - if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \ - } else { \ - if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = NULL; \ - } \ - UNLOCK(Pg_lock(STR_PAGES)); \ - FREE_PAGE(pg_hd); \ - } else { \ - if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \ - PgHd_previous(pg_hd) = NULL; \ - if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ - PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ - Pg_free_pg(STR_PAGES) = pg_hd; \ - } \ - PgHd_free_str(pg_hd) = (void *) STR; \ - UNLOCK(Pg_lock(STR_PAGES)); \ - } \ +#define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ + { pg_hd_ptr pg_hd; \ + pg_hd = PAGE_HEADER(STR); \ + LOCK(Pg_lock(STR_PAGES)); \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), -1); \ + if (--PgHd_str_in_use(pg_hd) == 0) { \ + UPDATE_STATS(Pg_pg_alloc(STR_PAGES), -1); \ + if (PgHd_previous(pg_hd)) { \ + if ((PgHd_next(PgHd_previous(pg_hd)) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = PgHd_previous(pg_hd); \ + } else { \ + if ((Pg_free_pg(STR_PAGES) = PgHd_next(pg_hd)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = NULL; \ + } \ + UNLOCK(Pg_lock(STR_PAGES)); \ + FREE_PAGE(pg_hd); \ + } else { \ + if ((STRUCT_NEXT(STR) = (STR_TYPE *) PgHd_free_str(pg_hd)) == NULL) { \ + PgHd_previous(pg_hd) = NULL; \ + if ((PgHd_next(pg_hd) = Pg_free_pg(STR_PAGES)) != NULL) \ + PgHd_previous(PgHd_next(pg_hd)) = pg_hd; \ + Pg_free_pg(STR_PAGES) = pg_hd; \ + } \ + PgHd_free_str(pg_hd) = (void *) STR; \ + UNLOCK(Pg_lock(STR_PAGES)); \ + } \ } -#endif /* --------------------------- MEMORY_ALLOC_SCHEME ---------------------------- */ +#endif /* --------------------------- MEMORY_ALLOC_SCHEME -------------------------------------------- */ #ifdef YAPOR -#define ALLOC_BLOCK(BLOCK, SIZE) \ - if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \ +#define ALLOC_BLOCK(BLOCK, SIZE) \ + if ((BLOCK = (void *) Yap_AllocCodeSpace(SIZE)) == NULL) \ Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace error (ALLOC_BLOCK)") -#define FREE_BLOCK(BLOCK) \ +#define FREE_BLOCK(BLOCK) \ Yap_FreeCodeSpace((char *) (BLOCK)) #else /* TABLING */ -#define ALLOC_BLOCK(BLOCK, SIZE) \ - if ((BLOCK = malloc(SIZE)) == NULL) \ +#define ALLOC_BLOCK(BLOCK, SIZE) \ + if ((BLOCK = malloc(SIZE)) == NULL) \ Yap_Error(FATAL_ERROR, TermNil, "malloc error (ALLOC_BLOCK)") -#define FREE_BLOCK(BLOCK) \ +#define FREE_BLOCK(BLOCK) \ free(BLOCK) #endif /* YAPOR - TABLING */ -#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \ - { int i; void **ptr; \ - ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \ - BUCKET_PTR = (void *) ptr; \ - for (i = NUM_BUCKETS; i != 0; i--) \ - *ptr++ = NULL; \ +#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \ + { int i; void **ptr; \ + ALLOC_BLOCK(ptr, NUM_BUCKETS * sizeof(void *)); \ + BUCKET_PTR = (void *) ptr; \ + for (i = NUM_BUCKETS; i != 0; i--) \ + *ptr++ = NULL; \ } #define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR) diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 3143936fc..2bac304f0 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -684,7 +684,7 @@ Int p_abolish_table(void) { sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); if (sg_node) { TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; - free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); + free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST); } return (TRUE); } @@ -704,7 +704,7 @@ Int p_abolish_all_tables(void) { sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent)); if (sg_node) { TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL; - free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0); + free_subgoal_trie_branch(sg_node, TabEnt_arity(tab_ent), 0, TRAVERSE_POSITION_FIRST); } tab_ent = TabEnt_next(tab_ent); } diff --git a/OPTYap/opt.proto.h b/OPTYap/opt.proto.h index bdbe62aab..a26522a55 100644 --- a/OPTYap/opt.proto.h +++ b/OPTYap/opt.proto.h @@ -67,8 +67,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr); ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr); void load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr); void private_completion(sg_fr_ptr sg_fr); -void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra); -void free_answer_trie_branch(ans_node_ptr node); +void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position); +void free_answer_trie_branch(ans_node_ptr node, int position); void update_answer_trie(sg_fr_ptr sg_fr); void traverse_table(tab_ent_ptr tab_ent, int show_table); void table_stats(void); diff --git a/OPTYap/tab.insts.i b/OPTYap/tab.insts.i index 5c045297b..8ca819423 100644 --- a/OPTYap/tab.insts.i +++ b/OPTYap/tab.insts.i @@ -95,9 +95,10 @@ /* store deterministic generator choice point */ \ HBREG = H; \ store_yaam_reg_cpdepth(gcp); \ - gcp->cp_tr = TR; \ gcp->cp_ap = COMPLETION; \ gcp->cp_b = B; \ + gcp->cp_tr = TR; \ + gcp->cp_h = H; \ DET_GEN_CP(gcp)->cp_sg_fr = SG_FR; \ store_low_level_trace_info(DET_GEN_CP(gcp), TAB_ENT); \ set_cut((CELL *)gcp, B); \ @@ -748,6 +749,7 @@ choiceptr gcp = NORM_CP(DET_GEN_CP(subs_ptr) - 1); sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr; DET_GEN_CP(gcp)->cp_sg_fr = sg_fr; + gcp->cp_h = B->cp_h; #ifdef DEPTH_LIMIT gcp->cp_depth = B->cp_depth; #endif /* DEPTH_LIMIT */ @@ -775,6 +777,7 @@ choiceptr gcp = NORM_CP(DET_GEN_CP(subs_ptr) - 1); sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr; DET_GEN_CP(gcp)->cp_sg_fr = sg_fr; + gcp->cp_h = B->cp_h; #ifdef DEPTH_LIMIT gcp->cp_depth = B->cp_depth; #endif /* DEPTH_LIMIT */ @@ -811,19 +814,12 @@ sg_fr = GEN_CP(gcp)->cp_sg_fr; subs_ptr = (CELL *)(GEN_CP(gcp) + 1) + PREG->u.s.s; } -#ifdef TABLING_ERRORS +#if defined(TABLING_ERRORS) && !defined(DETERMINISTIC_TABLING) { - sg_fr_ptr aux_sg_fr; int i, j, arity_args, arity_subs; CELL *aux_args; CELL *aux_subs; - aux_sg_fr = LOCAL_top_sg_fr; - while (aux_sg_fr && aux_sg_fr != sg_fr) - aux_sg_fr = SgFr_next(aux_sg_fr); - if (aux_sg_fr == NULL) - TABLING_ERROR_MESSAGE("aux_sg_fr == NULL (table_new_answer)"); - arity_args = PREG->u.s.s; arity_subs = *subs_ptr; aux_args = (CELL *)(GEN_CP(gcp) + 1); @@ -838,7 +834,7 @@ TABLING_ERROR_MESSAGE("j == arity_args (table_new_answer)"); } } -#endif /* TABLING_ERRORS */ +#endif /* TABLING_ERRORS && !DETERMINISTIC_TABLING */ #ifdef TABLE_LOCK_AT_ENTRY_LEVEL LOCK(SgFr_lock(sg_fr)); #endif /* TABLE_LOCK_LEVEL */ @@ -1001,19 +997,23 @@ #endif /* TABLING_ERRORS */ UNLOCK(SgFr_lock(sg_fr)); if (IS_BATCHED_GEN_CP(gcp)) { - /* if the number of substitution variables is zero, - an answer is sufficient to perform an early completion */ -#ifdef DETERMINISTIC_TABLING - if (IS_DET_GEN_CP(gcp) && gcp == B) { +#ifdef TABLING_EARLY_COMPLETION + if (gcp == PROTECT_FROZEN_B(B) && (*subs_ptr == 0 || gcp->cp_ap == COMPLETION)) { + /* if the current generator choice point is the topmost choice point and the current */ + /* call is deterministic (i.e., the number of substitution variables is zero or */ + /* there are no more alternatives) then the current answer is deterministic and we */ + /* can perform an early completion and remove the current generator choice point */ private_completion(sg_fr); B = B->cp_b; SET_BB(PROTECT_FROZEN_B(B)); - } else -#endif /* DETERMINISTIC_TABLING */ - if (*subs_ptr == 0 && gcp->cp_ap != NULL) { - gcp->cp_ap = COMPLETION; + } else if (*subs_ptr == 0) { + /* if the number of substitution variables is zero, an answer is sufficient to perform */ + /* an early completion, but the current generator choice point cannot be removed */ mark_as_completed(sg_fr); + if (gcp->cp_ap != NULL) + gcp->cp_ap = COMPLETION; } +#endif /* TABLING_EARLY_COMPLETION */ /* deallocate and procceed */ PREG = (yamop *) YENV[E_CP]; PREFETCH_OP(PREG); @@ -1025,12 +1025,15 @@ #endif /* DEPTH_LIMIT */ GONext(); } else { - /* if the number of substitution variables is zero, - an answer is sufficient to perform an early completion */ - if (*subs_ptr == 0 && gcp->cp_ap != ANSWER_RESOLUTION) { - gcp->cp_ap = COMPLETION; +#ifdef TABLING_EARLY_COMPLETION + if (*subs_ptr == 0) { + /* if the number of substitution variables is zero, an answer is sufficient to perform */ + /* an early completion, but the current generator choice point cannot be removed */ mark_as_completed(sg_fr); + if (gcp->cp_ap != ANSWER_RESOLUTION) + gcp->cp_ap = COMPLETION; } +#endif /* TABLING_EARLY_COMPLETION */ /* fail */ goto fail; } diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index b90ea8bd0..91da4953c 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -57,6 +57,23 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p +/* ----------------- ** +** Defines ** +** ----------------- */ + +#define TRAVERSE_MODE_NORMAL 0 +#define TRAVERSE_MODE_FLOAT 1 +#define TRAVERSE_MODE_FLOAT2 2 +#define TRAVERSE_MODE_FLOAT_END 3 +#define TRAVERSE_MODE_LONG 4 +#define TRAVERSE_MODE_LONG_END 5 +/* do not change order !!! */ +#define TRAVERSE_POSITION_NEXT 0 +#define TRAVERSE_POSITION_FIRST 1 +#define TRAVERSE_POSITION_LAST 2 + + + /* ----------------------- ** ** Tabling Macros ** ** ----------------------- */ @@ -591,8 +608,10 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) { UNLOCK(SgFr_lock(sg_fr)); } else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) { /* yes answer --> complete */ - /* at this point the subgoal should be already completed (early completion) */ - /* SgFr_state(sg_fr) = complete; */ +#ifndef TABLING_EARLY_COMPLETION + /* with early completion, at this point the subgoal should be already completed */ + SgFr_state(sg_fr) = complete; +#endif /* TABLING_EARLY_COMPLETION */ UNLOCK(SgFr_lock(sg_fr)); } else { /* answers --> incomplete/ready */ @@ -609,7 +628,7 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) { node = TrNode_child(SgFr_answer_trie(sg_fr)); TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; UNLOCK(SgFr_lock(sg_fr)); - free_answer_trie_branch(node); + free_answer_trie_branch(node, TRAVERSE_POSITION_FIRST); #endif /* INCOMPLETE_TABLING */ } #ifdef LIMIT_TABLING @@ -919,7 +938,12 @@ void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) { while (valid_solutions) { first_answer = last_answer = NULL; - sg_fr = GEN_CP(TgSolFr_gen_cp(valid_solutions))->cp_sg_fr; +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(TgSolFr_gen_cp(valid_solutions))) + sg_fr = DET_GEN_CP(TgSolFr_gen_cp(valid_solutions))->cp_sg_fr; + else +#endif /* DETERMINISTIC_TABLING */ + sg_fr = GEN_CP(TgSolFr_gen_cp(valid_solutions))->cp_sg_fr; ltt_valid_solutions = valid_solutions; valid_solutions = TgSolFr_next(valid_solutions); do { diff --git a/OPTYap/tab.suspend.c b/OPTYap/tab.suspend.c index 7132e69f3..f36428513 100644 --- a/OPTYap/tab.suspend.c +++ b/OPTYap/tab.suspend.c @@ -46,7 +46,12 @@ void public_completion(void) { sg_fr_ptr top_sg_fr; /* complete subgoals */ - top_sg_fr = SgFr_next(GEN_CP(LOCAL_top_cp)->cp_sg_fr); +#ifdef DETERMINISTIC_TABLING + if (IS_DET_GEN_CP(LOCAL_top_cp)) + top_sg_fr = SgFr_next(DET_GEN_CP(LOCAL_top_cp)->cp_sg_fr); + else +#endif /* DETERMINISTIC_TABLING */ + top_sg_fr = SgFr_next(GEN_CP(LOCAL_top_cp)->cp_sg_fr); do { mark_as_completed(LOCAL_top_sg_fr); LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 4f83695ae..6e9edbecb 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -25,19 +25,6 @@ #include "tab.macros.h" -/* ----------------- ** -** Defines ** -** ----------------- */ - -#define TRAVERSE_NORMAL 0 -#define TRAVERSE_FLOAT 1 -#define TRAVERSE_FLOAT2 2 -#define TRAVERSE_FLOAT_END 3 -#define TRAVERSE_LONG 4 -#define TRAVERSE_LONG_END 5 - - - /* ------------------------------------- ** ** Local functions declaration ** ** ------------------------------------- */ @@ -49,10 +36,10 @@ static int update_answer_trie_branch(ans_node_ptr previous_node, ans_node_ptr no static int update_answer_trie_branch(ans_node_ptr node); #endif /* TABLING_INNER_CUTS */ #else -static void update_answer_trie_branch(ans_node_ptr node); +static void update_answer_trie_branch(ans_node_ptr node, int position); #endif /* YAPOR */ -static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode); -static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode); +static void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position); +static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position); @@ -63,109 +50,112 @@ static void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index STD_PROTO(static inline sg_node_ptr subgoal_trie_node_check_insert, (tab_ent_ptr, sg_node_ptr, Term)); STD_PROTO(static inline ans_node_ptr answer_trie_node_check_insert, (sg_fr_ptr, ans_node_ptr, Term, int)); +#if defined(TABLE_LOCK_AT_WRITE_LEVEL) +#define LOCK_NODE(NODE) LOCK_TABLE(NODE) +#define UNLOCK_NODE(NODE) UNLOCK_TABLE(NODE) +#elif defined(TABLE_LOCK_AT_NODE_LEVEL) +#define LOCK_NODE(NODE) TRIE_LOCK(TrNode_lock(NODE)) +#define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE)) +#else +#define LOCK_NODE(NODE) +#define UNLOCK_NODE(NODE) +#endif /* TABLE_LOCK_LEVEL */ #ifdef TABLE_LOCK_AT_WRITE_LEVEL - static inline sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { - sg_node_ptr chain_node, new_node; + sg_node_ptr child_node; sg_hash_ptr hash; + child_node = TrNode_child(parent_node); - chain_node = TrNode_child(parent_node); - - - if (chain_node == NULL) { + if (child_node == NULL) { #ifdef ALLOC_BEFORE_CHECK - new_subgoal_trie_node(new_node, t, NULL, parent_node, NULL); + new_subgoal_trie_node(child_node, t, NULL, parent_node, NULL); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (TrNode_child(parent_node)) { - chain_node = TrNode_child(parent_node); + sg_node_ptr chain_node = TrNode_child(parent_node); if (IS_SUBGOAL_HASH(chain_node)) { #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); hash = (sg_hash_ptr) chain_node; goto subgoal_hash; } do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } chain_node = TrNode_next(chain_node); } while (chain_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = TrNode_child(parent_node); + TrNode_next(child_node) = TrNode_child(parent_node); #else - new_subgoal_trie_node(new_node, t, NULL, parent_node, TrNode_child(parent_node)); + new_subgoal_trie_node(child_node, t, NULL, parent_node, TrNode_child(parent_node)); } else { - new_subgoal_trie_node(new_node, t, NULL, parent_node, NULL); + new_subgoal_trie_node(child_node, t, NULL, parent_node, NULL); #endif /* ALLOC_BEFORE_CHECK */ } - TrNode_child(parent_node) = new_node; - UNLOCK_TABLE(parent_node); - return new_node; + TrNode_child(parent_node) = child_node; + UNLOCK_NODE(parent_node); + return child_node; } - - if (! IS_SUBGOAL_HASH(chain_node)) { - sg_node_ptr first_node; - int count_nodes; - - first_node = chain_node; - count_nodes = 0; + if (! IS_SUBGOAL_HASH(child_node)) { + sg_node_ptr first_node = child_node; + int count_nodes = 0; do { - if (TrNode_entry(chain_node) == t) { - return chain_node; + if (TrNode_entry(child_node) == t) { + return child_node; } count_nodes++; - chain_node = TrNode_next(chain_node); - } while (chain_node); + child_node = TrNode_next(child_node); + } while (child_node); #ifdef ALLOC_BEFORE_CHECK - new_subgoal_trie_node(new_node, t, NULL, parent_node, first_node); + new_subgoal_trie_node(child_node, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (first_node != TrNode_child(parent_node)) { - chain_node = TrNode_child(parent_node); + sg_node_ptr chain_node = TrNode_child(parent_node); if (IS_SUBGOAL_HASH(chain_node)) { #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); hash = (sg_hash_ptr) chain_node; goto subgoal_hash; } do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = TrNode_child(parent_node); + TrNode_next(child_node) = TrNode_child(parent_node); #else - new_subgoal_trie_node(new_node, t, NULL, parent_node, TrNode_child(parent_node)); + new_subgoal_trie_node(child_node, t, NULL, parent_node, TrNode_child(parent_node)); } else { - new_subgoal_trie_node(new_node, t, NULL, parent_node, first_node); + new_subgoal_trie_node(child_node, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ } if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { /* alloc a new hash */ - sg_node_ptr next_node, *bucket; + sg_node_ptr chain_node, next_node, *bucket; new_subgoal_hash(hash, count_nodes, tab_ent); - chain_node = new_node; + chain_node = child_node; do { bucket = Hash_bucket(hash, HASH_TERM(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); next_node = TrNode_next(chain_node); @@ -175,73 +165,71 @@ sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr pare } while (chain_node); TrNode_child(parent_node) = (sg_node_ptr) hash; } else { - TrNode_child(parent_node) = new_node; + TrNode_child(parent_node) = child_node; } - UNLOCK_TABLE(parent_node); - return new_node; + UNLOCK_NODE(parent_node); + return child_node; } - - hash = (sg_hash_ptr) chain_node; + hash = (sg_hash_ptr) child_node; subgoal_hash: { /* trie nodes with hashing */ sg_node_ptr *bucket, first_node; - int seed, count_nodes; + int seed, count_nodes = 0; seed = Hash_seed(hash); bucket = Hash_bucket(hash, HASH_TERM(t, seed)); - first_node = chain_node = *bucket; - count_nodes = 0; - while (chain_node) { - if (TrNode_entry(chain_node) == t) { - return chain_node; + first_node = child_node = *bucket; + while (child_node) { + if (TrNode_entry(child_node) == t) { + return child_node; } count_nodes++; - chain_node = TrNode_next(chain_node); + child_node = TrNode_next(child_node); } #ifdef ALLOC_BEFORE_CHECK - new_subgoal_trie_node(new_node, t, NULL, parent_node, first_node); + new_subgoal_trie_node(child_node, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (seed != Hash_seed(hash)) { /* the hash has been expanded */ #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); goto subgoal_hash; } if (first_node != *bucket) { - chain_node = *bucket; + sg_node_ptr chain_node = *bucket; do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_SUBGOAL_TRIE_NODE(new_node); + FREE_SUBGOAL_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = *bucket; + TrNode_next(child_node) = *bucket; #else - new_subgoal_trie_node(new_node, t, NULL, parent_node, *bucket); + new_subgoal_trie_node(child_node, t, NULL, parent_node, *bucket); } else { - new_subgoal_trie_node(new_node, t, NULL, parent_node, first_node); + new_subgoal_trie_node(child_node, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ } - *bucket = new_node; + *bucket = child_node; Hash_num_nodes(hash)++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - sg_node_ptr next_node, *first_old_bucket, *old_bucket; + sg_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; first_old_bucket = Hash_buckets(hash); old_bucket = first_old_bucket + Hash_num_buckets(hash); - seed = Hash_num_buckets(hash) * 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), seed); - seed--; + Hash_num_buckets(hash) *= 2; + ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); + seed = Hash_num_buckets(hash) - 1; do { if (*--old_bucket) { chain_node = *old_bucket; @@ -254,18 +242,17 @@ subgoal_hash: } while (chain_node); } } while (old_bucket != first_old_bucket); - Hash_num_buckets(hash) = seed + 1; FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_TABLE(parent_node); - return new_node; + UNLOCK_NODE(parent_node); + return child_node; } } -static inline +static inline ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) { - ans_node_ptr chain_node, new_node; + ans_node_ptr child_node; ans_hash_ptr hash; #ifdef TABLING_ERRORS @@ -273,100 +260,94 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ TABLING_ERROR_MESSAGE("IS_ANSWER_LEAF_NODE(parent_node) (answer_trie_node_check_insert)"); #endif /* TABLING_ERRORS */ + child_node = TrNode_child(parent_node); - chain_node = TrNode_child(parent_node); - - - if (chain_node == NULL) { + if (child_node == NULL) { #ifdef ALLOC_BEFORE_CHECK - new_answer_trie_node(new_node, instr, t, NULL, parent_node, NULL); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, NULL); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (TrNode_child(parent_node)) { - chain_node = TrNode_child(parent_node); + ans_node_ptr chain_node = TrNode_child(parent_node); if (IS_ANSWER_HASH(chain_node)) { #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); hash = (ans_hash_ptr) chain_node; goto answer_hash; } do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } chain_node = TrNode_next(chain_node); } while (chain_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = TrNode_child(parent_node); + TrNode_next(child_node) = TrNode_child(parent_node); #else - new_answer_trie_node(new_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); } else { - new_answer_trie_node(new_node, instr, t, NULL, parent_node, NULL); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, NULL); #endif /* ALLOC_BEFORE_CHECK */ } - TrNode_child(parent_node) = new_node; - UNLOCK_TABLE(parent_node); - return new_node; + TrNode_child(parent_node) = child_node; + UNLOCK_NODE(parent_node); + return child_node; } - - if (! IS_ANSWER_HASH(chain_node)) { - ans_node_ptr first_node; - int count_nodes; - - first_node = chain_node; - count_nodes = 0; + if (! IS_ANSWER_HASH(child_node)) { + ans_node_ptr first_node = child_node; + int count_nodes = 0; do { - if (TrNode_entry(chain_node) == t) { - return chain_node; + if (TrNode_entry(child_node) == t) { + return child_node; } count_nodes++; - chain_node = TrNode_next(chain_node); - } while (chain_node); + child_node = TrNode_next(child_node); + } while (child_node); #ifdef ALLOC_BEFORE_CHECK - new_answer_trie_node(new_node, instr, t, NULL, parent_node, first_node); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (first_node != TrNode_child(parent_node)) { - chain_node = TrNode_child(parent_node); + ans_node_ptr chain_node = TrNode_child(parent_node); if (IS_ANSWER_HASH(chain_node)) { #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); hash = (ans_hash_ptr) chain_node; goto answer_hash; } do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = TrNode_child(parent_node); + TrNode_next(child_node) = TrNode_child(parent_node); #else - new_answer_trie_node(new_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); } else { - new_answer_trie_node(new_node, instr, t, NULL, parent_node, first_node); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ } if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { /* alloc a new hash */ - ans_node_ptr next_node, *bucket; + ans_node_ptr chain_node, next_node, *bucket; new_answer_hash(hash, count_nodes, sg_fr); - chain_node = new_node; + chain_node = child_node; do { bucket = Hash_bucket(hash, HASH_TERM(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); next_node = TrNode_next(chain_node); @@ -376,73 +357,71 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ } while (chain_node); TrNode_child(parent_node) = (ans_node_ptr) hash; } else { - TrNode_child(parent_node) = new_node; + TrNode_child(parent_node) = child_node; } - UNLOCK_TABLE(parent_node); - return new_node; + UNLOCK_NODE(parent_node); + return child_node; } - - hash = (ans_hash_ptr) chain_node; + hash = (ans_hash_ptr) child_node; answer_hash: { /* trie nodes with hashing */ ans_node_ptr *bucket, first_node; - int seed, count_nodes; + int seed, count_nodes = 0; seed = Hash_seed(hash); bucket = Hash_bucket(hash, HASH_TERM(t, seed)); - first_node = chain_node = *bucket; - count_nodes = 0; - while (chain_node) { - if (TrNode_entry(chain_node) == t) { - return chain_node; + first_node = child_node = *bucket; + while (child_node) { + if (TrNode_entry(child_node) == t) { + return child_node; } count_nodes++; - chain_node = TrNode_next(chain_node); + child_node = TrNode_next(child_node); } #ifdef ALLOC_BEFORE_CHECK - new_answer_trie_node(new_node, instr, t, NULL, parent_node, first_node); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ - LOCK_TABLE(parent_node); + LOCK_NODE(parent_node); if (seed != Hash_seed(hash)) { /* the hash has been expanded */ #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); goto answer_hash; } if (first_node != *bucket) { - chain_node = *bucket; + ans_node_ptr chain_node = *bucket; do { if (TrNode_entry(chain_node) == t) { #ifdef ALLOC_BEFORE_CHECK - FREE_ANSWER_TRIE_NODE(new_node); + FREE_ANSWER_TRIE_NODE(child_node); #endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_TABLE(parent_node); + UNLOCK_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); #ifdef ALLOC_BEFORE_CHECK - TrNode_next(new_node) = *bucket; + TrNode_next(child_node) = *bucket; #else - new_answer_trie_node(new_node, instr, t, NULL, parent_node, *bucket); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, *bucket); } else { - new_answer_trie_node(new_node, instr, t, NULL, parent_node, first_node); + new_answer_trie_node(child_node, instr, t, NULL, parent_node, first_node); #endif /* ALLOC_BEFORE_CHECK */ } - *bucket = new_node; + *bucket = child_node; Hash_num_nodes(hash)++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ - ans_node_ptr next_node, *first_old_bucket, *old_bucket; + ans_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; first_old_bucket = Hash_buckets(hash); old_bucket = first_old_bucket + Hash_num_buckets(hash); - seed = Hash_num_buckets(hash) * 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), seed); - seed--; + Hash_num_buckets(hash) *= 2; + ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); + seed = Hash_num_buckets(hash) - 1; do { if (*--old_bucket) { chain_node = *old_bucket; @@ -455,25 +434,13 @@ answer_hash: } while (chain_node); } } while (old_bucket != first_old_bucket); - Hash_num_buckets(hash) = seed + 1; FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_TABLE(parent_node); - return new_node; + UNLOCK_NODE(parent_node); + return child_node; } } #else /* TABLE_LOCK_AT_ENTRY_LEVEL || TABLE_LOCK_AT_NODE_LEVEL || ! YAPOR */ - - -#ifdef TABLE_LOCK_AT_NODE_LEVEL -#define LOCK_NODE(NODE) TRIE_LOCK(TrNode_lock(NODE)) -#define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE)) -#else -#define LOCK_NODE(NODE) -#define UNLOCK_NODE(NODE) -#endif /* TABLE_LOCK_AT_NODE_LEVEL */ - - static inline sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { sg_node_ptr child_node; @@ -489,8 +456,7 @@ sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr pare } if (! IS_SUBGOAL_HASH(child_node)) { - int count_nodes; - count_nodes = 0; + int count_nodes = 0; do { if (TrNode_entry(child_node) == t) { UNLOCK_NODE(parent_node); @@ -524,11 +490,10 @@ sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr pare { /* trie nodes with hashing */ sg_hash_ptr hash; sg_node_ptr *bucket; - int count_nodes; + int count_nodes = 0; hash = (sg_hash_ptr) child_node; bucket = Hash_bucket(hash, HASH_TERM(t, Hash_seed(hash))); child_node = *bucket; - count_nodes = 0; while (child_node) { if (TrNode_entry(child_node) == t) { UNLOCK_NODE(parent_node); @@ -536,10 +501,10 @@ sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr pare } count_nodes++; child_node = TrNode_next(child_node); - } while (child_node); - Hash_num_nodes(hash)++; + } new_subgoal_trie_node(child_node, t, NULL, parent_node, *bucket); *bucket = child_node; + Hash_num_nodes(hash)++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ sg_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; @@ -547,7 +512,7 @@ sg_node_ptr subgoal_trie_node_check_insert(tab_ent_ptr tab_ent, sg_node_ptr pare first_old_bucket = Hash_buckets(hash); old_bucket = first_old_bucket + Hash_num_buckets(hash); Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); + ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); seed = Hash_num_buckets(hash) - 1; do { if (*--old_bucket) { @@ -589,8 +554,7 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ } if (! IS_ANSWER_HASH(child_node)) { - int count_nodes; - count_nodes = 0; + int count_nodes = 0; do { if (TrNode_entry(child_node) == t) { UNLOCK_NODE(parent_node); @@ -624,11 +588,10 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ { /* trie nodes with hashing */ ans_hash_ptr hash; ans_node_ptr *bucket; - int count_nodes; + int count_nodes = 0; hash = (ans_hash_ptr) child_node; bucket = Hash_bucket(hash, HASH_TERM(t, Hash_seed(hash))); child_node = *bucket; - count_nodes = 0; while (child_node) { if (TrNode_entry(child_node) == t) { UNLOCK_NODE(parent_node); @@ -636,10 +599,10 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ } count_nodes++; child_node = TrNode_next(child_node); - } while (child_node); - Hash_num_nodes(hash)++; + } new_answer_trie_node(child_node, instr, t, NULL, parent_node, *bucket); *bucket = child_node; + Hash_num_nodes(hash)++; if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { /* expand current hash */ ans_node_ptr chain_node, next_node, *first_old_bucket, *old_bucket; @@ -647,7 +610,7 @@ ans_node_ptr answer_trie_node_check_insert(sg_fr_ptr sg_fr, ans_node_ptr parent_ first_old_bucket = Hash_buckets(hash); old_bucket = first_old_bucket + Hash_num_buckets(hash); Hash_num_buckets(hash) *= 2; - ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); + ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); seed = Hash_num_buckets(hash) - 1; do { if (*--old_bucket) { @@ -834,12 +797,12 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { current_ans_node = SgFr_answer_trie(sg_fr); for (i = subs_arity; i >= 1; i--) { +#ifdef TABLING_ERRORS + if (IsNonVarTerm(*(subs_ptr + i))) + TABLING_ERROR_MESSAGE("IsNonVarTem(*(subs_ptr + i)) (answer_search)"); +#endif /* TABLING_ERRORS */ STACK_CHECK_EXPAND(stack_terms, stack_vars, stack_terms_base); STACK_PUSH_UP(Deref(*(subs_ptr + i)), stack_terms); -#ifdef TABLING_ERRORS - if (IsNonVarTerm(*stack_terms)) - TABLING_ERROR_MESSAGE("IsNonVarTem(*stack_terms) (answer_search)"); -#endif /* TABLING_ERRORS */ do { Term t = STACK_POP_DOWN(stack_terms); if (IsVarTerm(t)) { @@ -1104,9 +1067,14 @@ void private_completion(sg_fr_ptr sg_fr) { } -void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) { - if (TrNode_next(node)) - free_subgoal_trie_branch(TrNode_next(node), nodes_left, nodes_extra); +void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra, int position) { + int current_nodes_left = 0, current_nodes_extra = 0; + + /* save current state if first sibling node */ + if (position == TRAVERSE_POSITION_FIRST) { + current_nodes_left = nodes_left; + current_nodes_extra = nodes_extra; + } if (nodes_extra) { #ifdef TRIE_COMPACT_PAIRS @@ -1148,7 +1116,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) } } if (nodes_left) - free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra); + free_subgoal_trie_branch(TrNode_child(node), nodes_left, nodes_extra, TRAVERSE_POSITION_FIRST); else { sg_fr_ptr sg_fr; ans_node_ptr ans_node; @@ -1156,7 +1124,7 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) free_answer_hash_chain(SgFr_hash_chain(sg_fr)); ans_node = SgFr_answer_trie(sg_fr); if (TrNode_child(ans_node)) - free_answer_trie_branch(TrNode_child(ans_node)); + free_answer_trie_branch(TrNode_child(ans_node), TRAVERSE_POSITION_FIRST); FREE_ANSWER_TRIE_NODE(ans_node); #ifdef LIMIT_TABLING remove_from_global_sg_fr_list(sg_fr); @@ -1164,21 +1132,41 @@ void free_subgoal_trie_branch(sg_node_ptr node, int nodes_left, int nodes_extra) FREE_SUBGOAL_FRAME(sg_fr); } - FREE_SUBGOAL_TRIE_NODE(node); + if (position == TRAVERSE_POSITION_FIRST) { + sg_node_ptr next = TrNode_next(node); + FREE_SUBGOAL_TRIE_NODE(node); + /* restore the initial state */ + nodes_left = current_nodes_left; + nodes_extra = current_nodes_extra; + while (next) { + node = next; + next = TrNode_next(node); + free_subgoal_trie_branch(node, nodes_left, nodes_extra, TRAVERSE_POSITION_NEXT); + } + } else + FREE_SUBGOAL_TRIE_NODE(node); return; } -void free_answer_trie_branch(ans_node_ptr node) { +void free_answer_trie_branch(ans_node_ptr node, int position) { #ifdef TABLING_INNER_CUTS if (TrNode_child(node) && ! IS_ANSWER_LEAF_NODE(node)) #else if (! IS_ANSWER_LEAF_NODE(node)) #endif /* TABLING_INNER_CUTS */ - free_answer_trie_branch(TrNode_child(node)); - if (TrNode_next(node)) - free_answer_trie_branch(TrNode_next(node)); - FREE_ANSWER_TRIE_NODE(node); + free_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); + + if (position == TRAVERSE_POSITION_FIRST) { + ans_node_ptr next = TrNode_next(node); + FREE_ANSWER_TRIE_NODE(node); + while (next) { + node = next; + next = TrNode_next(node); + free_answer_trie_branch(node, TRAVERSE_POSITION_NEXT); + } + } else + FREE_ANSWER_TRIE_NODE(node); return; } @@ -1188,16 +1176,20 @@ void update_answer_trie(sg_fr_ptr sg_fr) { free_answer_hash_chain(SgFr_hash_chain(sg_fr)); SgFr_hash_chain(sg_fr) = NULL; + SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */ node = TrNode_child(SgFr_answer_trie(sg_fr)); if (node) { +#ifdef YAPOR TrNode_instr(node) -= 1; #ifdef TABLING_INNER_CUTS update_answer_trie_branch(NULL, node); #else update_answer_trie_branch(node); #endif /* TABLING_INNER_CUTS */ +#else /* TABLING */ + update_answer_trie_branch(node, TRAVERSE_POSITION_FIRST); +#endif /* YAPOR */ } - SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */ return; } @@ -1265,7 +1257,7 @@ void traverse_table(tab_ent_ptr tab_ent, int show_table) { int *arity = (int *) malloc(sizeof(int) * ARITY_ARRAY_SIZE); arity[0] = 1; arity[1] = TabEnt_arity(tab_ent); - traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_NORMAL); + traverse_subgoal_trie(sg_node, str, str_index, arity, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST); free(str); free(arity); } else { @@ -1290,7 +1282,7 @@ void traverse_table(tab_ent_ptr tab_ent, int show_table) { } } } else - SHOW_TABLE(" empty\n"); + SHOW_TABLE(" EMPTY\n"); return; } @@ -1399,39 +1391,43 @@ int update_answer_trie_branch(ans_node_ptr node) { #endif /* TABLING_INNER_CUTS */ #else /* TABLING */ static -void update_answer_trie_branch(ans_node_ptr node) { - if (! IS_ANSWER_LEAF_NODE(node)) { - TrNode_instr(TrNode_child(node)) -= 1; /* retry --> try */ - update_answer_trie_branch(TrNode_child(node)); +void update_answer_trie_branch(ans_node_ptr node, int position) { + if (! IS_ANSWER_LEAF_NODE(node)) + update_answer_trie_branch(TrNode_child(node), TRAVERSE_POSITION_FIRST); /* retry --> try */ + if (position == TRAVERSE_POSITION_FIRST) { + ans_node_ptr next = TrNode_next(node); + if (next) { + while (TrNode_next(next)) { + update_answer_trie_branch(next, TRAVERSE_POSITION_NEXT); /* retry --> retry */ + next = TrNode_next(next); + } + update_answer_trie_branch(next, TRAVERSE_POSITION_LAST); /* retry --> trust */ + } else + position += TRAVERSE_POSITION_LAST; /* try --> do */ } - if (TrNode_next(node)) { - update_answer_trie_branch(TrNode_next(node)); - } else { - TrNode_instr(node) -= 2; /* retry --> trust : try --> do */ - } - TrNode_instr(node) = Yap_opcode(TrNode_instr(node)); + TrNode_instr(node) = Yap_opcode(TrNode_instr(node) - position); return; } #endif /* YAPOR */ static -void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode) { +void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *arity, int depth, int mode, int position) { + int *current_arity = NULL, current_str_index = 0, current_mode = 0; Term t; /* test if hashing */ if (IS_SUBGOAL_HASH(sg_node)) { sg_node_ptr *bucket, *last_bucket; sg_hash_ptr hash; - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); - memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); hash = (sg_hash_ptr) sg_node; bucket = Hash_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash); + current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); do { if (*bucket) { - sg_node = *bucket; - traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode); + traverse_subgoal_trie(*bucket, str, str_index, arity, depth, mode, TRAVERSE_POSITION_FIRST); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); #ifdef TRIE_COMPACT_PAIRS if (arity[arity[0]] == -2 && str[str_index - 1] != '[') @@ -1446,37 +1442,29 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a return; } - /* test if sibling node */ - if (TrNode_next(sg_node)) { - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + /* save current state if first sibling node */ + if (position == TRAVERSE_POSITION_FIRST) { + current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); - traverse_subgoal_trie(TrNode_next(sg_node), str, str_index, arity, depth, mode); - memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); - free(current_arity); -#ifdef TRIE_COMPACT_PAIRS - if (arity[arity[0]] == -2 && str[str_index - 1] != '[') - str[str_index - 1] = ','; -#else - if (arity[arity[0]] == -1) - str[str_index - 1] = '|'; -#endif /* TRIE_COMPACT_PAIRS */ + current_str_index = str_index; + current_mode = mode; } /* test the node type */ t = TrNode_entry(sg_node); #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { arity[0]++; arity[arity[0]] = (int) t; - mode = TRAVERSE_FLOAT2; - } else if (mode == TRAVERSE_FLOAT2) { + mode = TRAVERSE_MODE_FLOAT2; + } else if (mode == TRAVERSE_MODE_FLOAT2) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *t_dbl = t; *(t_dbl + 1) = (Term) arity[arity[0]]; arity[0]--; #else /* SIZEOF_DOUBLE == SIZEOF_INT_P */ - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *t_dbl = t; @@ -1507,8 +1495,8 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a } } } - mode = TRAVERSE_NORMAL; - } else if (mode == TRAVERSE_LONG) { + mode = TRAVERSE_MODE_NORMAL; + } else if (mode == TRAVERSE_MODE_LONG) { Int li = (Int) t; #if SHORT_INTS str_index += sprintf(& str[str_index], "%ld", li); @@ -1540,7 +1528,7 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a } } } - mode = TRAVERSE_NORMAL; + mode = TRAVERSE_MODE_NORMAL; } else if (IsVarTerm(t)) { #if SHORT_INTS str_index += sprintf(& str[str_index], "VAR%ld", VarIndexOfTableTerm(t)); @@ -1656,9 +1644,9 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a } else if (IsApplTerm(t)) { Functor f = (Functor) RepAppl(t); if (f == FunctorDouble) { - mode = TRAVERSE_FLOAT; + mode = TRAVERSE_MODE_FLOAT; } else if (f == FunctorLongInt) { - mode = TRAVERSE_LONG; + mode = TRAVERSE_MODE_LONG; } else { str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); arity[0]++; @@ -1702,39 +1690,59 @@ void traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *a SHOW_TABLE(" TRUE\n"); } else { arity[0] = 0; - traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_NORMAL); + traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, 1, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST); if (SgFr_state(sg_fr) < complete) { TrStat_sg_incomplete++; SHOW_TABLE(" ---> INCOMPLETE\n"); } } } - /* ... or continue with child node */ else - traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode); + traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, depth + 1, mode, TRAVERSE_POSITION_FIRST); + + /* continue iteratively with sibling nodes */ + if (position == TRAVERSE_POSITION_FIRST) { + /* restore the initial state */ + str_index = current_str_index; + mode = current_mode; + sg_node = TrNode_next(sg_node); + while (sg_node) { + memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); +#ifdef TRIE_COMPACT_PAIRS + if (arity[arity[0]] == -2 && str[str_index - 1] != '[') + str[str_index - 1] = ','; +#else + if (arity[arity[0]] == -1) + str[str_index - 1] = '|'; +#endif /* TRIE_COMPACT_PAIRS */ + traverse_subgoal_trie(sg_node, str, str_index, arity, depth, mode, TRAVERSE_POSITION_NEXT); + sg_node = TrNode_next(sg_node); + } + free(current_arity); + } return; } static -void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode) { + void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int *arity, int var_index, int depth, int mode, int position) { + int *current_arity = NULL, current_str_index = 0, current_var_index = 0, current_mode = 0; Term t; /* test if hashing */ if (IS_ANSWER_HASH(ans_node)) { ans_node_ptr *bucket, *last_bucket; ans_hash_ptr hash; - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); - memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); hash = (ans_hash_ptr) ans_node; bucket = Hash_buckets(hash); last_bucket = bucket + Hash_num_buckets(hash); + current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); do { if (*bucket) { - ans_node = *bucket; - traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode); + traverse_answer_trie(*bucket, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_FIRST); memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); #ifdef TRIE_COMPACT_PAIRS if (arity[arity[0]] == -2 && str[str_index - 1] != '[') @@ -1749,36 +1757,29 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int * return; } - /* test if sibling node */ - if (TrNode_next(ans_node)) { - int *current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); + /* save current state if first sibling node */ + if (position == TRAVERSE_POSITION_FIRST) { + current_arity = (int *) malloc(sizeof(int) * (arity[0] + 1)); memcpy(current_arity, arity, sizeof(int) * (arity[0] + 1)); - traverse_answer_trie(TrNode_next(ans_node), str, str_index, arity, var_index, depth, mode); - memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); - free(current_arity); -#ifdef TRIE_COMPACT_PAIRS - if (arity[arity[0]] == -2 && str[str_index - 1] != '[') - str[str_index - 1] = ','; -#else - if (arity[arity[0]] == -1) - str[str_index - 1] = '|'; -#endif /* TRIE_COMPACT_PAIRS */ + current_str_index = str_index; + current_var_index = var_index; + current_mode = mode; } /* print VAR when starting a term */ - if (arity[0] == 0 && mode == TRAVERSE_NORMAL) { + if (arity[0] == 0 && mode == TRAVERSE_MODE_NORMAL) { str_index += sprintf(& str[str_index], " VAR%d: ", var_index); var_index++; } /* test the node type */ t = TrNode_entry(ans_node); - if (mode == TRAVERSE_FLOAT) { + if (mode == TRAVERSE_MODE_FLOAT) { #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P arity[0]++; arity[arity[0]] = (int) t; - mode = TRAVERSE_FLOAT2; - } else if (mode == TRAVERSE_FLOAT2) { + mode = TRAVERSE_MODE_FLOAT2; + } else if (mode == TRAVERSE_MODE_FLOAT2) { volatile Float dbl; volatile Term *t_dbl = (Term *)((void *) &dbl); *t_dbl = t; @@ -1815,10 +1816,10 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int * } } } - mode = TRAVERSE_FLOAT_END; - } else if (mode == TRAVERSE_FLOAT_END) { - mode = TRAVERSE_NORMAL; - } else if (mode == TRAVERSE_LONG) { + mode = TRAVERSE_MODE_FLOAT_END; + } else if (mode == TRAVERSE_MODE_FLOAT_END) { + mode = TRAVERSE_MODE_NORMAL; + } else if (mode == TRAVERSE_MODE_LONG) { Int li = (Int) t; #if SHORT_INTS str_index += sprintf(& str[str_index], "%ld", li); @@ -1850,9 +1851,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int * } } } - mode = TRAVERSE_LONG_END; - } else if (mode == TRAVERSE_LONG_END) { - mode = TRAVERSE_NORMAL; + mode = TRAVERSE_MODE_LONG_END; + } else if (mode == TRAVERSE_MODE_LONG_END) { + mode = TRAVERSE_MODE_NORMAL; } else if (IsVarTerm(t)) { #if SHORT_INTS str_index += sprintf(& str[str_index], "ANSVAR%ld", VarIndexOfTableTerm(t)); @@ -1968,9 +1969,9 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int * } else if (IsApplTerm(t)) { Functor f = (Functor) RepAppl(t); if (f == FunctorDouble) { - mode = TRAVERSE_FLOAT; + mode = TRAVERSE_MODE_FLOAT; } else if (f == FunctorLongInt) { - mode = TRAVERSE_LONG; + mode = TRAVERSE_MODE_LONG; } else { str_index += sprintf(& str[str_index], "%s(", AtomName(NameOfFunctor(f))); arity[0]++; @@ -1992,16 +1993,36 @@ void traverse_answer_trie(ans_node_ptr ans_node, char *str, int str_index, int * else if (depth > TrStat_ans_max_depth) TrStat_ans_max_depth = depth; } - #ifdef TABLING_INNER_CUTS /* ... or continue with pruned node */ else if (TrNode_child(ans_node) == NULL) TrStat_ans_pruned++; #endif /* TABLING_INNER_CUTS */ - /* ... or continue with child node */ else - traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode); + traverse_answer_trie(TrNode_child(ans_node), str, str_index, arity, var_index, depth + 1, mode, TRAVERSE_POSITION_FIRST); + + /* continue iteratively with sibling nodes */ + if (position == TRAVERSE_POSITION_FIRST) { + /* restore the initial state */ + str_index = current_str_index; + var_index = current_var_index; + mode = current_mode; + ans_node = TrNode_next(ans_node); + while (ans_node) { + memcpy(arity, current_arity, sizeof(int) * (current_arity[0] + 1)); +#ifdef TRIE_COMPACT_PAIRS + if (arity[arity[0]] == -2 && str[str_index - 1] != '[') + str[str_index - 1] = ','; +#else + if (arity[arity[0]] == -1) + str[str_index - 1] = '|'; +#endif /* TRIE_COMPACT_PAIRS */ + traverse_answer_trie(ans_node, str, str_index, arity, var_index, depth, mode, TRAVERSE_POSITION_NEXT); + ans_node = TrNode_next(ans_node); + } + free(current_arity); + } return; } diff --git a/OPTYap/tab.tries.insts.i b/OPTYap/tab.tries.insts.i index d2f5d33c4..a4a27a88f 100644 --- a/OPTYap/tab.tries.insts.i +++ b/OPTYap/tab.tries.insts.i @@ -521,10 +521,11 @@ ** trie_extension ** ** ------------------------ */ -#define stack_trie_extension_instr() \ - *aux_ptr-- = TrNode_entry(node); \ - *aux_ptr = heap_arity + 1; \ - YENV = aux_ptr; \ +#define stack_trie_extension_instr() \ + *aux_ptr-- = 0; /* float/longint extension mark */ \ + *aux_ptr-- = TrNode_entry(node); \ + *aux_ptr = heap_arity + 2; \ + YENV = aux_ptr; \ next_trie_instruction(node) @@ -1233,13 +1234,15 @@ Term t; #if SIZEOF_DOUBLE == 2 * SIZEOF_INT_P + heap_arity -= 4; *t_dbl = *++aux_ptr; + ++aux_ptr; /* jump the float/longint extension mark */ *(t_dbl + 1) = *++aux_ptr; - heap_arity -= 2; #else /* SIZEOF_DOUBLE == SIZEOF_INT_P */ + heap_arity -= 2; *t_dbl = *++aux_ptr; - heap_arity -= 1; #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ + ++aux_ptr; /* jump the float/longint extension mark */ t = MkFloatTerm(dbl); stack_trie_float_longint_instr(); ENDPBOp(); @@ -1266,9 +1269,11 @@ int heap_arity = *aux_ptr; int vars_arity = *(aux_ptr + heap_arity + 1); int subs_arity = *(aux_ptr + heap_arity + 2); - Term t = MkLongIntTerm(*++aux_ptr); + Term t; - heap_arity -= 1; + heap_arity -= 2; + t = MkLongIntTerm(*++aux_ptr); + ++aux_ptr; /* jump the float/longint extension mark */ stack_trie_float_longint_instr(); ENDPBOp();