diff --git a/C/absmi.c b/C/absmi.c index 3f0a55568..23bafb8fc 100644 --- a/C/absmi.c +++ b/C/absmi.c @@ -10,8 +10,11 @@ * * * File: absmi.c * * comments: Portable abstract machine interpreter * -* Last rev: $Date: 2005-08-02 03:09:48 $,$Author: vsc $ * +* Last rev: $Date: 2005-08-04 15:45:49 $,$Author: ricroc $ * * $Log: not supported by cvs2svn $ +* Revision 1.172 2005/08/02 03:09:48 vsc +* fix debugger to do well nonsource predicates. +* * Revision 1.171 2005/08/01 15:40:36 ricroc * TABLING NEW: better support for incomplete tabling * @@ -1528,7 +1531,15 @@ Yap_absmi(int inp) { register CELL flags; CELL *pt1 = RepPair(d1); - +#ifdef LIMIT_TABLING + if ((ADDR) pt1 == Yap_TrailBase) { + sg_fr_ptr sg_fr = (sg_fr_ptr) TrailVal(pt0); + TrailTerm(pt0) = AbsPair((CELL *)(pt0 - 1)); + SgFr_state(sg_fr)--; /* complete_in_use --> complete : compiled_in_use --> compiled */ + insert_into_global_sg_fr_list(sg_fr); + goto failloop; + } +#endif /* LIMIT_TABLING */ #ifdef FROZEN_STACKS /* TRAIL */ /* avoid frozen segments */ #ifdef SBA @@ -1536,10 +1547,10 @@ Yap_absmi(int inp) #else if ((ADDR) pt1 >= Yap_TrailBase) #endif /* SBA */ - { - pt0 = (tr_fr_ptr) pt1; - goto failloop; - } + { + pt0 = (tr_fr_ptr) pt1; + goto failloop; + } #endif /* FROZEN_STACKS */ flags = *pt1; #if defined(YAPOR) || defined(THREADS) @@ -1702,6 +1713,13 @@ Yap_absmi(int inp) pt1 -= 3; } else if (IsPairTerm(d1)) { CELL *pt = RepPair(d1); +#ifdef LIMIT_TABLING + if ((ADDR) pt == Yap_TrailBase) { + sg_fr_ptr sg_fr = (sg_fr_ptr) TrailVal(pt1); + SgFr_state(sg_fr)--; /* complete_in_use --> complete : compiled_in_use --> compiled */ + insert_into_global_sg_fr_list(sg_fr); + } else +#endif /* LIMIT_TABLING */ if ((ADDR) pt >= Yap_TrailBase) { pt1 = (tr_fr_ptr)pt; } else if ((*pt & (LogUpdMask|IndexMask)) == (LogUpdMask|IndexMask)) { diff --git a/C/c_interface.c b/C/c_interface.c index 0df428f53..7c01c266b 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -10,8 +10,12 @@ * File: c_interface.c * * comments: c_interface primitives definition * * * -* Last rev: $Date: 2005-07-19 17:12:18 $,$Author: rslopes $ * +* Last rev: $Date: 2005-08-04 15:45:51 $,$Author: ricroc $ * * $Log: not supported by cvs2svn $ +* Revision 1.69 2005/07/19 17:12:18 rslopes +* fix for older compilers that do not support declaration of vars +* in the middle of the function code. +* * Revision 1.68 2005/05/31 00:23:47 ricroc * remove abort_yapor function * @@ -1124,6 +1128,7 @@ YAP_Init(YAP_init_args *yap_init) /* tell the system who should cope with interruptions */ Yap_PrologShouldHandleInterrupts = yap_init->PrologShouldHandleInterrupts; Yap_InitWorkspace(Heap, Stack, Trail, + yap_init->MaxTableSpaceSize, yap_init->NumberWorkers, yap_init->SchedulerLoop, yap_init->DelayedReleaseLoad diff --git a/C/errors.c b/C/errors.c index 13f3ffce8..c7fb3bf78 100644 --- a/C/errors.c +++ b/C/errors.c @@ -422,9 +422,13 @@ Yap_Error(yap_error_number type, Term where, char *format,...) tmpbuf[0] = '\0'; } if (Yap_PrologMode == UserCCallMode) { + fprintf(stderr,"%%\n%%\n"); fprintf(stderr,"%% YAP OOOPS in USER C-CODE: %s.\n",tmpbuf); + fprintf(stderr,"%%\n%%\n"); } else { + fprintf(stderr,"%%\n%%\n"); fprintf(stderr,"%% YAP OOOPS: %s.\n",tmpbuf); + fprintf(stderr,"%%\n%%\n"); } error_exit_yap (1); } diff --git a/C/init.c b/C/init.c index e10d01d1d..7e2d4434b 100644 --- a/C/init.c +++ b/C/init.c @@ -1126,13 +1126,8 @@ InitVersion(void) void -Yap_InitWorkspace(int Heap, - int Stack, - int Trail, - int aux_number_workers, - int aux_scheduler_loop, - int aux_delayed_release_load -) +Yap_InitWorkspace(int Heap, int Stack, int Trail, int max_table_size, + int n_workers, int sch_loop, int delay_load) { int i; @@ -1159,22 +1154,22 @@ Yap_InitWorkspace(int Heap, #ifdef YAPOR worker_id = 0; - if (aux_number_workers > MAX_WORKERS) + if (n_workers > MAX_WORKERS) Yap_Error(INTERNAL_ERROR, TermNil, "excessive number of workers (Yap_InitWorkspace)"); #ifdef ENV_COPY - INFORMATION_MESSAGE("YapOr: copy model with %d worker%s", aux_number_workers, aux_number_workers == 1 ? "":"s"); + INFORMATION_MESSAGE("YapOr: copy model with %d worker%s", n_workers, n_workers == 1 ? "":"s"); #elif ACOW - INFORMATION_MESSAGE("YapOr: acow model with %d worker%s", aux_number_workers, aux_number_workers == 1 ? "":"s"); + INFORMATION_MESSAGE("YapOr: acow model with %d worker%s", n_workers, n_workers == 1 ? "":"s"); #else /* SBA */ - INFORMATION_MESSAGE("YapOr: sba model with %d worker%s", aux_number_workers, aux_number_workers == 1 ? "":"s"); + INFORMATION_MESSAGE("YapOr: sba model with %d worker%s", n_workers, n_workers == 1 ? "":"s"); #endif /* ENV_COPY - ACOW - SBA */ - map_memory(Heap, Stack, Trail, aux_number_workers); + map_memory(Heap, Stack, Trail, n_workers); #else Yap_InitMemory (Trail, Heap, Stack); #endif /* YAPOR */ #if defined(YAPOR) || defined(TABLING) - init_global(aux_number_workers, aux_scheduler_loop, aux_delayed_release_load); + init_global(max_table_size, n_workers, sch_loop, delay_load); #endif /* YAPOR || TABLING */ Yap_InitTime (); diff --git a/C/stdpreds.c b/C/stdpreds.c index a8d4d92b9..f1d59c74f 100644 --- a/C/stdpreds.c +++ b/C/stdpreds.c @@ -11,8 +11,11 @@ * File: stdpreds.c * * comments: General-purpose C implemented system predicates * * * -* Last rev: $Date: 2005-07-20 13:54:27 $,$Author: rslopes $ * +* Last rev: $Date: 2005-08-04 15:45:53 $,$Author: ricroc $ * * $Log: not supported by cvs2svn $ +* Revision 1.92 2005/07/20 13:54:27 rslopes +* solved warning: cast from pointer to integer of different size +* * Revision 1.91 2005/07/06 19:33:54 ricroc * TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure. * @@ -2814,7 +2817,7 @@ p_access_yap_flags(void) { Term tflag = Deref(ARG1); Int flag; - Term tout; + Term tout = 0; if (IsVarTerm(tflag)) { Yap_Error(INSTANTIATION_ERROR, tflag, "access_yap_flags/2"); diff --git a/H/Yapproto.h b/H/Yapproto.h index 4da36fe85..fc19a669b 100644 --- a/H/Yapproto.h +++ b/H/Yapproto.h @@ -10,7 +10,7 @@ * File: Yap.proto * * mods: * * comments: Function declarations for YAP * -* version: $Id: Yapproto.h,v 1.58 2004-12-28 22:20:36 vsc Exp $ * +* version: $Id: Yapproto.h,v 1.59 2005-08-04 15:45:53 ricroc Exp $ * *************************************************************************/ /* prototype file for Yap */ @@ -186,7 +186,7 @@ void STD_PROTO(Yap_InitCPred,(char *, unsigned long int, CPredicate, int)); void STD_PROTO(Yap_InitAsmPred,(char *, unsigned long int, int, CPredicate, int)); void STD_PROTO(Yap_InitCmpPred,(char *, unsigned long int, CmpPredicate, int)); void STD_PROTO(Yap_InitCPredBack,(char *, unsigned long int, unsigned int, CPredicate,CPredicate,int)); -void STD_PROTO(Yap_InitWorkspace,(int,int,int,int,int,int)); +void STD_PROTO(Yap_InitWorkspace,(int,int,int,int,int,int,int)); #if defined(YAPOR) || defined(THREADS) void STD_PROTO(Yap_KillStacks,(int)); diff --git a/H/amiops.h b/H/amiops.h index 5d830e4b8..49812db0d 100644 --- a/H/amiops.h +++ b/H/amiops.h @@ -136,8 +136,8 @@ AlignGlobalForDouble(void) register tr_fr_ptr r; \ r = TR; \ TR = r + 1; \ - TrailTerm(r) = (CELL) (TERM); \ - TrailVal(r) = (VAL); \ + TrailTerm(r) = (Term) (TERM); \ + TrailVal(r) = (CELL) (VAL); \ } #ifdef BFZ_TRAIL_SCHEME @@ -304,20 +304,18 @@ Binding Macros for Multiple Assignment Variables. #endif /* TABLING */ -#define REF_TO_TRENTRY(REF) AbsPair(((CELL *)&((REF)->Flags))) -#define CLREF_TO_TRENTRY(REF) AbsPair(((CELL *)&((REF)->ClFlags))) +#define REF_TO_TRENTRY(REF) AbsPair(((CELL *)&((REF)->Flags))) +#define CLREF_TO_TRENTRY(REF) AbsPair(((CELL *)&((REF)->ClFlags))) -#define TRAIL_REF(REF) TrailTerm(TR++) = REF_TO_TRENTRY(REF) -#define TRAIL_CLREF(REF) TrailTerm(TR++) = CLREF_TO_TRENTRY(REF) -#define TRAIL_LINK(REF) TrailTerm(TR++) = AbsPair((CELL *)(REF)) +#define TRAIL_REF(REF) TrailTerm(TR++) = REF_TO_TRENTRY(REF) +#define TRAIL_CLREF(REF) TrailTerm(TR++) = CLREF_TO_TRENTRY(REF) +#define TRAIL_LINK(REF) TrailTerm(TR++) = AbsPair((CELL *)(REF)) +#define TRAIL_FRAME(FR) DO_TRAIL(AbsPair((CELL *)(Yap_TrailBase)), FR) -#define Bind(A,D) TRAIL(A,D); *(A) = (D) - -#define Bind_Global(A,D) TRAIL_GLOBAL(A,D); *(A) = (D) - -#define BIND(A,D,L) *(A) = (D); Trail(A,D,L) - -#define BIND_GLOBAL(A,D,L) *(A) = (D); Trail_Global(A,D,L) +#define Bind(A,D) TRAIL(A,D); *(A) = (D) +#define Bind_Global(A,D) TRAIL_GLOBAL(A,D); *(A) = (D) +#define BIND(A,D,L) *(A) = (D); Trail(A,D,L) +#define BIND_GLOBAL(A,D,L) *(A) = (D); Trail_Global(A,D,L) #ifdef COROUTINING #define BIND_GLOBAL2(A,D,LAB,LAB1) *(A) = (D); if ((A) < HBREG) goto LAB; goto LAB1 diff --git a/OPTYap/opt.config.h b/OPTYap/opt.config.h index 74f4eb33d..78a489ea7 100644 --- a/OPTYap/opt.config.h +++ b/OPTYap/opt.config.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.config.h - version: $Id: opt.config.h,v 1.8 2005-08-01 15:40:38 ricroc Exp $ + version: $Id: opt.config.h,v 1.9 2005-08-04 15:45:54 ricroc Exp $ **********************************************************************/ @@ -63,6 +63,11 @@ /* #define TABLE_LOCK_AT_NODE_LEVEL 1 */ /* #define ALLOC_BEFORE_CHECK 1 */ +/* ----------------------------------------------- ** +** limit the table space size? (optional) ** +** ----------------------------------------------- */ +/* #define LIMIT_TABLING 1 */ + /* ----------------------------------------------- ** ** support incomplete tabling? (optional) ** ** ----------------------------------------------- */ @@ -116,6 +121,7 @@ #if defined(MMAP_MEMORY_MAPPING_SCHEME) && defined(SHM_MEMORY_MAPPING_SCHEME) #error Do not define multiple memory mapping schemes #endif /* MMAP_MEMORY_MAPPING_SCHEME && SHM_MEMORY_MAPPING_SCHEME */ +#undef LIMIT_TABLING #endif /* YAPOR */ #ifdef TABLING @@ -125,9 +131,6 @@ #if defined(BFZ_TRAIL_SCHEME) && defined(BBREG_TRAIL_SCHEME) #error Do not define multiple trail schemes #endif /* BFZ_TRAIL_SCHEME && BBREG_TRAIL_SCHEME */ -#else -#undef BFZ_TRAIL_SCHEME -#undef BBREG_TRAIL_SCHEME #endif /* TABLING */ #if defined(YAPOR) && defined(TABLING) @@ -162,10 +165,17 @@ #endif /* !YAPOR */ #ifndef TABLING +#undef BFZ_TRAIL_SCHEME +#undef BBREG_TRAIL_SCHEME +#undef LIMIT_TABLING #undef INCOMPLETE_TABLING #undef TABLING_ERRORS #endif /* !TABLING */ +#ifndef SHM_MEMORY_ALLOC_SCHEME +#undef LIMIT_TABLING +#endif /* !SHM_MEMORY_ALLOC_SCHEME */ + #if defined(YAPOR_ERRORS) && defined(TABLING_ERRORS) #define OPTYAP_ERRORS #endif /* YAPOR_ERRORS && TABLING_ERRORS */ diff --git a/OPTYap/opt.init.c b/OPTYap/opt.init.c index cf17f9d5a..2b7eb2581 100644 --- a/OPTYap/opt.init.c +++ b/OPTYap/opt.init.c @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.init.c - version: $Id: opt.init.c,v 1.9 2005-07-11 19:17:26 ricroc Exp $ + version: $Id: opt.init.c,v 1.10 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -61,10 +61,13 @@ ma_h_inner_struct *ma_h_top; ** Global functions ** ** -------------------------- */ -void init_global(int n_workers, int sch_loop, int delay_load) { +void init_global(int max_table_size, int n_workers, int sch_loop, int delay_load) { int i; /* global data related to memory management */ +#ifdef LIMIT_TABLING + GLOBAL_MAX_PAGES = max_table_size * 1024 * 1024 / Yap_page_size; +#endif /* LIMIT_TABLING */ INIT_PAGES(GLOBAL_PAGES_void, void *); #ifdef YAPOR INIT_PAGES(GLOBAL_PAGES_or_fr, struct or_frame); @@ -135,6 +138,11 @@ void init_global(int n_workers, int sch_loop, int delay_load) { #ifdef TABLING /* global data related to tabling */ GLOBAL_root_tab_ent = NULL; +#ifdef LIMIT_TABLING + GLOBAL_first_sg_fr = NULL; + GLOBAL_last_sg_fr = NULL; + GLOBAL_check_sg_fr = NULL; +#endif /* LIMIT_TABLING */ for (i = 0; i < MAX_TABLE_VARS; i++) GLOBAL_table_var_enumerator(i) = (CELL) & GLOBAL_table_var_enumerator(i); #ifdef TABLE_LOCK_AT_WRITE_LEVEL diff --git a/OPTYap/opt.macros.h b/OPTYap/opt.macros.h index d9cabe528..37e89c4b7 100644 --- a/OPTYap/opt.macros.h +++ b/OPTYap/opt.macros.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.macros.h - version: $Id: opt.macros.h,v 1.8 2005-08-01 15:40:38 ricroc Exp $ + version: $Id: opt.macros.h,v 1.9 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -15,7 +15,7 @@ #include -#define SHMMAX 0x2000000 /* works fine with linux */ +#define SHMMAX 0x2000000 /* 32 Mbytes: works fine with linux */ @@ -50,178 +50,212 @@ 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) \ - UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ - if ((STR = (STR_TYPE *) Yap_AllocCodeSpace(sizeof(STR_TYPE))) == NULL) \ +#elif YAP_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ +#define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ + UPDATE_STATS(Pg_str_in_use(STR_PAGES), 1); \ + if ((STR = (STR_TYPE *) Yap_AllocCodeSpace(sizeof(STR_TYPE))) == NULL) \ Yap_Error(FATAL_ERROR, TermNil, "Yap_AllocCodeSpace 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); \ Yap_FreeCodeSpace((char *) (STR)) -#elif SHM_MEMORY_ALLOC_SCHEME /* ------------------------------------------------ */ -#define ALLOC_PAGE(PG_HD) \ - LOCK(Pg_lock(GLOBAL_PAGES_void)); \ - UPDATE_STATS(Pg_str_in_use(GLOBAL_PAGES_void), 1); \ - 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); \ - } \ - PG_HD = Pg_free_pg(GLOBAL_PAGES_void); \ - Pg_free_pg(GLOBAL_PAGES_void) = PgHd_next(PG_HD); \ +#elif SHM_MEMORY_ALLOC_SCHEME /* ---------------------------------------------------- */ +#ifdef LIMIT_TABLING +#define CHECK_TABLE_LIMIT \ + if (GLOBAL_MAX_PAGES && Pg_pg_alloc(GLOBAL_PAGES_void) >= GLOBAL_MAX_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, "table space full (CHECK_TABLE_LIMIT)"); \ + /* 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) == NULL); \ + GLOBAL_check_sg_fr = sg_fr; \ + } else +#else +#define CHECK_TABLE_LIMIT +#endif /* LIMIT_TABLING */ + +#define ALLOC_PAGE(PG_HD) \ + LOCK(Pg_lock(GLOBAL_PAGES_void)); \ + if (Pg_free_pg(GLOBAL_PAGES_void) == NULL) { \ + CHECK_TABLE_LIMIT \ + { 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 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 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) -#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 a4f1d40a9..1f4663bae 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.preds.c - version: $Id: opt.preds.c,v 1.23 2005-08-01 17:59:49 ricroc Exp $ + version: $Id: opt.preds.c,v 1.24 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -585,6 +585,19 @@ int p_tabling_mode(void) { else mode = MkAtomTerm(Yap_LookupAtom("batched")); t = MkPairTerm(mode, t); + mode = MkAtomTerm(Yap_LookupAtom("default")); + t = MkPairTerm(mode, t); + t = MkPairTerm(t, MkAtomTerm(AtomNil)); + if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) + mode = MkAtomTerm(Yap_LookupAtom("load_answers")); + else + mode = MkAtomTerm(Yap_LookupAtom("exec_answers")); + t = MkPairTerm(mode, t); + if (IsMode_Local(TabEnt_mode(tab_ent))) + mode = MkAtomTerm(Yap_LookupAtom("local")); + else + mode = MkAtomTerm(Yap_LookupAtom("batched")); + t = MkPairTerm(mode, t); Bind((CELL *)val, t); return(TRUE); } @@ -866,8 +879,8 @@ void shm_pages(long pages_in_use, long bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "\n%s total memory in use: %8ld pages %10ld bytes\n", - (Pg_str_in_use(GLOBAL_PAGES_void) == pages_in_use && - Pg_pg_alloc(GLOBAL_PAGES_void) - pages_in_use == cont) ? " ": "*", + Pg_str_in_use(GLOBAL_PAGES_void) == pages_in_use && + Pg_pg_alloc(GLOBAL_PAGES_void) - pages_in_use == cont ? " ": "*", Pg_str_in_use(GLOBAL_PAGES_void), bytes_in_use); fprintf(Yap_stderr, " total memory: %8ld pages %10ld bytes\n", Pg_pg_alloc(GLOBAL_PAGES_void), Pg_pg_alloc(GLOBAL_PAGES_void) * Yap_page_size); @@ -892,7 +905,8 @@ void shm_or_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s or frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_or_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_or_fr) == 1) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_or_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_or_fr) == 1 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_or_fr), Pg_str_in_use(GLOBAL_PAGES_or_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_or_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_or_fr) * sizeof(struct or_frame); @@ -916,7 +930,8 @@ void shm_query_goal_solution_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s query goal solution frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_qg_sol_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_qg_sol_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_qg_sol_fr), Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_qg_sol_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_qg_sol_fr) * sizeof(struct query_goal_solution_frame); @@ -940,7 +955,8 @@ void shm_query_goal_answer_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s query goal answer frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_qg_ans_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_qg_ans_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_qg_ans_fr), Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_qg_ans_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_qg_ans_fr) * sizeof(struct query_goal_answer_frame); @@ -966,7 +982,8 @@ void shm_table_subgoal_solution_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s table subgoal solution frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_tg_sol_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_tg_sol_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_tg_sol_fr), Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_tg_sol_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_tg_sol_fr) * sizeof(struct table_subgoal_solution_frame); @@ -990,7 +1007,8 @@ void shm_table_subgoal_answer_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s table subgoal answer frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_tg_ans_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_tg_ans_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_tg_ans_fr), Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_tg_ans_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_tg_ans_fr) * sizeof(struct table_subgoal_answer_frame); @@ -1006,6 +1024,11 @@ void shm_table_entries(long *pages_in_use, long *bytes_in_use) { pg_hd_ptr pg_hd; tab_ent_ptr aux_ptr; + aux_ptr = GLOBAL_root_tab_ent; + while(aux_ptr) { + cont++; + aux_ptr = TabEnt_next(aux_ptr); + } pg_hd = Pg_free_pg(GLOBAL_PAGES_tab_ent); while (pg_hd) { aux_ptr = PgHd_free_str(pg_hd); @@ -1016,7 +1039,7 @@ void shm_table_entries(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s table entries: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_tab_ent) == cont) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_tab_ent) + Pg_str_in_use(GLOBAL_PAGES_tab_ent) == cont ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_tab_ent), Pg_str_in_use(GLOBAL_PAGES_tab_ent)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_tab_ent); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_tab_ent) * sizeof(struct table_entry); @@ -1030,6 +1053,13 @@ void shm_subgoal_frames(long *pages_in_use, long *bytes_in_use) { pg_hd_ptr pg_hd; sg_fr_ptr aux_ptr; +#ifdef LIMIT_TABLING + aux_ptr = GLOBAL_first_sg_fr; + while(aux_ptr) { + cont++; + aux_ptr = SgFr_next(aux_ptr); + } +#endif /* LIMIT_TABLING */ pg_hd = Pg_free_pg(GLOBAL_PAGES_sg_fr); while (pg_hd) { aux_ptr = PgHd_free_str(pg_hd); @@ -1040,7 +1070,10 @@ void shm_subgoal_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s subgoal frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_sg_fr) == cont) ? " ": "*", +#ifdef LIMIT_TABLING + Pg_str_in_use(GLOBAL_PAGES_sg_fr) + +#endif /* LIMIT_TABLING */ + Pg_str_free(GLOBAL_PAGES_sg_fr) == cont ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_sg_fr), Pg_str_in_use(GLOBAL_PAGES_sg_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_sg_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_sg_fr) * sizeof(struct subgoal_frame); @@ -1064,7 +1097,7 @@ void shm_subgoal_trie_nodes(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s subgoal trie nodes: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_sg_node) == cont) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_sg_node) == cont ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_sg_node), Pg_str_in_use(GLOBAL_PAGES_sg_node)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_sg_node); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_sg_node) * sizeof(struct subgoal_trie_node); @@ -1088,7 +1121,7 @@ void shm_answer_trie_nodes(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s answer trie nodes: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_ans_node) == cont) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_ans_node) == cont ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_ans_node), Pg_str_in_use(GLOBAL_PAGES_ans_node)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_ans_node); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_ans_node) * sizeof(struct answer_trie_node); @@ -1112,7 +1145,7 @@ void shm_subgoal_hashes(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s subgoal hashes: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_sg_hash) == cont) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_sg_hash) == cont ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_sg_hash), Pg_str_in_use(GLOBAL_PAGES_sg_hash)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_sg_hash); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_sg_hash) * sizeof(struct subgoal_hash); @@ -1136,7 +1169,8 @@ void shm_answer_hashes(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s answer hashes: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_ans_hash) == cont && Pg_str_in_use(GLOBAL_PAGES_ans_hash) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_ans_hash) == cont && + Pg_str_in_use(GLOBAL_PAGES_ans_hash) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_ans_hash), Pg_str_in_use(GLOBAL_PAGES_ans_hash)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_ans_hash); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_ans_hash) * sizeof(struct answer_hash); @@ -1160,7 +1194,8 @@ void shm_dependency_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s dependency frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_dep_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_dep_fr) == 1) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_dep_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_dep_fr) == 1 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_dep_fr), Pg_str_in_use(GLOBAL_PAGES_dep_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_dep_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_dep_fr) * sizeof(struct dependency_frame); @@ -1186,7 +1221,8 @@ void shm_suspension_frames(long *pages_in_use, long *bytes_in_use) { pg_hd = PgHd_next(pg_hd); } fprintf(Yap_stderr, "%s suspension frames: %8ld pages %10ld structs in use\n", - (Pg_str_free(GLOBAL_PAGES_susp_fr) == cont && Pg_str_in_use(GLOBAL_PAGES_susp_fr) == 0) ? " ": "*", + Pg_str_free(GLOBAL_PAGES_susp_fr) == cont && + Pg_str_in_use(GLOBAL_PAGES_susp_fr) == 0 ? " ": "*", Pg_pg_alloc(GLOBAL_PAGES_susp_fr), Pg_str_in_use(GLOBAL_PAGES_susp_fr)); *pages_in_use += Pg_pg_alloc(GLOBAL_PAGES_susp_fr); *bytes_in_use += Pg_str_in_use(GLOBAL_PAGES_susp_fr) * sizeof(struct suspension_frame); diff --git a/OPTYap/opt.proto.h b/OPTYap/opt.proto.h index b2ef32dff..4a110a623 100644 --- a/OPTYap/opt.proto.h +++ b/OPTYap/opt.proto.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.proto.h - version: $Id: opt.proto.h,v 1.10 2005-08-01 15:40:38 ricroc Exp $ + version: $Id: opt.proto.h,v 1.11 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -41,7 +41,7 @@ void error_message(const char *mesg, ...); ** opt.init.c ** ** ------------ */ -void init_global(int n_workers, int sch_loop, int delay_load); +void init_global(int max_table_size, int n_workers, int sch_loop, int delay_load); void init_local(void); void make_root_frames(void); #ifdef YAPOR diff --git a/OPTYap/opt.structs.h b/OPTYap/opt.structs.h index 31737191e..2cb8cc891 100644 --- a/OPTYap/opt.structs.h +++ b/OPTYap/opt.structs.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: opt.structs.h - version: $Id: opt.structs.h,v 1.8 2005-07-11 19:17:27 ricroc Exp $ + version: $Id: opt.structs.h,v 1.9 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -64,6 +64,9 @@ struct pages { ** ----------------------------- */ struct global_pages { +#ifdef LIMIT_TABLING + int max_pages; +#endif /* LIMIT_TABLING */ struct pages void_pages; #ifdef YAPOR struct pages or_frame_pages; @@ -163,6 +166,11 @@ struct global_data{ #ifdef TABLING /* global data related to tabling */ struct table_entry *root_table_entry; +#ifdef LIMIT_TABLING + struct subgoal_frame *first_subgoal_frame; + struct subgoal_frame *last_subgoal_frame; + struct subgoal_frame *check_subgoal_frame; +#endif /* LIMIT_TABLING */ struct dependency_frame *root_dependency_frame; CELL table_var_enumerator[MAX_TABLE_VARS]; #ifdef TABLE_LOCK_AT_WRITE_LEVEL @@ -174,6 +182,7 @@ struct global_data{ #endif /* TABLING */ }; +#define GLOBAL_MAX_PAGES (GLOBAL.pages.max_pages) #define GLOBAL_PAGES_void (GLOBAL.pages.void_pages) #define GLOBAL_PAGES_or_fr (GLOBAL.pages.or_frame_pages) #define GLOBAL_PAGES_qg_sol_fr (GLOBAL.pages.query_goal_solution_frame_pages) @@ -222,6 +231,9 @@ struct global_data{ #define PARALLEL_EXECUTION_MODE (GLOBAL.parallel_execution_mode) #define GLOBAL_answers (GLOBAL.answers) #define GLOBAL_root_tab_ent (GLOBAL.root_table_entry) +#define GLOBAL_first_sg_fr (GLOBAL.first_subgoal_frame) +#define GLOBAL_last_sg_fr (GLOBAL.last_subgoal_frame) +#define GLOBAL_check_sg_fr (GLOBAL.check_subgoal_frame) #define GLOBAL_root_dep_fr (GLOBAL.root_dependency_frame) #define GLOBAL_table_var_enumerator(index) (GLOBAL.table_var_enumerator[index]) #define GLOBAL_table_lock(index) (GLOBAL.table_lock[index]) diff --git a/OPTYap/tab.insts.i b/OPTYap/tab.insts.i index 4b2b21e75..a8bfb8e2c 100644 --- a/OPTYap/tab.insts.i +++ b/OPTYap/tab.insts.i @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: tab.insts.i - version: $Id: tab.insts.i,v 1.18 2005-08-01 18:26:28 ricroc Exp $ + version: $Id: tab.insts.i,v 1.19 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -362,32 +362,33 @@ tab_ent = PREG->u.ld.te; sg_fr = subgoal_search(PREG, &YENV); LOCK(SgFr_lock(sg_fr)); - if (SgFr_state(sg_fr) == start) { - /* subgoal new or not complete (abolished) */ -#ifdef INCOMPLETE_TABLING - ans_node_ptr ans_node = SgFr_first_answer(sg_fr); - if (ans_node) { - /* subgoal not complete --> start by loading the answers already found */ - CELL *subs_ptr = YENV; - init_subgoal_frame(sg_fr); - UNLOCK(SgFr_lock(sg_fr)); - SgFr_try_answer(sg_fr) = ans_node; - store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); - PREG = (yamop *) CPREG; - PREFETCH_OP(PREG); - load_answer_trie(ans_node, subs_ptr); - YENV = ENV; - GONext(); - } -#endif /* INCOMPLETE_TABLING */ + if (SgFr_state(sg_fr) == ready) { /* subgoal new */ init_subgoal_frame(sg_fr); UNLOCK(SgFr_lock(sg_fr)); store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, COMPLETION); - PREG = PREG->u.ld.d; /* PREG = NEXTOP(PREG,ld); */ + PREG = PREG->u.ld.d; /* should work also with PREG = NEXTOP(PREG,ld); */ PREFETCH_OP(PREG); allocate_environment(); GONext(); +#ifdef INCOMPLETE_TABLING + } else if (SgFr_state(sg_fr) == incomplete) { + /* subgoal incomplete --> start by loading the answers already found */ + ans_node_ptr ans_node = SgFr_first_answer(sg_fr); + CELL *subs_ptr = YENV; + init_subgoal_frame(sg_fr); + UNLOCK(SgFr_lock(sg_fr)); +#ifdef LIMIT_TABLING + remove_from_global_sg_fr_list(sg_fr); +#endif /* LIMIT_TABLING */ + SgFr_try_answer(sg_fr) = ans_node; + store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); + PREG = (yamop *) CPREG; + PREFETCH_OP(PREG); + load_answer_trie(ans_node, subs_ptr); + YENV = ENV; + GONext(); +#endif /* INCOMPLETE_TABLING */ } else if (SgFr_state(sg_fr) == evaluating) { /* subgoal in evaluation */ choiceptr leader_cp; @@ -403,12 +404,12 @@ while (YOUNGER_CP(aux_cp, LOCAL_top_cp_on_stack)) aux_cp = aux_cp->cp_b; if (aux_cp->cp_or_fr != DepFr_top_or_fr(LOCAL_top_dep_fr)) - OPTYAP_ERROR_MESSAGE("Error on DepFr_top_or_fr (table_try_me_single)"); + OPTYAP_ERROR_MESSAGE("Error on DepFr_top_or_fr (table_try_single)"); aux_cp = B; while (YOUNGER_CP(aux_cp, DepFr_leader_cp(LOCAL_top_dep_fr))) aux_cp = aux_cp->cp_b; if (aux_cp != DepFr_leader_cp(LOCAL_top_dep_fr)) - OPTYAP_ERROR_MESSAGE("Error on DepFr_leader_cp (table_try_me_single)"); + OPTYAP_ERROR_MESSAGE("Error on DepFr_leader_cp (table_try_single)"); } #endif /* OPTYAP_ERRORS */ goto answer_resolution; @@ -428,6 +429,13 @@ GONext(); } else { /* answers -> get first answer */ +#ifdef LIMIT_TABLING + if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) { + SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */ + remove_from_global_sg_fr_list(sg_fr); + TRAIL_FRAME(sg_fr); + } +#endif /* LIMIT_TABLING */ if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) { /* load answers from the trie */ UNLOCK(SgFr_lock(sg_fr)); @@ -441,7 +449,7 @@ GONext(); } else { /* execute compiled code from the trie */ - if (SgFr_state(sg_fr) == complete) + if (SgFr_state(sg_fr) < compiled) update_answer_trie(sg_fr); UNLOCK(SgFr_lock(sg_fr)); PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr)); @@ -464,24 +472,7 @@ tab_ent = PREG->u.ld.te; sg_fr = subgoal_search(PREG, &YENV); LOCK(SgFr_lock(sg_fr)); - if (SgFr_state(sg_fr) == start) { - /* subgoal new or not complete (abolished) */ -#ifdef INCOMPLETE_TABLING - ans_node_ptr ans_node = SgFr_first_answer(sg_fr); - if (ans_node) { - /* subgoal not complete --> start by loading the answers already found */ - CELL *subs_ptr = YENV; - init_subgoal_frame(sg_fr); - UNLOCK(SgFr_lock(sg_fr)); - SgFr_try_answer(sg_fr) = ans_node; - store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); - PREG = (yamop *) CPREG; - PREFETCH_OP(PREG); - load_answer_trie(ans_node, subs_ptr); - YENV = ENV; - GONext(); - } -#endif /* INCOMPLETE_TABLING */ + if (SgFr_state(sg_fr) == ready) { /* subgoal new */ init_subgoal_frame(sg_fr); UNLOCK(SgFr_lock(sg_fr)); @@ -490,6 +481,24 @@ PREFETCH_OP(PREG); allocate_environment(); GONext(); +#ifdef INCOMPLETE_TABLING + } else if (SgFr_state(sg_fr) == incomplete) { + /* subgoal incomplete --> start by loading the answers already found */ + ans_node_ptr ans_node = SgFr_first_answer(sg_fr); + CELL *subs_ptr = YENV; + init_subgoal_frame(sg_fr); + UNLOCK(SgFr_lock(sg_fr)); +#ifdef LIMIT_TABLING + remove_from_global_sg_fr_list(sg_fr); +#endif /* LIMIT_TABLING */ + SgFr_try_answer(sg_fr) = ans_node; + store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); + PREG = (yamop *) CPREG; + PREFETCH_OP(PREG); + load_answer_trie(ans_node, subs_ptr); + YENV = ENV; + GONext(); +#endif /* INCOMPLETE_TABLING */ } else if (SgFr_state(sg_fr) == evaluating) { /* subgoal in evaluation */ choiceptr leader_cp; @@ -530,6 +539,13 @@ GONext(); } else { /* answers -> get first answer */ +#ifdef LIMIT_TABLING + if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) { + SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */ + remove_from_global_sg_fr_list(sg_fr); + TRAIL_FRAME(sg_fr); + } +#endif /* LIMIT_TABLING */ if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) { /* load answers from the trie */ UNLOCK(SgFr_lock(sg_fr)); @@ -543,7 +559,7 @@ GONext(); } else { /* execute compiled code from the trie */ - if (SgFr_state(sg_fr) == complete) + if (SgFr_state(sg_fr) < compiled) update_answer_trie(sg_fr); UNLOCK(SgFr_lock(sg_fr)); PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr)); @@ -566,24 +582,7 @@ tab_ent = PREG->u.ld.te; sg_fr = subgoal_search(PREG, &YENV); LOCK(SgFr_lock(sg_fr)); - if (SgFr_state(sg_fr) == start) { - /* subgoal new or not complete (abolished) */ -#ifdef INCOMPLETE_TABLING - ans_node_ptr ans_node = SgFr_first_answer(sg_fr); - if (ans_node) { - /* subgoal not complete --> start by loading the answers already found */ - CELL *subs_ptr = YENV; - init_subgoal_frame(sg_fr); - UNLOCK(SgFr_lock(sg_fr)); - SgFr_try_answer(sg_fr) = ans_node; - store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); - PREG = (yamop *) CPREG; - PREFETCH_OP(PREG); - load_answer_trie(ans_node, subs_ptr); - YENV = ENV; - GONext(); - } -#endif /* INCOMPLETE_TABLING */ + if (SgFr_state(sg_fr) == ready) { /* subgoal new */ init_subgoal_frame(sg_fr); UNLOCK(SgFr_lock(sg_fr)); @@ -592,6 +591,24 @@ PREFETCH_OP(PREG); allocate_environment(); GONext(); +#ifdef INCOMPLETE_TABLING + } else if (SgFr_state(sg_fr) == incomplete) { + /* subgoal incomplete --> start by loading the answers already found */ + ans_node_ptr ans_node = SgFr_first_answer(sg_fr); + CELL *subs_ptr = YENV; + init_subgoal_frame(sg_fr); + UNLOCK(SgFr_lock(sg_fr)); +#ifdef LIMIT_TABLING + remove_from_global_sg_fr_list(sg_fr); +#endif /* LIMIT_TABLING */ + SgFr_try_answer(sg_fr) = ans_node; + store_generator_node(tab_ent, sg_fr, PREG->u.ld.s, TRY_ANSWER); + PREG = (yamop *) CPREG; + PREFETCH_OP(PREG); + load_answer_trie(ans_node, subs_ptr); + YENV = ENV; + GONext(); +#endif /* INCOMPLETE_TABLING */ } else if (SgFr_state(sg_fr) == evaluating) { /* subgoal in evaluation */ choiceptr leader_cp; @@ -632,6 +649,13 @@ GONext(); } else { /* answers -> get first answer */ +#ifdef LIMIT_TABLING + if (SgFr_state(sg_fr) == complete || SgFr_state(sg_fr) == compiled) { + SgFr_state(sg_fr)++; /* complete --> complete_in_use : compiled --> compiled_in_use */ + remove_from_global_sg_fr_list(sg_fr); + TRAIL_FRAME(sg_fr); + } +#endif /* LIMIT_TABLING */ if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) { /* load answers from the trie */ UNLOCK(SgFr_lock(sg_fr)); @@ -645,7 +669,7 @@ GONext(); } else { /* execute compiled code from the trie */ - if (SgFr_state(sg_fr) == complete) + if (SgFr_state(sg_fr) < compiled) update_answer_trie(sg_fr); UNLOCK(SgFr_lock(sg_fr)); PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr)); @@ -1554,6 +1578,11 @@ } else { /* answers -> get first answer */ tab_ent_ptr tab_ent = SgFr_tab_ent(sg_fr); +#ifdef LIMIT_TABLING + SgFr_state(sg_fr)++; /* complete --> complete_in_use */ + remove_from_global_sg_fr_list(sg_fr); + TRAIL_FRAME(sg_fr); +#endif /* LIMIT_TABLING */ if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) { /* load answers from the trie */ if(TrNode_child(ans_node) != NULL) { @@ -1567,7 +1596,7 @@ } else { /* execute compiled code from the trie */ LOCK(SgFr_lock(sg_fr)); - if (SgFr_state(sg_fr) == complete) + if (SgFr_state(sg_fr) < compiled) update_answer_trie(sg_fr); UNLOCK(SgFr_lock(sg_fr)); PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr)); diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index 8a241cb0e..bcecc37ae 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: tab.macros.h - version: $Id: tab.macros.h,v 1.17 2005-08-01 15:40:38 ricroc Exp $ + version: $Id: tab.macros.h,v 1.18 2005-08-04 15:45:55 ricroc Exp $ **********************************************************************/ @@ -232,7 +232,7 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p ALLOC_SUBGOAL_FRAME(SG_FR); \ INIT_LOCK(SgFr_lock(SG_FR)); \ SgFr_code(SG_FR) = CODE; \ - SgFr_state(SG_FR) = start; \ + SgFr_state(SG_FR) = ready; \ new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \ SgFr_hash_chain(SG_FR) = NULL; \ SgFr_answer_trie(SG_FR) = ans_node; \ @@ -321,6 +321,35 @@ STD_PROTO(static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames, (tg_sol_fr_p AnsHash_init_next_field(HASH, SG_FR) +#ifdef LIMIT_TABLING +#define insert_into_global_sg_fr_list(SG_FR) \ + SgFr_previous(SG_FR) = GLOBAL_last_sg_fr; \ + SgFr_next(SG_FR) = NULL; \ + if (GLOBAL_first_sg_fr == NULL) \ + GLOBAL_first_sg_fr = SG_FR; \ + else \ + SgFr_next(GLOBAL_last_sg_fr) = SG_FR; \ + GLOBAL_last_sg_fr = SG_FR +#define remove_from_global_sg_fr_list(SG_FR) \ + if (SgFr_previous(SG_FR)) { \ + if ((SgFr_next(SgFr_previous(SG_FR)) = SgFr_next(SG_FR)) != NULL) \ + SgFr_previous(SgFr_next(SG_FR)) = SgFr_previous(SG_FR); \ + else \ + GLOBAL_last_sg_fr = SgFr_previous(SG_FR); \ + } else { \ + if ((GLOBAL_first_sg_fr = SgFr_next(SG_FR)) != NULL) \ + SgFr_previous(SgFr_next(SG_FR)) = NULL; \ + else \ + GLOBAL_last_sg_fr = NULL; \ + } \ + if (GLOBAL_check_sg_fr == SG_FR) \ + GLOBAL_check_sg_fr = SgFr_previous(SG_FR) +#else +#define insert_into_global_sg_fr_list(SG_FR) +#define remove_from_global_sg_fr_list(SG_FR) +#endif /* LIMIT_TABLING */ + + /* ------------------------- ** ** Inline funcions ** @@ -516,28 +545,37 @@ void abolish_incomplete_subgoals(choiceptr prune_cp) { sg_fr = LOCAL_top_sg_fr; LOCAL_top_sg_fr = SgFr_next(sg_fr); LOCK(SgFr_lock(sg_fr)); - if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) { - /* yes answer --> complete */ - SgFr_state(sg_fr) = complete; + if (SgFr_first_answer(sg_fr) == NULL) { + /* no answers --> ready */ + SgFr_state(sg_fr) = ready; UNLOCK(SgFr_lock(sg_fr)); } else { + if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) { + /* yes answer --> complete */ + SgFr_state(sg_fr) = complete; + UNLOCK(SgFr_lock(sg_fr)); + } else { + /* answers --> incomplete/ready */ #ifdef INCOMPLETE_TABLING - SgFr_state(sg_fr) = start; - UNLOCK(SgFr_lock(sg_fr)); + SgFr_state(sg_fr) = incomplete; + UNLOCK(SgFr_lock(sg_fr)); #else - ans_node_ptr node; - SgFr_state(sg_fr) = start; - free_answer_hash_chain(SgFr_hash_chain(sg_fr)); - SgFr_first_answer(sg_fr) = NULL; - SgFr_last_answer(sg_fr) = NULL; - SgFr_hash_chain(sg_fr) = NULL; - node = TrNode_child(SgFr_answer_trie(sg_fr)); - TrNode_child(SgFr_answer_trie(sg_fr)) = NULL; - UNLOCK(SgFr_lock(sg_fr)); - if (node) + ans_node_ptr node; + 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; + 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); #endif /* INCOMPLETE_TABLING */ + } } +#ifdef LIMIT_TABLING + insert_into_global_sg_fr_list(sg_fr); +#endif /* LIMIT_TABLING */ } return; diff --git a/OPTYap/tab.structs.h b/OPTYap/tab.structs.h index 3b2fca9ec..b8ce36660 100644 --- a/OPTYap/tab.structs.h +++ b/OPTYap/tab.structs.h @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: tab.structs.h - version: $Id: tab.structs.h,v 1.9 2005-08-01 15:40:39 ricroc Exp $ + version: $Id: tab.structs.h,v 1.10 2005-08-04 15:45:56 ricroc Exp $ **********************************************************************/ @@ -25,9 +25,9 @@ #define SetMode_SchedulingOn(X) (X) |= Mode_SchedulingOn #define SetMode_CompletedOn(X) (X) |= Mode_CompletedOn #define IsMode_SchedulingOn(X) ((X) & Mode_SchedulingOn) -#define IsMode_SchedulingOff(X) !IsMode_SchedulingOn(X) +#define IsMode_SchedulingOff(X) (!IsMode_SchedulingOn(X)) #define IsMode_CompletedOn(X) ((X) & Mode_CompletedOn) -#define IsMode_CompletedOff(X) !IsMode_CompletedOn(X) +#define IsMode_CompletedOff(X) (!IsMode_CompletedOn(X)) #define SetMode_Local(X) (X) |= Mode_Local #define SetMode_Batched(X) (X) &= ~Mode_Local @@ -156,11 +156,14 @@ typedef struct subgoal_frame { #endif /* YAPOR */ yamop *code_of_subgoal; enum { - start = 0, - evaluating = 1, - complete = 2, - compiled = 3 - } state_flag; + incomplete = 0, /* INCOMPLETE_TABLING */ + ready = 1, + evaluating = 2, + complete = 3, + complete_in_use = 4, /* LIMIT_TABLING */ + compiled = 5, + compiled_in_use = 6 /* LIMIT_TABLING */ + } state_flag; /* do not change order !!! */ choiceptr generator_choice_point; struct answer_hash *hash_chain; struct answer_trie_node *answer_trie; @@ -169,6 +172,9 @@ typedef struct subgoal_frame { #ifdef INCOMPLETE_TABLING struct answer_trie_node *try_answer; #endif /* INCOMPLETE_TABLING */ +#ifdef LIMIT_TABLING + struct subgoal_frame *previous; +#endif /* LIMIT_TABLING */ struct subgoal_frame *next; } *sg_fr_ptr; @@ -185,6 +191,7 @@ typedef struct subgoal_frame { #define SgFr_first_answer(X) ((X)->first_answer) #define SgFr_last_answer(X) ((X)->last_answer) #define SgFr_try_answer(X) ((X)->try_answer) +#define SgFr_previous(X) ((X)->previous) #define SgFr_next(X) ((X)->next) /* ------------------------------------------------------------------------------------------- ** @@ -207,7 +214,8 @@ typedef struct subgoal_frame { SgFr_try_answer: a pointer to the bottom answer trie node of the last tried answer. It is used when a subgoal was not completed during the previous evaluation. Not completed subgoals start by trying the answers already found. - SgFr_next: a pointer to chain between subgoal frames. + SgFr_previous: a pointer to the previous subgoal frame on the chain. + SgFr_next: a pointer to the next subgoal frame on the chain. ** ------------------------------------------------------------------------------------------- */ @@ -258,7 +266,7 @@ typedef struct dependency_frame { DepFr_leader_cp: a pointer to the leader choice point. DepFr_cons_cp: a pointer to the correspondent consumer choice point. DepFr_last_answer: a pointer to the last consumed answer. - DepFr_next: a pointer to chain between dependency frames. + DepFr_next: a pointer to the next dependency frame on the chain. ** ---------------------------------------------------------------------------------------------------- */ diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index e36bdf0b0..ab986a3df 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -5,7 +5,7 @@ Copyright: R. Rocha and NCC - University of Porto, Portugal File: tab.tries.C - version: $Id: tab.tries.c,v 1.15 2005-08-01 15:40:39 ricroc Exp $ + version: $Id: tab.tries.c,v 1.16 2005-08-04 15:45:56 ricroc Exp $ **********************************************************************/ @@ -946,12 +946,26 @@ void load_answer_trie(ans_node_ptr ans_node, CELL *subs_ptr) { void private_completion(sg_fr_ptr sg_fr) { /* complete subgoals */ - mark_as_completed(LOCAL_top_sg_fr); +#ifdef LIMIT_TABLING + sg_fr_ptr aux_sg_fr; while (LOCAL_top_sg_fr != sg_fr) { - LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); - mark_as_completed(LOCAL_top_sg_fr); + aux_sg_fr = LOCAL_top_sg_fr; + LOCAL_top_sg_fr = SgFr_next(aux_sg_fr); + mark_as_completed(aux_sg_fr); + insert_into_global_sg_fr_list(aux_sg_fr); } + aux_sg_fr = LOCAL_top_sg_fr; + LOCAL_top_sg_fr = SgFr_next(aux_sg_fr); + mark_as_completed(aux_sg_fr); + insert_into_global_sg_fr_list(aux_sg_fr); +#else + while (LOCAL_top_sg_fr != sg_fr) { + mark_as_completed(LOCAL_top_sg_fr); + LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); + } + mark_as_completed(LOCAL_top_sg_fr); LOCAL_top_sg_fr = SgFr_next(LOCAL_top_sg_fr); +#endif /* LIMIT_TABLING */ /* release dependency frames */ while (EQUAL_OR_YOUNGER_CP(DepFr_cons_cp(LOCAL_top_dep_fr), B)) { /* never equal if batched scheduling */ @@ -994,6 +1008,9 @@ void free_subgoal_trie_branch(sg_node_ptr node, int missing_nodes) { if (TrNode_child(ans_node)) free_answer_trie_branch(TrNode_child(ans_node)); FREE_ANSWER_TRIE_NODE(ans_node); +#ifdef LIMIT_TABLING + remove_from_global_sg_fr_list(sg_fr); +#endif /* LIMIT_TABLING */ FREE_SUBGOAL_FRAME(sg_fr); } @@ -1030,7 +1047,7 @@ void update_answer_trie(sg_fr_ptr sg_fr) { update_answer_trie_branch(node); #endif /* TABLING_INNER_CUTS */ } - SgFr_state(sg_fr) = compiled; + SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */ return; } @@ -1038,7 +1055,7 @@ void update_answer_trie(sg_fr_ptr sg_fr) { static struct trie_statistics{ int show; long subgoals; - long subgoals_not_complete; + long subgoals_incomplete; long subgoal_trie_nodes; long subgoal_linear_nodes; int subgoal_trie_max_depth; @@ -1054,7 +1071,7 @@ static struct trie_statistics{ } trie_stats; #define TrStat_show trie_stats.show #define TrStat_subgoals trie_stats.subgoals -#define TrStat_sg_not_complete trie_stats.subgoals_not_complete +#define TrStat_sg_incomplete trie_stats.subgoals_incomplete #define TrStat_sg_nodes trie_stats.subgoal_trie_nodes #define TrStat_sg_linear_nodes trie_stats.subgoal_linear_nodes #define TrStat_sg_max_depth trie_stats.subgoal_trie_max_depth @@ -1078,7 +1095,7 @@ int traverse_table(tab_ent_ptr tab_ent, Atom pred_atom, int show_table) { TrStat_show = show_table; TrStat_subgoals = 0; - TrStat_sg_not_complete = 0; + TrStat_sg_incomplete = 0; TrStat_sg_nodes = 1; TrStat_sg_linear_nodes = 0; TrStat_sg_max_depth = -1; @@ -1107,7 +1124,7 @@ int traverse_table(tab_ent_ptr tab_ent, Atom pred_atom, int show_table) { void table_stats(void) { fprintf(Yap_stderr, "\n Subgoal trie structure"); fprintf(Yap_stderr, "\n subgoals: %ld", TrStat_subgoals); - fprintf(Yap_stderr, "\n subgoals not complete: %ld", TrStat_sg_not_complete); + fprintf(Yap_stderr, "\n subgoals incomplete: %ld", TrStat_sg_incomplete); fprintf(Yap_stderr, "\n nodes: %ld (%ld%c saving)", TrStat_sg_nodes, TrStat_sg_linear_nodes == 0 ? 0 : (TrStat_sg_linear_nodes - TrStat_sg_nodes + 1) * 100 / TrStat_sg_linear_nodes, @@ -1434,9 +1451,9 @@ int traverse_subgoal_trie(sg_node_ptr sg_node, char *str, int str_index, int *ar } else if (depth > TrStat_sg_max_depth) { TrStat_sg_max_depth = depth; } - if (SgFr_state(sg_fr) == start || SgFr_state(sg_fr) == evaluating) { - TrStat_sg_not_complete++; - SHOW_TABLE("%s. ---> NOT COMPLETE\n", str); + if (SgFr_state(sg_fr) < complete) { + TrStat_sg_incomplete++; + SHOW_TABLE("%s. ---> INCOMPLETE\n", str); } else { SHOW_TABLE("%s.\n", str); } diff --git a/console/yap.c b/console/yap.c index d93e2f5fb..d52b4715b 100644 --- a/console/yap.c +++ b/console/yap.c @@ -236,16 +236,19 @@ print_usage(void) DefStackSpace, MinStackSpace); fprintf(stderr," -t Trail area in Kbytes (default: %d, minimum: %d)\n", DefTrailSpace, MinTrailSpace); +#ifdef TABLING + fprintf(stderr," -ts Maximum table space area in Mbytes (default: unlimited)\n"); +#endif /* TABLING */ #ifdef YAPOR - fprintf(stderr," -w YapOr option: Number of workers (default: %d)\n", + fprintf(stderr," -w Number of workers (default: %d)\n", DEFAULT_NUMBERWORKERS); - fprintf(stderr," -sl YapOr option: Loop scheduler executions before look for hiden shared work (default: %d)\n", DEFAULT_SCHEDULERLOOP); - - /*nf: Preprocessor */ - fprintf(stderr," -DVar=Name : persistent definition\n"); - fprintf(stderr," -d YapOr option: Value of delayed release of load (default: %d)\n", + fprintf(stderr," -sl Loop scheduler executions before look for hiden shared work (default: %d)\n", + DEFAULT_SCHEDULERLOOP); + fprintf(stderr," -d Value of delayed release of load (default: %d)\n", DEFAULT_DELAYEDRELEASELOAD); -#endif + /* nf: Preprocessor */ + fprintf(stderr," -DVar=Name : persistent definition\n"); +#endif /* YAPOR */ fprintf(stderr,"\n"); } @@ -354,6 +357,10 @@ parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) case 't': case 'T': ssize = &(iap->TrailSize); + if (p[1] == 's') { + p++; + ssize = &(iap->MaxTableSpaceSize); + } GetSize: if (*++p == '\0') { @@ -473,6 +480,7 @@ init_standard_system(int argc, char *argv[], YAP_init_args *iap) iap->YapPrologRCFile = NULL; iap->HaltAfterConsult = FALSE; iap->FastBoot = FALSE; + iap->MaxTableSpaceSize = 0; iap->NumberWorkers = DEFAULT_NUMBERWORKERS; iap->SchedulerLoop = DEFAULT_SCHEDULERLOOP; iap->DelayedReleaseLoad = DEFAULT_DELAYEDRELEASELOAD; diff --git a/include/yap_structs.h b/include/yap_structs.h index d4eaf04cf..7f1a4ae01 100644 --- a/include/yap_structs.h +++ b/include/yap_structs.h @@ -87,6 +87,9 @@ typedef struct { int HaltAfterConsult; /* ignore .yaprc, .prolog.ini, etc. files. */ int FastBoot; + /* the next field only interest YAPTAB */ + /* if NON-0, maximum size for Table Space */ + int MaxTableSpaceSize; /* the next three fields only interest YAPOR, but we keep them so that users don't need to recompile DLL in order to use YAPOR */ /* if NON-0, number of workers we want to have (default=1) */