TABLING FIX: recover unused space algorithm

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1359 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
ricroc 2005-08-10 21:36:34 +00:00
parent 97af65a510
commit d12421405c
3 changed files with 155 additions and 49 deletions

View File

@ -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

View File

@ -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; \

View File

@ -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);
}