diff --git a/OPTYap/opt.config.h b/OPTYap/opt.config.h index e43cfd17f..4e28b927c 100644 --- a/OPTYap/opt.config.h +++ b/OPTYap/opt.config.h @@ -20,13 +20,12 @@ /****************************************************************************************** ** use shared pages memory alloc scheme for OPTYap data structures? (optional) ** ******************************************************************************************/ - /* #define USE_PAGES_MALLOC 1 */ /************************************************************************ -** TABLING Configuration Parameters ** +** Tabling Configuration Parameters ** ************************************************************************/ /**************************** @@ -43,7 +42,7 @@ /********************************************************* ** support mode directed tabling ? (optional) ** *********************************************************/ -/* #define MODE_DIRECTED_TABLING 1 */ +#define MODE_DIRECTED_TABLING 1 /**************************************************** ** support early completion ? (optional) ** @@ -83,7 +82,7 @@ /************************************************************************ -** YAPOR Configuration Parameters ** +** YapOr Configuration Parameters ** ************************************************************************/ /**************************** @@ -107,42 +106,57 @@ /************************************************************************ -** OPTYAP Configuration Parameters ** +** OPTYap Configuration Parameters ** ************************************************************************/ /**************************** ** default sizes ** ****************************/ -#define TABLE_LOCK_BUCKETS 512 #define TG_ANSWER_SLOTS 20 +#define TRIE_LOCK_BUCKETS 512 -/*********************************************************** -** tries locking scheme (mandatory, define one) ** -************************************************************ -** The TABLE_LOCK_AT_ENTRY_LEVEL scheme locks the access ** -** to the table space in the entry data structure. It ** -** restricts the number of lock operations needed to go ** -** through the table data structures. ** -** ** -** The TABLE_LOCK_AT_NODE_LEVEL scheme locks each data ** -** structure before accessing it. It decreases ** -** concurrrency for workers accessing commom parts of the ** -** table space. ** -** ** -** The TABLE_LOCK_AT_WRITE_LEVEL scheme is an hibrid ** -** scheme, it only locks a table data structure when it ** -** is going to update it. You can use ALLOC_BEFORE_CHECK ** -** with this scheme to allocate a node before checking ** -** if it will be necessary. ** -***********************************************************/ -/* #define TABLE_LOCK_AT_ENTRY_LEVEL 1 */ -/* #define TABLE_LOCK_AT_NODE_LEVEL 1 */ -#define TABLE_LOCK_AT_WRITE_LEVEL 1 -/* #define ALLOC_BEFORE_CHECK 1 */ +/************************************************************************* +** tries locking scheme (mandatory, define one per trie type) ** +************************************************************************** +** The (TRIE_TYPE)_LOCK_AT_ENTRY_LEVEL scheme locks the access to the ** +** table space in the entry data structure. It restricts the number of ** +** lock operations needed to go through the table data structures. ** +** ** +** The (TRIE_TYPE)_LOCK_AT_NODE_LEVEL scheme locks each data structure ** +** before accessing it. It decreases concurrrency for workers accessing ** +** commom parts of the table space. ** +** ** +** The (TRIE_TYPE)_LOCK_AT_WRITE_LEVEL scheme is an hibrid scheme, it ** +** only locks a table data structure when it is going to update it. You ** +** can use (TRIE_TYPE)_ALLOC_BEFORE_CHECK with this scheme to allocate ** +** a node before checking if it will be necessary. ** +*************************************************************************/ +/* #define SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL 1 */ +#define SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL 1 +/* #define SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL 1 */ +/* #define SUBGOAL_TRIE_ALLOC_BEFORE_CHECK 1 */ -/********************************************** -** support inner cuts ? (optional) ** -**********************************************/ +/* #define ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL 1 */ +#define ANSWER_TRIE_LOCK_AT_NODE_LEVEL 1 +/* #define ANSWER_TRIE_LOCK_AT_WRITE_LEVEL 1 */ +/* #define ANSWER_TRIE_ALLOC_BEFORE_CHECK 1 */ + +#define GLOBAL_TRIE_LOCK_AT_NODE_LEVEL 1 +/* #define GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL 1 */ +/* #define GLOBAL_TRIE_ALLOC_BEFORE_CHECK 1 */ + +/******************************************************************* +** tries locking data structure (mandatory, define one) ** +******************************************************************** +** Data structure to be used for locking the trie when using the ** +** (TRIE_TYPE)_LOCK_AT_[NODE|WRITE]_LEVEL schemes ** +*******************************************************************/ +#define TRIE_LOCK_USING_NODE_FIELD 1 +/* #define TRIE_LOCK_USING_GLOBAL_ARRAY 1 */ + +/****************************************************** +** support tabling inner cuts ? (optional) ** +******************************************************/ #define TABLING_INNER_CUTS 1 /********************************************************* @@ -158,73 +172,138 @@ #ifndef USE_PAGES_MALLOC #undef LIMIT_TABLING -#endif /* !USE_PAGES_MALLOC */ +#endif /* ! USE_PAGES_MALLOC */ + + +#ifdef TABLING +#if !defined(BFZ_TRAIL_SCHEME) && !defined(BBREG_TRAIL_SCHEME) +#error Define a trail scheme +#endif +#if defined(BFZ_TRAIL_SCHEME) && defined(BBREG_TRAIL_SCHEME) +#error Do not define multiple trail schemes +#endif +#else /* ! TABLING */ +#undef BFZ_TRAIL_SCHEME +#undef BBREG_TRAIL_SCHEME +#undef MODE_DIRECTED_TABLING +#undef TABLING_EARLY_COMPLETION +#undef TRIE_COMPACT_PAIRS +#undef GLOBAL_TRIE_FOR_SUBTERMS +#undef INCOMPLETE_TABLING +#undef LIMIT_TABLING +#undef DETERMINISTIC_TABLING +#undef DEBUG_TABLING +#endif /* TABLING */ + #ifdef YAPOR #ifdef i386 /* For i386 machines we use shared memory segments */ #undef MMAP_MEMORY_MAPPING_SCHEME #define SHM_MEMORY_MAPPING_SCHEME -#endif /* i386 */ +#endif #if !defined(MMAP_MEMORY_MAPPING_SCHEME) && !defined(SHM_MEMORY_MAPPING_SCHEME) #error Define a memory mapping scheme -#endif /* !MMAP_MEMORY_MAPPING_SCHEME && !SHM_MEMORY_MAPPING_SCHEME */ +#endif #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 */ +#endif #undef LIMIT_TABLING +#else /* ! YAPOR */ +#undef MMAP_MEMORY_MAPPING_SCHEME +#undef SHM_MEMORY_MAPPING_SCHEME +#undef DEBUG_YAPOR #endif /* YAPOR */ -#ifdef TABLING -#if !defined(BFZ_TRAIL_SCHEME) && !defined(BBREG_TRAIL_SCHEME) -#error Define a trail scheme -#endif /* !BFZ_TRAIL_SCHEME && !BBREG_TRAIL_SCHEME */ -#if defined(BFZ_TRAIL_SCHEME) && defined(BBREG_TRAIL_SCHEME) -#error Do not define multiple trail schemes -#endif /* BFZ_TRAIL_SCHEME && BBREG_TRAIL_SCHEME */ -#endif /* TABLING */ #if defined(YAPOR) && defined(TABLING) -#if !defined(TABLE_LOCK_AT_ENTRY_LEVEL) && !defined(TABLE_LOCK_AT_NODE_LEVEL) && !defined(TABLE_LOCK_AT_WRITE_LEVEL) -#error Define a table lock scheme -#endif /* !TABLE_LOCK_AT_ENTRY_LEVEL && !TABLE_LOCK_AT_NODE_LEVEL && !TABLE_LOCK_AT_WRITE_LEVEL */ -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) -#if defined(TABLE_LOCK_AT_NODE_LEVEL) || defined(TABLE_LOCK_AT_WRITE_LEVEL) -#error Do not define multiple table lock schemes -#endif /* TABLE_LOCK_AT_NODE_LEVEL || TABLE_LOCK_AT_WRITE_LEVEL */ -#endif /* TABLE_LOCK_AT_ENTRY_LEVEL */ -#if defined(TABLE_LOCK_AT_NODE_LEVEL) && defined(TABLE_LOCK_AT_WRITE_LEVEL) -#error Do not define multiple table lock schemes -#endif /* TABLE_LOCK_AT_NODE_LEVEL || TABLE_LOCK_AT_WRITE_LEVEL */ -#ifndef TABLE_LOCK_AT_WRITE_LEVEL -#undef ALLOC_BEFORE_CHECK -#endif /* !TABLE_LOCK_AT_WRITE_LEVEL */ -#else -#undef TABLE_LOCK_AT_ENTRY_LEVEL -#undef TABLE_LOCK_AT_NODE_LEVEL -#undef TABLE_LOCK_AT_WRITE_LEVEL -#undef ALLOC_BEFORE_CHECK -#endif /* YAPOR && TABLING */ - -#if !defined(TABLING) || !defined(YAPOR) +/* SUBGOAL_TRIE_LOCK_LEVEL */ +#if !defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && !defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) && !defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL) +#error Define a subgoal trie lock scheme +#endif +#if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) +#error Do not define multiple subgoal trie lock schemes +#endif +#if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL) +#error Do not define multiple subgoal trie lock schemes +#endif +#if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) && defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL) +#error Do not define multiple subgoal trie lock schemes +#endif +#ifndef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL +#undef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK +#endif +/* ANSWER_TRIE_LOCK_LEVEL */ +#if !defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && !defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) && !defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL) +#error Define a answer trie lock scheme +#endif +#if defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) +#error Do not define multiple answer trie lock schemes +#endif +#if defined(ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL) +#error Do not define multiple answer trie lock schemes +#endif +#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) && defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL) +#error Do not define multiple answer trie lock schemes +#endif +#ifndef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL +#undef ANSWER_TRIE_ALLOC_BEFORE_CHECK +#endif +/* GLOBAL_TRIE_LOCK_LEVEL */ +#if !defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) && !defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL) +#error Define a global trie lock scheme +#endif +#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) && defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL) +#error Do not define multiple global trie lock schemes +#endif +#ifndef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL +#undef GLOBAL_TRIE_ALLOC_BEFORE_CHECK +#endif +/* TRIE_LOCK_USING_NODE_FIELD / TRIE_LOCK_USING_GLOBAL_ARRAY */ +#if !defined(TRIE_LOCK_USING_NODE_FIELD) && !defined(TRIE_LOCK_USING_GLOBAL_ARRAY) +#error Define a trie lock data structure +#endif +#if defined(TRIE_LOCK_USING_NODE_FIELD) && defined(TRIE_LOCK_USING_GLOBAL_ARRAY) +#error Do not define multiple trie lock data structures +#endif +#ifdef TRIE_LOCK_USING_NODE_FIELD +#if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL) +#define SUBGOAL_TRIE_LOCK_USING_NODE_FIELD 1 +#endif +#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) || defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL) +#define ANSWER_TRIE_LOCK_USING_NODE_FIELD 1 +#endif +#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL) +#define GLOBAL_TRIE_LOCK_USING_NODE_FIELD 1 +#endif +#elif TRIE_LOCK_USING_GLOBAL_ARRAY +#if defined(SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL) +#define SUBGOAL_TRIE_LOCK_USING_GLOBAL_ARRAY 1 +#endif +#if defined(ANSWER_TRIE_LOCK_AT_NODE_LEVEL) || defined(ANSWER_TRIE_LOCK_AT_WRITE_LEVEL) +#define ANSWER_TRIE_LOCK_USING_GLOBAL_ARRAY 1 +#endif +#if defined(GLOBAL_TRIE_LOCK_AT_NODE_LEVEL) || defined(GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL) +#define GLOBAL_TRIE_LOCK_USING_GLOBAL_ARRAY 1 +#endif +#endif +#else /* ! TABLING || ! YAPOR */ +#undef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL +#undef SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL +#undef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL +#undef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK +#undef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL +#undef ANSWER_TRIE_LOCK_AT_NODE_LEVEL +#undef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL +#undef ANSWER_TRIE_ALLOC_BEFORE_CHECK +#undef GLOBAL_TRIE_LOCK_AT_NODE_LEVEL +#undef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL +#undef GLOBAL_TRIE_ALLOC_BEFORE_CHECK +#undef TRIE_LOCK_USING_NODE_FIELD +#undef TRIE_LOCK_USING_GLOBAL_ARRAY #undef TABLING_INNER_CUTS #undef TIMESTAMP_CHECK -#endif /* !TABLING || !YAPOR */ +#endif /* YAPOR && TABLING */ -#ifndef YAPOR -#undef DEBUG_YAPOR -#endif /* !YAPOR */ - -#ifndef TABLING -#undef BFZ_TRAIL_SCHEME -#undef BBREG_TRAIL_SCHEME -#undef TABLING_EARLY_COMPLETION -#undef TRIE_COMPACT_PAIRS -#undef GLOBAL_TRIE_FOR_SUBTERMS -#undef DETERMINISTIC_TABLING -#undef LIMIT_TABLING -#undef INCOMPLETE_TABLING -#undef DEBUG_TABLING -#endif /* !TABLING */ #if defined(DEBUG_YAPOR) && defined(DEBUG_TABLING) #define DEBUG_OPTYAP diff --git a/OPTYap/opt.init.c b/OPTYap/opt.init.c index e7104482d..e7b982e0c 100644 --- a/OPTYap/opt.init.c +++ b/OPTYap/opt.init.c @@ -147,10 +147,10 @@ void Yap_init_global_optyap_data(int max_table_size, int n_workers, int sch_loop CELL *pt = GLOBAL_table_var_enumerator_addr(i); RESET_VARIABLE(pt); } -#ifdef TABLE_LOCK_AT_WRITE_LEVEL - for (i = 0; i < TABLE_LOCK_BUCKETS; i++) - INIT_LOCK(GLOBAL_table_lock(i)); -#endif /* TABLE_LOCK_AT_WRITE_LEVEL */ +#ifdef TRIE_LOCK_USING_GLOBAL_ARRAY + for (i = 0; i < TRIE_LOCK_BUCKETS; i++) + INIT_LOCK(GLOBAL_trie_locks(i)); +#endif /* TRIE_LOCK_USING_GLOBAL_ARRAY */ #endif /* TABLING */ return; diff --git a/OPTYap/opt.preds.c b/OPTYap/opt.preds.c index c50113369..06ecb77f2 100644 --- a/OPTYap/opt.preds.c +++ b/OPTYap/opt.preds.c @@ -255,7 +255,7 @@ static Int p_table( USES_REGS1 ) { pos_agreg = pos_index; pos_index = 0; for (i = 0; i < arity; i++) { - int aux_pos; + int aux_pos = 0; if (aux_mode_directed[i] == MODE_DIRECTED_MAX) aux_pos = pos_agreg++; else if (aux_mode_directed[i] == MODE_DIRECTED_MIN) diff --git a/OPTYap/opt.proto.h b/OPTYap/opt.proto.h index 971a5b40b..58d0fa4f5 100644 --- a/OPTYap/opt.proto.h +++ b/OPTYap/opt.proto.h @@ -45,6 +45,9 @@ void finish_yapor(void); #ifdef TABLING sg_fr_ptr subgoal_search(yamop *, CELL **); ans_node_ptr answer_search(sg_fr_ptr, CELL *); +#ifdef MODE_DIRECTED_TABLING +ans_node_ptr mode_directed_answer_search(sg_fr_ptr, CELL *); +#endif /* MODE_DIRECTED_TABLING */ void load_answer(ans_node_ptr, CELL *); CELL *exec_substitution(gt_node_ptr, CELL *); void update_answer_trie(sg_fr_ptr); diff --git a/OPTYap/opt.structs.h b/OPTYap/opt.structs.h index 9ac8bf3ee..9c5fc8719 100644 --- a/OPTYap/opt.structs.h +++ b/OPTYap/opt.structs.h @@ -213,9 +213,9 @@ struct global_optyap_data { struct dependency_frame *root_dependency_frame; #endif /* YAPOR */ CELL table_var_enumerator[MAX_TABLE_VARS]; -#ifdef TABLE_LOCK_AT_WRITE_LEVEL - lockvar table_lock[TABLE_LOCK_BUCKETS]; -#endif /* TABLE_LOCK_AT_WRITE_LEVEL */ +#ifdef TRIE_LOCK_USING_GLOBAL_ARRAY + lockvar trie_locks[TRIE_LOCK_BUCKETS]; +#endif /* TRIE_LOCK_USING_GLOBAL_ARRAY */ #ifdef TIMESTAMP_CHECK long timestamp; #endif /* TIMESTAMP_CHECK */ @@ -282,7 +282,7 @@ struct global_optyap_data { #define GLOBAL_root_dep_fr (GLOBAL_optyap_data.root_dependency_frame) #define GLOBAL_table_var_enumerator(index) (GLOBAL_optyap_data.table_var_enumerator[index]) #define GLOBAL_table_var_enumerator_addr(index) (GLOBAL_optyap_data.table_var_enumerator + (index)) -#define GLOBAL_table_lock(index) (GLOBAL_optyap_data.table_lock[index]) +#define GLOBAL_trie_locks(index) (GLOBAL_optyap_data.trie_locks[index]) #define GLOBAL_timestamp (GLOBAL_optyap_data.timestamp) diff --git a/OPTYap/tab.insts.i b/OPTYap/tab.insts.i index 1ce06fd17..e8e35bc9f 100644 --- a/OPTYap/tab.insts.i +++ b/OPTYap/tab.insts.i @@ -865,19 +865,19 @@ } } #endif /* DEBUG_TABLING && !DETERMINISTIC_TABLING */ -#ifdef TABLE_LOCK_AT_ENTRY_LEVEL - LOCK(SgFr_lock(sg_fr)); -#endif /* TABLE_LOCK_LEVEL */ - ans_node = answer_search(sg_fr, subs_ptr); + LOCK_ANSWER_TRIE(sg_fr); #ifdef MODE_DIRECTED_TABLING - if (ans_node == NULL) /* no answer inserted */ - goto fail; + if (SgFr_mode_directed(sg_fr)) { + ans_node = mode_directed_answer_search(sg_fr, subs_ptr); + if (ans_node == NULL) { + /* no answer inserted */ + UNLOCK_ANSWER_TRIE(sg_fr); + goto fail; + } + } else #endif /* MODE_DIRECTED_TABLING */ -#if defined(TABLE_LOCK_AT_NODE_LEVEL) - LOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - LOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + ans_node = answer_search(sg_fr, subs_ptr); + LOCK_ANSWER_NODE(ans_node); if (! IS_ANSWER_LEAF_NODE(ans_node)) { /* new answer */ #ifdef TABLING_INNER_CUTS @@ -903,13 +903,8 @@ EQUAL_OR_YOUNGER_CP(Get_LOCAL_top_cp(), REMOTE_pruning_scope(i))) { leftmost_or_fr = LOCAL_top_or_fr; pending_table_new_answer: -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - UNLOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + UNLOCK_ANSWER_NODE(ans_node); + UNLOCK_ANSWER_TRIE(sg_fr); LOCK_OR_FRAME(leftmost_or_fr); if (Get_LOCAL_prune_request()) { UNLOCK_OR_FRAME(leftmost_or_fr); @@ -996,24 +991,16 @@ /* check for prune requests */ if (Get_LOCAL_prune_request()) { -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - UNLOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + UNLOCK_ANSWER_NODE(ans_node); + UNLOCK_ANSWER_TRIE(sg_fr); SCHEDULER_GET_WORK(); } #endif /* TABLING_INNER_CUTS */ TAG_AS_ANSWER_LEAF_NODE(ans_node); -#if defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(ans_node)); + UNLOCK_ANSWER_NODE(ans_node); +#ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL LOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(ans_node); - LOCK(SgFr_lock(sg_fr)); -#endif /* TABLE_LOCK_LEVEL */ +#endif /* ! ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */ if (SgFr_first_answer(sg_fr) == NULL) SgFr_first_answer(sg_fr) = ans_node; else @@ -1072,13 +1059,8 @@ } } else { /* repeated answer */ -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - UNLOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + UNLOCK_ANSWER_NODE(ans_node); + UNLOCK_ANSWER_TRIE(sg_fr); goto fail; } ENDPBOp(); @@ -1111,18 +1093,13 @@ /* unconsumed answers */ #ifdef MODE_DIRECTED_TABLING if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; + ans_node_ptr old_ans_node; + old_ans_node = ans_node; ans_node = TrNode_child(ans_node); do { ans_node = TrNode_child(ans_node); } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - do { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; - aux_ans_node = TrNode_child(first_ans_node); - } while (aux_ans_node != ans_node); + TrNode_child(old_ans_node) = ans_node; } else #endif /* MODE_DIRECTED_TABLING */ ans_node = TrNode_child(ans_node); @@ -1175,18 +1152,13 @@ /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; + ans_node_ptr old_ans_node; + old_ans_node = ans_node; ans_node = TrNode_child(ans_node); do { ans_node = TrNode_child(ans_node); } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - do { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; - aux_ans_node = TrNode_child(first_ans_node); - } while (aux_ans_node != ans_node); + TrNode_child(old_ans_node) = ans_node; } else #endif /* MODE_DIRECTED_TABLING */ ans_node = TrNode_child(ans_node); @@ -1434,18 +1406,13 @@ /* dependency frame with unconsumed answers */ #ifdef MODE_DIRECTED_TABLING if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; + ans_node_ptr old_ans_node; + old_ans_node = ans_node; ans_node = TrNode_child(ans_node); do { ans_node = TrNode_child(ans_node); } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - do { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; - aux_ans_node = TrNode_child(first_ans_node); - } while (aux_ans_node != ans_node); + TrNode_child(old_ans_node) = ans_node; } else #endif /* MODE_DIRECTED_TABLING */ ans_node = TrNode_child(ans_node); @@ -1609,18 +1576,13 @@ UNLOCK_OR_FRAME(LOCAL_top_or_fr); #ifdef MODE_DIRECTED_TABLING if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) { - ans_node_ptr first_ans_node, aux_ans_node; - first_ans_node = ans_node; + ans_node_ptr old_ans_node; + old_ans_node = ans_node; ans_node = TrNode_child(ans_node); do { ans_node = TrNode_child(ans_node); } while (IS_INVALID_LEAF_NODE(ans_node)); - aux_ans_node = TrNode_child(first_ans_node); - do { - TrNode_child(first_ans_node) = ans_node; - first_ans_node = aux_ans_node; - aux_ans_node = TrNode_child(first_ans_node); - } while (aux_ans_node != ans_node); + TrNode_child(old_ans_node) = ans_node; } else #endif /* MODE_DIRECTED_TABLING */ ans_node = TrNode_child(ans_node); diff --git a/OPTYap/tab.macros.h b/OPTYap/tab.macros.h index 8bfee9589..bba941a71 100644 --- a/OPTYap/tab.macros.h +++ b/OPTYap/tab.macros.h @@ -135,6 +135,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define CompactPairEndList AbsPair((Term *) (2*(LowTagBits + 1))) #endif /* TRIE_COMPACT_PAIRS */ +/* choice points */ #define NORM_CP(CP) ((choiceptr)(CP)) #define GEN_CP(CP) ((struct generator_choicept *)(CP)) #define CONS_CP(CP) ((struct consumer_choicept *)(CP)) @@ -148,6 +149,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL) #endif /* DETERMINISTIC_TABLING */ +/* leaf nodes */ #define TAG_AS_SUBGOAL_LEAF_NODE(NODE) TrNode_child(NODE) = (sg_node_ptr)((unsigned long int) TrNode_child(NODE) | 0x1) #define UNTAG_SUBGOAL_LEAF_NODE(NODE) ((sg_fr_ptr)((unsigned long int) (NODE) & ~(0x1))) #define IS_SUBGOAL_LEAF_NODE(NODE) ((unsigned long int) TrNode_child(NODE) & 0x1) @@ -157,6 +159,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define TAG_AS_INVALID_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2) #define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2) +/* trie hashes */ #define MAX_NODES_PER_TRIE_LEVEL 8 #define MAX_NODES_PER_BUCKET (MAX_NODES_PER_TRIE_LEVEL / 2) #define BASE_HASH_BUCKETS 64 @@ -167,26 +170,26 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define IS_ANSWER_TRIE_HASH(NODE) (TrNode_instr(NODE) == ANSWER_TRIE_HASH_MARK) #define GLOBAL_TRIE_HASH_MARK ((Term) MakeTableVarTerm(MAX_TABLE_VARS)) #define IS_GLOBAL_TRIE_HASH(NODE) (TrNode_entry(NODE) == GLOBAL_TRIE_HASH_MARK) +#define HASH_TRIE_LOCK(NODE) GLOBAL_trie_locks((((unsigned long int) (NODE)) >> 5) & (TRIE_LOCK_BUCKETS - 1)) -#define HASH_TABLE_LOCK(NODE) ((((unsigned long int) (NODE)) >> 5) & (TABLE_LOCK_BUCKETS - 1)) -#define LOCK_TABLE(NODE) LOCK(GLOBAL_table_lock(HASH_TABLE_LOCK(NODE))) -#define UNLOCK_TABLE(NODE) UNLOCK(GLOBAL_table_lock(HASH_TABLE_LOCK(NODE))) - -#define STACK_PUSH_UP(ITEM, STACK) *--(STACK) = (CELL)(ITEM) -#define STACK_POP_UP(STACK) *--(STACK) -#define STACK_PUSH_DOWN(ITEM, STACK) *(STACK)++ = (CELL)(ITEM) -#define STACK_POP_DOWN(STACK) *(STACK)++ -#define STACK_NOT_EMPTY(STACK, STACK_BASE) (STACK) != (STACK_BASE) -#define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) if ((STACK_LIMIT) >= (STACK)) EXPAND_AUX_STACK(STACK) -#define STACK_CHECK_EXPAND(STACK, STACK_LIMIT) if ((STACK_LIMIT) >= (STACK)+4096) EXPAND_STACK(STACK) +/* auxiliary stack */ +#define STACK_PUSH_UP(ITEM, STACK) *--(STACK) = (CELL)(ITEM) +#define STACK_POP_UP(STACK) *--(STACK) +#define STACK_PUSH_DOWN(ITEM, STACK) *(STACK)++ = (CELL)(ITEM) +#define STACK_POP_DOWN(STACK) *(STACK)++ +#define STACK_NOT_EMPTY(STACK, STACK_BASE) (STACK) != (STACK_BASE) #if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) -#define EXPAND_AUX_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (AUX_STACK_CHECK_EXPAND)"); -#define EXPAND_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)"); +#define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \ + if ((STACK_LIMIT) >= (STACK)) \ + Yap_Error(INTERNAL_ERROR, TermNil, "stack full (AUX_STACK_CHECK_EXPAND)") #else /* YAPOR_THREADS */ -#define EXPAND_AUX_STACK(STACK) STACK = expand_auxiliary_stack(STACK) -#define EXPAND_STACK(STACK) Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)"); +#define AUX_STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \ + if ((STACK_LIMIT) >= (STACK)) \ + STACK = expand_auxiliary_stack(STACK) #endif /* YAPOR */ -#define OPTYAP_ERROR_MESSAGE(OP, COND) +#define STACK_CHECK_EXPAND(STACK, STACK_LIMIT) \ + if ((STACK_LIMIT) >= (STACK) + 4096) \ + Yap_Error(INTERNAL_ERROR, TermNil, "stack full (STACK_CHECK_EXPAND)") @@ -270,43 +273,87 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); #define AnsHash_init_previous_field(HASH, SG_FR) #endif /* MODE_DIRECTED_TABLING */ -#ifdef TABLE_LOCK_AT_ENTRY_LEVEL -#define TabEnt_init_lock_field(TAB_ENT) \ - INIT_LOCK(TabEnt_lock(TAB_ENT)) +#ifdef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL +#define LOCK_SUBGOAL_TRIE(TAB_ENT) LOCK(TabEnt_lock(TAB_ENT)) +#define UNLOCK_SUBGOAL_TRIE(TAB_ENT) UNLOCK(TabEnt_lock(TAB_ENT)) #define SgHash_init_next_field(HASH, TAB_ENT) \ Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ TabEnt_hash_chain(TAB_ENT) = HASH -#define AnsHash_init_chain_fields(HASH, SG_FR) \ - AnsHash_init_previous_field(HASH, SG_FR); \ - Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ - SgFr_hash_chain(SG_FR) = HASH #else -#define TabEnt_init_lock_field(TAB_ENT) +#define LOCK_SUBGOAL_TRIE(TAB_ENT) +#define UNLOCK_SUBGOAL_TRIE(TAB_ENT) #define SgHash_init_next_field(HASH, TAB_ENT) \ LOCK(TabEnt_lock(TAB_ENT)); \ Hash_next(HASH) = TabEnt_hash_chain(TAB_ENT); \ TabEnt_hash_chain(TAB_ENT) = HASH; \ UNLOCK(TabEnt_lock(TAB_ENT)) -#define AnsHash_init_chain_fields(HASH, SG_FR) \ - LOCK(SgFr_lock(SG_FR)); \ - AnsHash_init_previous_field(HASH, SG_FR); \ - Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ - SgFr_hash_chain(SG_FR) = HASH; \ - UNLOCK(SgFr_lock(SG_FR)) -#endif /* TABLE_LOCK_AT_ENTRY_LEVEL */ +#endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL */ -#ifdef TABLE_LOCK_AT_NODE_LEVEL -#define TrNode_init_lock_field(NODE) \ - INIT_LOCK(TrNode_lock(NODE)) +#ifdef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL +#define LOCK_ANSWER_TRIE(SG_FR) LOCK(SgFr_lock(SG_FR)) +#define UNLOCK_ANSWER_TRIE(SG_FR) UNLOCK(SgFr_lock(SG_FR)) +#define AnsHash_init_chain_fields(HASH, SG_FR) \ + AnsHash_init_previous_field(HASH, SG_FR); \ + Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ + SgFr_hash_chain(SG_FR) = HASH #else -#define TrNode_init_lock_field(NODE) -#endif /* TABLE_LOCK_AT_NODE_LEVEL */ +#define LOCK_ANSWER_TRIE(SG_FR) +#define UNLOCK_ANSWER_TRIE(SG_FR) +#define AnsHash_init_chain_fields(HASH, SG_FR) \ + LOCK(SgFr_lock(SG_FR)); \ + AnsHash_init_previous_field(HASH, SG_FR); \ + Hash_next(HASH) = SgFr_hash_chain(SG_FR); \ + SgFr_hash_chain(SG_FR) = HASH; \ + UNLOCK(SgFr_lock(SG_FR)) +#endif /* ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL */ + +#ifdef SUBGOAL_TRIE_LOCK_USING_NODE_FIELD +#define LOCK_SUBGOAL_NODE(NODE) LOCK(TrNode_lock(NODE)) +#define UNLOCK_SUBGOAL_NODE(NODE) UNLOCK(TrNode_lock(NODE)) +#define SgNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE)) +#elif SUBGOAL_TRIE_LOCK_USING_GLOBAL_ARRAY +#define LOCK_SUBGOAL_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE)) +#define UNLOCK_SUBGOAL_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE)) +#define SgNode_init_lock_field(NODE) +#else +#define LOCK_SUBGOAL_NODE(NODE) +#define UNLOCK_SUBGOAL_NODE(NODE) +#define SgNode_init_lock_field(NODE) +#endif /* SUBGOAL_TRIE_LOCK_LEVEL */ + +#ifdef ANSWER_TRIE_LOCK_USING_NODE_FIELD +#define LOCK_ANSWER_NODE(NODE) LOCK(TrNode_lock(NODE)) +#define UNLOCK_ANSWER_NODE(NODE) UNLOCK(TrNode_lock(NODE)) +#define AnsNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE)) +#elif ANSWER_TRIE_LOCK_USING_GLOBAL_ARRAY +#define LOCK_ANSWER_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE)) +#define UNLOCK_ANSWER_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE)) +#define AnsNode_init_lock_field(NODE) +#else +#define LOCK_ANSWER_NODE(NODE) +#define UNLOCK_ANSWER_NODE(NODE) +#define AnsNode_init_lock_field(NODE) +#endif /* ANSWER_TRIE_LOCK_LEVEL */ + +#ifdef GLOBAL_TRIE_LOCK_USING_NODE_FIELD +#define LOCK_GLOBAL_NODE(NODE) LOCK(TrNode_lock(NODE)) +#define UNLOCK_GLOBAL_NODE(NODE) UNLOCK(TrNode_lock(NODE)) +#define GtNode_init_lock_field(NODE) INIT_LOCK(TrNode_lock(NODE)) +#elif GLOBAL_TRIE_LOCK_USING_GLOBAL_ARRAY +#define LOCK_GLOBAL_NODE(NODE) LOCK(HASH_TRIE_LOCK(NODE)) +#define UNLOCK_GLOBAL_NODE(NODE) UNLOCK(HASH_TRIE_LOCK(NODE)) +#define GtNode_init_lock_field(NODE) +#else +#define LOCK_GLOBAL_NODE(NODE) +#define UNLOCK_GLOBAL_NODE(NODE) +#define GtNode_init_lock_field(NODE) +#endif /* GLOBAL_TRIE_LOCK_LEVEL */ #define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \ { register sg_node_ptr sg_node; \ new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \ ALLOC_TABLE_ENTRY(TAB_ENT); \ - TabEnt_init_lock_field(TAB_ENT); \ + INIT_LOCK(TabEnt_lock(TAB_ENT)); \ TabEnt_pe(TAB_ENT) = PRED_ENTRY; \ TabEnt_atom(TAB_ENT) = ATOM; \ TabEnt_arity(TAB_ENT) = ARITY; \ @@ -362,48 +409,49 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int); (unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \ DepFr_next(DEP_FR) = NEXT -#define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \ - H_REG, B_REG, TR_REG, H_SIZE, B_SIZE, TR_SIZE) \ - ALLOC_SUSPENSION_FRAME(SUSP_FR); \ - SuspFr_top_or_fr_on_stack(SUSP_FR) = TOP_OR_FR_ON_STACK; \ - SuspFr_top_dep_fr(SUSP_FR) = TOP_DEP; \ - SuspFr_top_sg_fr(SUSP_FR) = TOP_SG; \ - SuspFr_global_reg(SUSP_FR) = (void *) (H_REG); \ - SuspFr_local_reg(SUSP_FR) = (void *) (B_REG); \ - SuspFr_trail_reg(SUSP_FR) = (void *) (TR_REG); \ - ALLOC_BLOCK(SuspFr_global_start(SUSP_FR), H_SIZE + B_SIZE + TR_SIZE, void *); \ - SuspFr_local_start(SUSP_FR) = SuspFr_global_start(SUSP_FR) + H_SIZE; \ - SuspFr_trail_start(SUSP_FR) = SuspFr_local_start(SUSP_FR) + B_SIZE; \ - SuspFr_global_size(SUSP_FR) = H_SIZE; \ - SuspFr_local_size(SUSP_FR) = B_SIZE; \ - SuspFr_trail_size(SUSP_FR) = TR_SIZE; \ - memcpy(SuspFr_global_start(SUSP_FR), SuspFr_global_reg(SUSP_FR), H_SIZE); \ - memcpy(SuspFr_local_start(SUSP_FR), SuspFr_local_reg(SUSP_FR), B_SIZE); \ +#define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \ + H_REG, B_REG, TR_REG, H_SIZE, B_SIZE, TR_SIZE) \ + ALLOC_SUSPENSION_FRAME(SUSP_FR); \ + SuspFr_top_or_fr_on_stack(SUSP_FR) = TOP_OR_FR_ON_STACK; \ + SuspFr_top_dep_fr(SUSP_FR) = TOP_DEP; \ + SuspFr_top_sg_fr(SUSP_FR) = TOP_SG; \ + SuspFr_global_reg(SUSP_FR) = (void *) (H_REG); \ + SuspFr_local_reg(SUSP_FR) = (void *) (B_REG); \ + SuspFr_trail_reg(SUSP_FR) = (void *) (TR_REG); \ + ALLOC_BLOCK(SuspFr_global_start(SUSP_FR), H_SIZE + B_SIZE + TR_SIZE, void *); \ + SuspFr_local_start(SUSP_FR) = SuspFr_global_start(SUSP_FR) + H_SIZE; \ + SuspFr_trail_start(SUSP_FR) = SuspFr_local_start(SUSP_FR) + B_SIZE; \ + SuspFr_global_size(SUSP_FR) = H_SIZE; \ + SuspFr_local_size(SUSP_FR) = B_SIZE; \ + SuspFr_trail_size(SUSP_FR) = TR_SIZE; \ + memcpy(SuspFr_global_start(SUSP_FR), SuspFr_global_reg(SUSP_FR), H_SIZE); \ + memcpy(SuspFr_local_start(SUSP_FR), SuspFr_local_reg(SUSP_FR), B_SIZE); \ memcpy(SuspFr_trail_start(SUSP_FR), SuspFr_trail_reg(SUSP_FR), TR_SIZE) #define new_subgoal_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \ ALLOC_SUBGOAL_TRIE_NODE(NODE); \ TrNode_entry(NODE) = ENTRY; \ - TrNode_init_lock_field(NODE); \ TrNode_child(NODE) = CHILD; \ TrNode_parent(NODE) = PARENT; \ - TrNode_next(NODE) = NEXT + TrNode_next(NODE) = NEXT; \ + SgNode_init_lock_field(NODE) #define new_answer_trie_node(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \ ALLOC_ANSWER_TRIE_NODE(NODE); \ TrNode_instr(NODE) = INSTR; \ TrNode_entry(NODE) = ENTRY; \ - TrNode_init_lock_field(NODE); \ TrNode_child(NODE) = CHILD; \ TrNode_parent(NODE) = PARENT; \ - TrNode_next(NODE) = NEXT + TrNode_next(NODE) = NEXT; \ + AnsNode_init_lock_field(NODE) #define new_global_trie_node(NODE, ENTRY, CHILD, PARENT, NEXT) \ ALLOC_GLOBAL_TRIE_NODE(NODE); \ TrNode_entry(NODE) = ENTRY; \ TrNode_child(NODE) = CHILD; \ TrNode_parent(NODE) = PARENT; \ - TrNode_next(NODE) = NEXT + TrNode_next(NODE) = NEXT; \ + GtNode_init_lock_field(NODE) #define new_subgoal_trie_hash(HASH, NUM_NODES, TAB_ENT) \ ALLOC_SUBGOAL_TRIE_HASH(HASH); \ @@ -1009,13 +1057,8 @@ static inline void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) { slots = TgAnsFr_free_slot(valid_answers); do { ans_node = TgAnsFr_answer(valid_answers, --slots); -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - LOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - LOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - LOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + LOCK_ANSWER_TRIE(sg_fr); + LOCK_ANSWER_NODE(ans_node); if (! IS_ANSWER_LEAF_NODE(ans_node)) { TAG_AS_ANSWER_LEAF_NODE(ans_node); if (first_answer == NULL) @@ -1024,13 +1067,8 @@ static inline void CUT_validate_tg_answers(tg_sol_fr_ptr valid_solutions) { TrNode_child(last_answer) = ans_node; last_answer = ans_node; } -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - UNLOCK(SgFr_lock(sg_fr)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(ans_node); -#endif /* TABLE_LOCK_LEVEL */ + UNLOCK_ANSWER_NODE(ans_node); + UNLOCK_ANSWER_TRIE(sg_fr); } while (slots); free_answer = valid_answers; valid_answers = TgAnsFr_next(valid_answers); diff --git a/OPTYap/tab.structs.h b/OPTYap/tab.structs.h index 28dff3422..1cf140b73 100644 --- a/OPTYap/tab.structs.h +++ b/OPTYap/tab.structs.h @@ -58,9 +58,9 @@ typedef struct subgoal_trie_node { struct subgoal_trie_node *parent; struct subgoal_trie_node *child; struct subgoal_trie_node *next; -#ifdef TABLE_LOCK_AT_NODE_LEVEL +#ifdef SUBGOAL_TRIE_LOCK_USING_NODE_FIELD lockvar lock; -#endif /* TABLE_LOCK_AT_NODE_LEVEL */ +#endif /* SUBGOAL_TRIE_LOCK_USING_NODE_FIELD */ } *sg_node_ptr; typedef struct answer_trie_node { @@ -72,9 +72,9 @@ typedef struct answer_trie_node { struct answer_trie_node *parent; struct answer_trie_node *child; struct answer_trie_node *next; -#ifdef TABLE_LOCK_AT_NODE_LEVEL +#ifdef ANSWER_TRIE_LOCK_USING_NODE_FIELD lockvar lock; -#endif /* TABLE_LOCK_AT_NODE_LEVEL */ +#endif /* ANSWER_TRIE_LOCK_USING_NODE_FIELD */ } *ans_node_ptr; typedef struct global_trie_node { @@ -82,9 +82,9 @@ typedef struct global_trie_node { struct global_trie_node *parent; struct global_trie_node *child; struct global_trie_node *next; -#ifdef TABLE_LOCK_AT_NODE_LEVEL +#ifdef GLOBAL_TRIE_LOCK_USING_NODE_FIELD lockvar lock; -#endif /* TABLE_LOCK_AT_NODE_LEVEL */ +#endif /* GLOBAL_TRIE_LOCK_USING_NODE_FIELD */ } *gt_node_ptr; #define TrNode_instr(X) ((X)->trie_instruction) diff --git a/OPTYap/tab.tries.c b/OPTYap/tab.tries.c index 5ae9f2938..39fb9e9bf 100644 --- a/OPTYap/tab.tries.c +++ b/OPTYap/tab.tries.c @@ -32,10 +32,6 @@ static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr, Term); static inline sg_node_ptr subgoal_search_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline sg_node_ptr subgoal_search_terms_loop(tab_ent_ptr, sg_node_ptr, Term, int *, CELL **); static inline ans_node_ptr answer_search_loop(sg_fr_ptr, ans_node_ptr, Term, int *); -#ifdef MODE_DIRECTED_TABLING -static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr, ans_node_ptr, Term, int); -static void invalidate_answer_trie(ans_node_ptr, sg_fr_ptr, int); -#endif /* MODE_DIRECTED_TABLING */ static inline ans_node_ptr answer_search_terms_loop(sg_fr_ptr, ans_node_ptr, Term, int *); #ifdef GLOBAL_TRIE_FOR_SUBTERMS static inline gt_node_ptr subgoal_search_global_trie_terms_loop(Term, int *, CELL **, CELL *); @@ -158,7 +154,7 @@ static struct trie_statistics{ #undef MODE_GLOBAL_TRIE_ENTRY #define INCLUDE_SUBGOAL_SEARCH_LOOP /* subgoal_search_loop */ -#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop + answer_search_mode_directed_min_max + invalidate_answer_trie */ +#define INCLUDE_ANSWER_SEARCH_LOOP /* answer_search_loop */ #define INCLUDE_LOAD_ANSWER_LOOP /* load_answer_loop */ #include "tab.tries.i" #undef INCLUDE_LOAD_ANSWER_LOOP @@ -183,6 +179,13 @@ static struct trie_statistics{ #undef INCLUDE_SUBGOAL_SEARCH_LOOP #undef MODE_GLOBAL_TRIE_LOOP +#ifdef MODE_DIRECTED_TABLING +#define INCLUDE_ANSWER_SEARCH_MODE_DIRECTED +#include "tab.tries.i" /* answer_search_min_max + invalidate_answer_trie */ +#undef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED +#endif /* MODE_DIRECTED_TABLING */ + + static inline CELL *exec_substitution_loop(gt_node_ptr current_node, CELL **stack_vars_ptr, CELL *stack_terms) { /************************************************************************ @@ -991,9 +994,7 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { pred_arity = preg->u.Otapl.s; tab_ent = preg->u.Otapl.te; current_sg_node = TabEnt_subgoal_trie(tab_ent); -#ifdef TABLE_LOCK_AT_ENTRY_LEVEL - LOCK(TabEnt_lock(tab_ent)); -#endif /* TABLE_LOCK_LEVEL */ + LOCK_SUBGOAL_TRIE(tab_ent); #ifdef MODE_DIRECTED_TABLING mode_directed = TabEnt_mode_directed(tab_ent); @@ -1031,12 +1032,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { Term t = STACK_POP_DOWN(stack_vars); RESET_VARIABLE(t); } - -#if defined(TABLE_LOCK_AT_NODE_LEVEL) - LOCK(TrNode_lock(current_sg_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - LOCK_TABLE(current_sg_node); -#endif /* TABLE_LOCK_LEVEL */ + + LOCK_SUBGOAL_NODE(current_sg_node); if (TrNode_sg_fr(current_sg_node) == NULL) { /* new tabled subgoal */ #ifdef MODE_DIRECTED_TABLING @@ -1057,13 +1054,8 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) { } #endif /* LIMIT_TABLING */ } -#if defined(TABLE_LOCK_AT_ENTRY_LEVEL) - UNLOCK(TabEnt_lock(tab_ent)); -#elif defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(current_sg_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(current_sg_node); -#endif /* TABLE_LOCK_LEVEL */ + UNLOCK_SUBGOAL_NODE(current_sg_node); + UNLOCK_SUBGOAL_TRIE(tab_ent); return sg_fr; } @@ -1074,83 +1066,9 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { CELL *stack_vars; int i, vars_arity; ans_node_ptr current_ans_node; -#ifdef MODE_DIRECTED_TABLING - int *mode_directed; -#endif /* MODE_DIRECTED_TABLING */ vars_arity = 0; current_ans_node = SgFr_answer_trie(sg_fr); -#ifdef MODE_DIRECTED_TABLING - mode_directed = SgFr_mode_directed(sg_fr); - if (mode_directed) { - ans_node_ptr invalid_ans_node = NULL; - int i = subs_arity, j = 0; - while (i) { - int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]); - int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]); - do { - TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); - if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) - current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); - else { -#if defined(TABLE_LOCK_AT_NODE_LEVEL) - LOCK(TrNode_lock(current_ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - LOCK_TABLE(current_ans_node); -#endif /* TABLE_LOCK_LEVEL */ - if (TrNode_child(current_ans_node) == NULL) { -#ifdef YAPOR - struct answer_trie_node virtual_ans_node; - ans_node_ptr parent_ans_node = current_ans_node; - TrNode_init_lock_field(&virtual_ans_node); - TrNode_parent(&virtual_ans_node) = NULL; - TrNode_child(&virtual_ans_node) = NULL; - current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity); - TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); -#else - current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); -#endif /* YAPOR */ - } else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) { - ans_node_ptr parent_ans_node = current_ans_node; - invalid_ans_node = TrNode_child(parent_ans_node); /* by default, assume a better answer */ - current_ans_node = answer_search_mode_directed_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode); - if (invalid_ans_node == TrNode_child(parent_ans_node)) /* worse or equal answer */ - invalid_ans_node = NULL; - } else if (mode == MODE_DIRECTED_FIRST) - current_ans_node = NULL; - else { /* mode == MODE_DIRECTED_LAST */ -#ifdef YAPOR - struct answer_trie_node virtual_ans_node; - ans_node_ptr parent_ans_node = current_ans_node; - invalid_ans_node = TrNode_child(parent_ans_node); - TrNode_init_lock_field(&virtual_ans_node); - TrNode_parent(&virtual_ans_node) = NULL; - TrNode_child(&virtual_ans_node) = NULL; - current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity); - TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); -#else - invalid_ans_node = TrNode_child(current_ans_node); - TrNode_child(current_ans_node) = NULL; - current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); -#endif /* YAPOR */ - } -#if defined(TABLE_LOCK_AT_NODE_LEVEL) - UNLOCK(TrNode_lock(current_ans_node)); -#elif defined(TABLE_LOCK_AT_WRITE_LEVEL) - UNLOCK_TABLE(current_ans_node); -#endif /* TABLE_LOCK_LEVEL */ - } - n_subs--; - i--; - } while (n_subs && current_ans_node); - if (current_ans_node == NULL) /* no answer inserted */ - break; - j++; - } - if (invalid_ans_node) - invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST); - } else -#endif /* MODE_DIRECTED_TABLING */ if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) { for (i = subs_arity; i >= 1; i--) { TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); @@ -1175,6 +1093,91 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { } +#ifdef MODE_DIRECTED_TABLING +ans_node_ptr mode_directed_answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) { +#define subs_arity *subs_ptr + CACHE_REGS + CELL *stack_vars; + int i, j, vars_arity; + ans_node_ptr current_ans_node, invalid_ans_node; + int *mode_directed; + + vars_arity = 0; + current_ans_node = SgFr_answer_trie(sg_fr); + invalid_ans_node = NULL; + mode_directed = SgFr_mode_directed(sg_fr); + j = 0; + i = subs_arity; + while (i) { + int mode = MODE_DIRECTED_GET_MODE(mode_directed[j]); + int n_subs = MODE_DIRECTED_GET_ARG(mode_directed[j]); + do { + TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i])); + if (mode == MODE_DIRECTED_INDEX || mode == MODE_DIRECTED_ALL) { + current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); + } else { + LOCK_ANSWER_NODE(current_ans_node); + if (TrNode_child(current_ans_node) == NULL) { +#ifdef YAPOR + struct answer_trie_node virtual_ans_node; + ans_node_ptr parent_ans_node = current_ans_node; + TrNode_init_lock_field(&virtual_ans_node); + TrNode_parent(&virtual_ans_node) = NULL; + TrNode_child(&virtual_ans_node) = NULL; + current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity); + TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); +#else + current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); +#endif /* YAPOR */ + } else if (mode == MODE_DIRECTED_MIN || mode == MODE_DIRECTED_MAX) { + ans_node_ptr parent_ans_node = current_ans_node; + invalid_ans_node = TrNode_child(parent_ans_node); /* by default, assume a better answer */ + current_ans_node = answer_search_min_max(sg_fr, current_ans_node, Deref(subs_ptr[i]), mode); + if (invalid_ans_node == TrNode_child(parent_ans_node)) /* worse or equal answer */ + invalid_ans_node = NULL; + } else if (mode == MODE_DIRECTED_FIRST) + current_ans_node = NULL; + else { /* mode == MODE_DIRECTED_LAST */ +#ifdef YAPOR + struct answer_trie_node virtual_ans_node; + ans_node_ptr parent_ans_node = current_ans_node; + invalid_ans_node = TrNode_child(parent_ans_node); + TrNode_init_lock_field(&virtual_ans_node); + TrNode_parent(&virtual_ans_node) = NULL; + TrNode_child(&virtual_ans_node) = NULL; + current_ans_node = answer_search_loop(sg_fr, &virtual_ans_node, Deref(subs_ptr[i]), &vars_arity); + TrNode_child(parent_ans_node) = TrNode_child(&virtual_ans_node); +#else + invalid_ans_node = TrNode_child(current_ans_node); + TrNode_child(current_ans_node) = NULL; + current_ans_node = answer_search_loop(sg_fr, current_ans_node, Deref(subs_ptr[i]), &vars_arity); +#endif /* YAPOR */ + } + UNLOCK_ANSWER_NODE(current_ans_node); + } + n_subs--; + i--; + } while (n_subs && current_ans_node); + if (current_ans_node == NULL) /* no answer inserted */ + break; + j++; + } + if (invalid_ans_node) + invalidate_answer_trie(invalid_ans_node, sg_fr, TRAVERSE_POSITION_FIRST); + + /* reset variables */ + stack_vars = (CELL *) TR; + while (vars_arity--) { + Term t = STACK_POP_DOWN(stack_vars); + RESET_VARIABLE(t); + } + + return current_ans_node; +#undef subs_arity +} +#endif /* MODE_DIRECTED_TABLING */ + + void load_answer(ans_node_ptr current_ans_node, CELL *subs_ptr) { CACHE_REGS #define subs_arity *subs_ptr diff --git a/OPTYap/tab.tries.i b/OPTYap/tab.tries.i index c2f0cf0c1..90d864f2c 100644 --- a/OPTYap/tab.tries.i +++ b/OPTYap/tab.tries.i @@ -52,25 +52,13 @@ #endif /* MODE_GLOBAL_TRIE_LOOP */ -#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) LOCK(TrNode_lock(NODE)) -#define UNLOCK_NODE(NODE) UNLOCK(TrNode_lock(NODE)) -#else /* TABLE_LOCK_AT_ENTRY_LEVEL || ! YAPOR */ -#define LOCK_NODE(NODE) -#define UNLOCK_NODE(NODE) -#endif /* TABLE_LOCK_LEVEL */ - - /************************************************************************ ** subgoal_trie_check_insert_(gt)_entry ** ************************************************************************/ #ifdef INCLUDE_SUBGOAL_TRIE_CHECK_INSERT -#ifndef TABLE_LOCK_AT_WRITE_LEVEL /* TABLE_LOCK_AT_ENTRY_LEVEL || TABLE_LOCK_AT_NODE_LEVEL || ! YAPOR */ +#ifndef SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL || SUBGOAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */ #ifdef MODE_GLOBAL_TRIE_ENTRY static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { #else @@ -78,12 +66,12 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s #endif /* MODE_GLOBAL_TRIE_ENTRY */ sg_node_ptr child_node; - LOCK_NODE(parent_node); + LOCK_SUBGOAL_NODE(parent_node); child_node = TrNode_child(parent_node); if (child_node == NULL) { NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); TrNode_child(parent_node) = child_node; - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } @@ -91,7 +79,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s int count_nodes = 0; do { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } count_nodes++; @@ -116,7 +104,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s } else { TrNode_child(parent_node) = child_node; } - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } @@ -129,7 +117,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } count_nodes++; @@ -162,11 +150,11 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s } while (old_bucket != first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } } -#else /* TABLE_LOCK_AT_WRITE_LEVEL */ +#else /* SUBGOAL_TRIE_LOCK_AT_WRITE_LEVEL */ #ifdef MODE_GLOBAL_TRIE_ENTRY static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) { #else @@ -177,40 +165,40 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s child_node = TrNode_child(parent_node); if (child_node == NULL) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_SUBGOAL_NODE(parent_node); if (TrNode_child(parent_node)) { sg_node_ptr chain_node = TrNode_child(parent_node); if (IS_SUBGOAL_TRIE_HASH(chain_node)) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); hash = (sg_hash_ptr) chain_node; goto subgoal_trie_hash; } do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); return chain_node; } chain_node = TrNode_next(chain_node); } while (chain_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = TrNode_child(parent_node); #else NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); } else { NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ } TrNode_child(parent_node) = child_node; - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } @@ -218,44 +206,43 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s sg_node_ptr first_node = child_node; int count_nodes = 0; do { - if (TrNode_entry(child_node) == t) { + if (TrNode_entry(child_node) == t) return child_node; - } count_nodes++; child_node = TrNode_next(child_node); } while (child_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_SUBGOAL_NODE(parent_node); if (first_node != TrNode_child(parent_node)) { sg_node_ptr chain_node = TrNode_child(parent_node); if (IS_SUBGOAL_TRIE_HASH(chain_node)) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); hash = (sg_hash_ptr) chain_node; goto subgoal_trie_hash; } do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = TrNode_child(parent_node); #else NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); } else { NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ } count_nodes++; if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { @@ -274,7 +261,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s } else { TrNode_child(parent_node) = child_node; } - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } @@ -288,44 +275,43 @@ subgoal_trie_hash: bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); first_node = child_node = *bucket; while (child_node) { - if (TrNode_entry(child_node) == t) { + if (TrNode_entry(child_node) == t) return child_node; - } count_nodes++; child_node = TrNode_next(child_node); } -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_SUBGOAL_NODE(parent_node); if (seed != Hash_seed(hash)) { /* the hash has been expanded */ -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); goto subgoal_trie_hash; } if (first_node != *bucket) { sg_node_ptr chain_node = *bucket; do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK FREE_SUBGOAL_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_SUBGOAL_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef SUBGOAL_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = *bucket; #else NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, *bucket); } else { NEW_SUBGOAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* SUBGOAL_TRIE_ALLOC_BEFORE_CHECK */ } *bucket = child_node; Hash_num_nodes(hash)++; @@ -352,11 +338,11 @@ subgoal_trie_hash: } while (old_bucket != first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_NODE(parent_node); + UNLOCK_SUBGOAL_NODE(parent_node); return child_node; } } -#endif /* TABLE_LOCK_LEVEL */ +#endif /* SUBGOAL_TRIE_LOCK_LEVEL */ #endif /* INCLUDE_SUBGOAL_TRIE_CHECK_INSERT */ @@ -366,7 +352,7 @@ subgoal_trie_hash: ************************************************************************/ #ifdef INCLUDE_ANSWER_TRIE_CHECK_INSERT -#ifndef TABLE_LOCK_AT_WRITE_LEVEL /* TABLE_LOCK_AT_ENTRY_LEVEL || TABLE_LOCK_AT_NODE_LEVEL || ! YAPOR */ +#ifndef ANSWER_TRIE_LOCK_AT_WRITE_LEVEL /* ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL || ANSWER_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */ #ifdef MODE_GLOBAL_TRIE_ENTRY static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) { #else @@ -375,12 +361,12 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n ans_node_ptr child_node; TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node)); - LOCK_NODE(parent_node); + LOCK_ANSWER_NODE(parent_node); child_node = TrNode_child(parent_node); if (child_node == NULL) { NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); TrNode_child(parent_node) = child_node; - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } @@ -388,7 +374,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n int count_nodes = 0; do { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } count_nodes++; @@ -413,7 +399,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n } else { TrNode_child(parent_node) = child_node; } - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } @@ -426,7 +412,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } count_nodes++; @@ -459,11 +445,11 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n } while (old_bucket != first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } } -#else +#else /* ANSWER_TRIE_LOCK_AT_WRITE_LEVEL */ #ifdef MODE_GLOBAL_TRIE_ENTRY static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) { #else @@ -475,40 +461,40 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n TABLING_ERROR_CHECKING(answer_trie_check_insert_(gt)_entry, IS_ANSWER_LEAF_NODE(parent_node)); child_node = TrNode_child(parent_node); if (child_node == NULL) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_ANSWER_NODE(parent_node); if (TrNode_child(parent_node)) { ans_node_ptr chain_node = TrNode_child(parent_node); if (IS_ANSWER_TRIE_HASH(chain_node)) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); hash = (ans_hash_ptr) chain_node; goto answer_trie_hash; } do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); return chain_node; } chain_node = TrNode_next(chain_node); } while (chain_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = TrNode_child(parent_node); #else NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); } else { NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, NULL); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ } TrNode_child(parent_node) = child_node; - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } @@ -516,44 +502,43 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n ans_node_ptr first_node = child_node; int count_nodes = 0; do { - if (TrNode_entry(child_node) == t) { + if (TrNode_entry(child_node) == t) return child_node; - } count_nodes++; child_node = TrNode_next(child_node); } while (child_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_ANSWER_NODE(parent_node); if (first_node != TrNode_child(parent_node)) { ans_node_ptr chain_node = TrNode_child(parent_node); if (IS_ANSWER_TRIE_HASH(chain_node)) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); hash = (ans_hash_ptr) chain_node; goto answer_trie_hash; } do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = TrNode_child(parent_node); #else NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, TrNode_child(parent_node)); } else { NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ } count_nodes++; if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { @@ -572,7 +557,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n } else { TrNode_child(parent_node) = child_node; } - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } @@ -586,44 +571,43 @@ answer_trie_hash: bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); first_node = child_node = *bucket; while (child_node) { - if (TrNode_entry(child_node) == t) { + if (TrNode_entry(child_node) == t) return child_node; - } count_nodes++; child_node = TrNode_next(child_node); } -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ - LOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_ANSWER_NODE(parent_node); if (seed != Hash_seed(hash)) { /* the hash has been expanded */ -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); goto answer_trie_hash; } if (first_node != *bucket) { ans_node_ptr chain_node = *bucket; do { if (TrNode_entry(chain_node) == t) { -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK FREE_ANSWER_TRIE_NODE(child_node); -#endif /* ALLOC_BEFORE_CHECK */ - UNLOCK_NODE(parent_node); +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_ANSWER_NODE(parent_node); return chain_node; } count_nodes++; chain_node = TrNode_next(chain_node); } while (chain_node != first_node); -#ifdef ALLOC_BEFORE_CHECK +#ifdef ANSWER_TRIE_ALLOC_BEFORE_CHECK TrNode_next(child_node) = *bucket; #else NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, *bucket); } else { NEW_ANSWER_TRIE_NODE(child_node, instr, t, NULL, parent_node, first_node); -#endif /* ALLOC_BEFORE_CHECK */ +#endif /* ANSWER_TRIE_ALLOC_BEFORE_CHECK */ } *bucket = child_node; Hash_num_nodes(hash)++; @@ -650,11 +634,11 @@ answer_trie_hash: } while (old_bucket != first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_NODE(parent_node); + UNLOCK_ANSWER_NODE(parent_node); return child_node; } } -#endif /* TABLE_LOCK_LEVEL */ +#endif /* ANSWER_TRIE_LOCK_LEVEL */ #endif /* INCLUDE_ANSWER_TRIE_CHECK_INSERT */ @@ -664,6 +648,7 @@ answer_trie_hash: ************************************************************************/ #ifdef INCLUDE_GLOBAL_TRIE_CHECK_INSERT +#ifndef GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL /* GLOBAL_TRIE_LOCK_AT_NODE_LEVEL || ! YAPOR */ #ifdef MODE_GLOBAL_TRIE_ENTRY static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_node, Term t) { #else @@ -671,12 +656,12 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node #endif /* MODE_GLOBAL_TRIE_ENTRY */ gt_node_ptr child_node; - LOCK_NODE(parent_node); + LOCK_GLOBAL_NODE(parent_node); child_node = TrNode_child(parent_node); if (child_node == NULL) { NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); TrNode_child(parent_node) = child_node; - UNLOCK_NODE(parent_node); + UNLOCK_GLOBAL_NODE(parent_node); return child_node; } @@ -684,7 +669,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node int count_nodes = 0; do { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_GLOBAL_NODE(parent_node); return child_node; } count_nodes++; @@ -709,7 +694,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node } else { TrNode_child(parent_node) = child_node; } - UNLOCK_NODE(parent_node); + UNLOCK_GLOBAL_NODE(parent_node); return child_node; } @@ -722,7 +707,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node child_node = *bucket; while (child_node) { if (TrNode_entry(child_node) == t) { - UNLOCK_NODE(parent_node); + UNLOCK_GLOBAL_NODE(parent_node); return child_node; } count_nodes++; @@ -755,10 +740,199 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node } while (old_bucket != first_old_bucket); FREE_HASH_BUCKETS(first_old_bucket); } - UNLOCK_NODE(parent_node); + UNLOCK_GLOBAL_NODE(parent_node); return child_node; } } +#else /* GLOBAL_TRIE_LOCK_AT_WRITE_LEVEL */ +#ifdef MODE_GLOBAL_TRIE_ENTRY +static inline gt_node_ptr global_trie_check_insert_gt_entry(gt_node_ptr parent_node, Term t) { +#else +static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node, Term t) { +#endif /* MODE_GLOBAL_TRIE_ENTRY */ + gt_node_ptr child_node; + gt_hash_ptr hash; + + child_node = TrNode_child(parent_node); + if (child_node == NULL) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_GLOBAL_NODE(parent_node); + if (TrNode_child(parent_node)) { + gt_node_ptr chain_node = TrNode_child(parent_node); + if (IS_GLOBAL_TRIE_HASH(chain_node)) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + hash = (gt_hash_ptr) chain_node; + goto global_trie_hash; + } + do { + if (TrNode_entry(chain_node) == t) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + return chain_node; + } + chain_node = TrNode_next(chain_node); + } while (chain_node); +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + TrNode_next(child_node) = TrNode_child(parent_node); +#else + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); + } else { + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, NULL); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + } + TrNode_child(parent_node) = child_node; + UNLOCK_GLOBAL_NODE(parent_node); + return child_node; + } + + if (! IS_GLOBAL_TRIE_HASH(child_node)) { + gt_node_ptr first_node = child_node; + int count_nodes = 0; + do { + if (TrNode_entry(child_node) == t) + return child_node; + count_nodes++; + child_node = TrNode_next(child_node); + } while (child_node); +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_GLOBAL_NODE(parent_node); + if (first_node != TrNode_child(parent_node)) { + gt_node_ptr chain_node = TrNode_child(parent_node); + if (IS_GLOBAL_TRIE_HASH(chain_node)) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + hash = (gt_hash_ptr) chain_node; + goto global_trie_hash; + } + do { + if (TrNode_entry(chain_node) == t) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + return chain_node; + } + count_nodes++; + chain_node = TrNode_next(chain_node); + } while (chain_node != first_node); +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + TrNode_next(child_node) = TrNode_child(parent_node); +#else + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, TrNode_child(parent_node)); + } else { + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + } + count_nodes++; + if (count_nodes >= MAX_NODES_PER_TRIE_LEVEL) { + /* alloc a new hash */ + gt_node_ptr chain_node, next_node, *bucket; + new_answer_trie_hash(hash, count_nodes, sg_fr); + chain_node = child_node; + do { + bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), BASE_HASH_BUCKETS - 1)); + next_node = TrNode_next(chain_node); + TrNode_next(chain_node) = *bucket; + *bucket = chain_node; + chain_node = next_node; + } while (chain_node); + TrNode_child(parent_node) = (gt_node_ptr) hash; + } else { + TrNode_child(parent_node) = child_node; + } + UNLOCK_GLOBAL_NODE(parent_node); + return child_node; + } + + hash = (gt_hash_ptr) child_node; +global_trie_hash: + { /* trie nodes with hashing */ + gt_node_ptr *bucket, first_node; + int seed, count_nodes = 0; + + seed = Hash_seed(hash); + bucket = Hash_bucket(hash, HASH_ENTRY(t, seed)); + first_node = child_node = *bucket; + while (child_node) { + if (TrNode_entry(child_node) == t) + return child_node; + count_nodes++; + child_node = TrNode_next(child_node); + } +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + LOCK_GLOBAL_NODE(parent_node); + if (seed != Hash_seed(hash)) { + /* the hash has been expanded */ +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + goto global_trie_hash; + } + if (first_node != *bucket) { + gt_node_ptr chain_node = *bucket; + do { + if (TrNode_entry(chain_node) == t) { +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + FREE_GLOBAL_TRIE_NODE(child_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + UNLOCK_GLOBAL_NODE(parent_node); + return chain_node; + } + count_nodes++; + chain_node = TrNode_next(chain_node); + } while (chain_node != first_node); +#ifdef GLOBAL_TRIE_ALLOC_BEFORE_CHECK + TrNode_next(child_node) = *bucket; +#else + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, *bucket); + } else { + NEW_GLOBAL_TRIE_NODE(child_node, t, NULL, parent_node, first_node); +#endif /* GLOBAL_TRIE_ALLOC_BEFORE_CHECK */ + } + *bucket = child_node; + Hash_num_nodes(hash)++; + count_nodes++; + if (count_nodes >= MAX_NODES_PER_BUCKET && Hash_num_nodes(hash) > Hash_num_buckets(hash)) { + /* expand current hash */ + gt_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); + Hash_num_buckets(hash) *= 2; + ALLOC_HASH_BUCKETS(Hash_buckets(hash), Hash_num_buckets(hash)); + seed = Hash_seed(hash); + do { + if (*--old_bucket) { + chain_node = *old_bucket; + do { + bucket = Hash_bucket(hash, HASH_ENTRY(TrNode_entry(chain_node), seed)); + next_node = TrNode_next(chain_node); + TrNode_next(chain_node) = *bucket; + *bucket = chain_node; + chain_node = next_node; + } while (chain_node); + } + } while (old_bucket != first_old_bucket); + FREE_HASH_BUCKETS(first_old_bucket); + } + UNLOCK_GLOBAL_NODE(parent_node); + return child_node; + } +} +#endif /* GLOBAL_TRIE_LOCK_LEVEL */ #endif /* INCLUDE_GLOBAL_TRIE_CHECK_INSERT */ @@ -1195,14 +1369,15 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr #undef in_pair #endif /* TRIE_COMPACT_PAIRS */ } +#endif /* INCLUDE_ANSWER_SEARCH_LOOP */ -/**************************************************************************** -** answer_search_mode_directed_min_max ** -****************************************************************************/ +/************************************************************** +** answer_search_min_max ** +**************************************************************/ -#if defined(MODE_DIRECTED_TABLING) && ! defined(MODE_TERMS_LOOP) && ! defined(MODE_GLOBAL_TRIE_LOOP) +#ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED #define ANSWER_SAFE_INSERT_ENTRY(NODE, ENTRY, INSTR) \ { ans_node_ptr new_node; \ NEW_ANSWER_TRIE_NODE(new_node, INSTR, ENTRY, NULL, NODE, NULL); \ @@ -1210,7 +1385,7 @@ static inline ans_node_ptr answer_search_loop(sg_fr_ptr sg_fr, ans_node_ptr curr NODE = new_node; \ } -static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) { +static inline ans_node_ptr answer_search_min_max(sg_fr_ptr sg_fr, ans_node_ptr current_node, Term t, int mode) { ans_node_ptr child_node; Term child_term; Float trie_value, term_value; @@ -1237,7 +1412,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, #endif /* SIZEOF_DOUBLE x SIZEOF_INT_P */ trie_value = u.dbl; } else - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_mode_directed_min_max: invalid arithmetic value"); + Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_min_max: invalid arithmetic value"); child_node = TrNode_child(child_node); } @@ -1251,7 +1426,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, else if (f == FunctorDouble) term_value = FloatOfTerm(t); else - Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_mode_directed_min_max: invalid arithmetic value"); + Yap_Error(INTERNAL_ERROR, TermNil, "answer_search_min_max: invalid arithmetic value"); } /* worse answer */ @@ -1286,6 +1461,7 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, } return current_node; } +#endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */ @@ -1293,6 +1469,20 @@ static inline ans_node_ptr answer_search_mode_directed_min_max(sg_fr_ptr sg_fr, ** invalidate_answer_trie ** ***************************************************************/ +#ifdef INCLUDE_ANSWER_SEARCH_MODE_DIRECTED +#ifdef YAPOR +#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ + TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ + SgFr_invalid_chain(SG_FR) = NODE +#else +#define INVALIDATE_ANSWER_TRIE_NODE(NODE, SG_FR) \ + FREE_ANSWER_TRIE_NODE(NODE) +#endif /* YAPOR */ +#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \ + TAG_AS_INVALID_LEAF_NODE(NODE); \ + TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \ + SgFr_invalid_chain(SG_FR) = NODE + static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, int position) { if (IS_ANSWER_TRIE_HASH(current_node)) { ans_hash_ptr hash; @@ -1304,15 +1494,11 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i current_node = *bucket; if (current_node) { ans_node_ptr next_node = TrNode_next(current_node); - if (! IS_ANSWER_LEAF_NODE(current_node)) { - invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); - FREE_ANSWER_TRIE_NODE(current_node); + if (IS_ANSWER_LEAF_NODE(current_node)) { + INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr); } else { - LOCK_NODE(current_ans_node); - TAG_AS_INVALID_LEAF_NODE(current_node); - UNLOCK_NODE(current_ans_node); - TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); - SgFr_invalid_chain(sg_fr) = current_node; + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr); } while (next_node) { current_node = next_node; @@ -1332,13 +1518,11 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i } else { if (position == TRAVERSE_POSITION_FIRST) { ans_node_ptr next_node = TrNode_next(current_node); - if (! IS_ANSWER_LEAF_NODE(current_node)) { - invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); - FREE_ANSWER_TRIE_NODE(current_node); + if (IS_ANSWER_LEAF_NODE(current_node)) { + INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr); } else { - TAG_AS_INVALID_LEAF_NODE(current_node); - TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); - SgFr_invalid_chain(sg_fr) = current_node; + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr); } while (next_node) { current_node = next_node; @@ -1346,20 +1530,17 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i invalidate_answer_trie(current_node, sg_fr, TRAVERSE_POSITION_NEXT); } } else { - if (! IS_ANSWER_LEAF_NODE(current_node)) { - invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); - FREE_ANSWER_TRIE_NODE(current_node); + if (IS_ANSWER_LEAF_NODE(current_node)) { + INVALIDATE_ANSWER_TRIE_LEAF_NODE(current_node, sg_fr); } else { - TAG_AS_INVALID_LEAF_NODE(current_node); - TrNode_next(current_node) = SgFr_invalid_chain(sg_fr); - SgFr_invalid_chain(sg_fr) = current_node; + invalidate_answer_trie(TrNode_child(current_node), sg_fr, TRAVERSE_POSITION_FIRST); + INVALIDATE_ANSWER_TRIE_NODE(current_node, sg_fr); } } } return; } -#endif /* MODE_DIRECTED_TABLING && ! MODE_TERMS_LOOP && ! MODE_GLOBAL_TRIE_LOOP */ -#endif /* INCLUDE_ANSWER_SEARCH_LOOP */ +#endif /* INCLUDE_ANSWER_SEARCH_MODE_DIRECTED */ @@ -1526,5 +1707,3 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node) { #undef NEW_GLOBAL_TRIE_NODE #undef SUBGOAL_CHECK_INSERT_ENTRY #undef ANSWER_CHECK_INSERT_ENTRY -#undef LOCK_NODE -#undef UNLOCK_NODE