diff --git a/OPTYap/opt.init.c b/OPTYap/opt.init.c index 1875eb32d..a59541952 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.11 2005-08-05 14:55:03 vsc Exp $ + version: $Id: opt.init.c,v 1.12 2005-08-10 21:36:34 ricroc Exp $ **********************************************************************/ @@ -66,7 +66,10 @@ void init_global(int max_table_size, int n_workers, int sch_loop, int delay_load /* global data related to memory management */ #ifdef LIMIT_TABLING - GLOBAL_MAX_PAGES = max_table_size * 1024 * 1024 / Yap_page_size; + if (max_table_size) + GLOBAL_MAX_PAGES = ((max_table_size - 1) * 1024 * 1024 / SHMMAX + 1) * SHMMAX / Yap_page_size; + else + GLOBAL_MAX_PAGES = -1; #endif /* LIMIT_TABLING */ INIT_PAGES(GLOBAL_PAGES_void, void *); #ifdef YAPOR diff --git a/OPTYap/opt.macros.h b/OPTYap/opt.macros.h index 37e89c4b7..30335da77 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.9 2005-08-04 15:45:55 ricroc Exp $ + version: $Id: opt.macros.h,v 1.10 2005-08-10 21:36:34 ricroc Exp $ **********************************************************************/ @@ -72,16 +72,53 @@ extern int Yap_page_size; Yap_FreeCodeSpace((char *) (STR)) #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; \ +#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 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, "table space full (CHECK_TABLE_LIMIT)"); \ + 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); */ \ @@ -96,47 +133,105 @@ extern int Yap_page_size; 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); \ + } while (Pg_free_pg(GLOBAL_PAGES_void) == Pg_free_pg(STR_PAGES)); \ GLOBAL_check_sg_fr = sg_fr; \ - } else -#else -#define CHECK_TABLE_LIMIT -#endif /* LIMIT_TABLING */ + } +#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)); \ + } \ + 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) { \ - 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); \ + 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; \ - UNLOCK(Pg_lock(GLOBAL_PAGES_void)) - #define ALLOC_STRUCT(STR, STR_PAGES, STR_TYPE) \ { pg_hd_ptr pg_hd; \ LOCK(Pg_lock(STR_PAGES)); \ @@ -204,6 +299,14 @@ extern int Yap_page_size; } \ } \ 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; \ + UNLOCK(Pg_lock(GLOBAL_PAGES_void)) #define FREE_STRUCT(STR, STR_PAGES, STR_TYPE) \ { pg_hd_ptr pg_hd; \ diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index 1f4663bae..f0a99de32 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.24 2005-08-04 15:45:55 ricroc Exp $ + version: $Id: opt.preds.c,v 1.25 2005-08-10 21:36:34 ricroc Exp $ **********************************************************************/ @@ -540,18 +540,18 @@ int p_table(void) { arity = ArityOfFunctor(func); } else return (FALSE); - if (pe->cs.p_code.FirstClause) /* predicate already defined */ - return (FALSE); - if (!(pe->PredFlags & TabledPredFlag)) { - pe->PredFlags |= TabledPredFlag; - new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); - new_table_entry(tab_ent, pe, arity, sg_node); - if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) - SetMode_Local(TabEnt_mode(tab_ent)); - if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) - SetMode_LoadAnswers(TabEnt_mode(tab_ent)); - pe->TableOfPred = tab_ent; - } + if (pe->PredFlags & TabledPredFlag) + return (TRUE); /* predicate already tabled */ + if (pe->cs.p_code.FirstClause) + return (FALSE); /* predicate already compiled */ + pe->PredFlags |= TabledPredFlag; + new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); + new_table_entry(tab_ent, pe, arity, sg_node); + if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) + SetMode_Local(TabEnt_mode(tab_ent)); + if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) + SetMode_LoadAnswers(TabEnt_mode(tab_ent)); + pe->TableOfPred = tab_ent; return (TRUE); }