Miguel's support for multi-threaded tabling
This commit is contained in:
parent
dc36b1cf65
commit
c594d321ef
@ -1924,6 +1924,9 @@ Yap_absmi(int inp)
|
|||||||
case _table_retry:
|
case _table_retry:
|
||||||
case _table_trust:
|
case _table_trust:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#ifdef DETERMINISTIC_TABLING
|
#ifdef DETERMINISTIC_TABLING
|
||||||
if (IS_DET_GEN_CP(B))
|
if (IS_DET_GEN_CP(B))
|
||||||
low_level_trace(retry_table_generator, DET_GEN_CP(B)->cp_pred_entry, NULL);
|
low_level_trace(retry_table_generator, DET_GEN_CP(B)->cp_pred_entry, NULL);
|
||||||
|
@ -588,6 +588,9 @@ PredForChoicePt(yamop *p_code) {
|
|||||||
case _table_try_answer:
|
case _table_try_answer:
|
||||||
case _table_answer_resolution:
|
case _table_answer_resolution:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
return NULL; /* ricroc: is this OK? */
|
return NULL; /* ricroc: is this OK? */
|
||||||
/* compile error --> return ENV_ToP(gc_B->cp_cp); */
|
/* compile error --> return ENV_ToP(gc_B->cp_cp); */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
@ -5486,6 +5489,9 @@ p_choicepoint_info( USES_REGS1 )
|
|||||||
case _table_retry:
|
case _table_retry:
|
||||||
case _table_trust:
|
case _table_trust:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#ifdef LOW_LEVEL_TRACER
|
#ifdef LOW_LEVEL_TRACER
|
||||||
#ifdef DETERMINISTIC_TABLING
|
#ifdef DETERMINISTIC_TABLING
|
||||||
if (IS_DET_GEN_CP(cptr)) {
|
if (IS_DET_GEN_CP(cptr)) {
|
||||||
|
@ -2112,6 +2112,9 @@ mark_choicepoints(register choiceptr gc_B, tr_fr_ptr saved_TR, int very_verbose
|
|||||||
nargs = 0;
|
nargs = 0;
|
||||||
break;
|
break;
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
{
|
{
|
||||||
CELL *vars_ptr, vars;
|
CELL *vars_ptr, vars;
|
||||||
#ifdef DETERMINISTIC_TABLING
|
#ifdef DETERMINISTIC_TABLING
|
||||||
@ -3035,6 +3038,9 @@ sweep_choicepoints(choiceptr gc_B USES_REGS)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
{
|
{
|
||||||
int nargs;
|
int nargs;
|
||||||
CELL *vars_ptr, vars;
|
CELL *vars_ptr, vars;
|
||||||
|
32
C/threads.c
32
C/threads.c
@ -27,6 +27,9 @@ static char SccsId[] = "%W% %G%";
|
|||||||
#if HAVE_STRING_H
|
#if HAVE_STRING_H
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TABLING
|
||||||
|
#include "tab.macros.h"
|
||||||
|
#endif /* TABLING */
|
||||||
|
|
||||||
#if THREADS
|
#if THREADS
|
||||||
|
|
||||||
@ -174,6 +177,20 @@ kill_thread_engine (int wid, int always_die)
|
|||||||
static void
|
static void
|
||||||
thread_die(int wid, int always_die)
|
thread_die(int wid, int always_die)
|
||||||
{
|
{
|
||||||
|
#ifdef TABLING
|
||||||
|
CACHE_REGS
|
||||||
|
tab_ent_ptr tab_ent;
|
||||||
|
|
||||||
|
tab_ent = GLOBAL_root_tab_ent;
|
||||||
|
while (tab_ent) {
|
||||||
|
abolish_table(tab_ent);
|
||||||
|
tab_ent = TabEnt_next(tab_ent);
|
||||||
|
}
|
||||||
|
FREE_DEPENDENCY_FRAME(LOCAL_top_dep_fr);
|
||||||
|
#endif /* TABLING */
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
|
fclose(LOCAL_thread_output);
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
if (!always_die) {
|
if (!always_die) {
|
||||||
/* called by thread itself */
|
/* called by thread itself */
|
||||||
GLOBAL_ThreadsTotalTime += Yap_cputime();
|
GLOBAL_ThreadsTotalTime += Yap_cputime();
|
||||||
@ -208,7 +225,7 @@ setup_engine(int myworker_id, int init_thread)
|
|||||||
DEBUG_TLOCK_ACCESS(2, myworker_id);
|
DEBUG_TLOCK_ACCESS(2, myworker_id);
|
||||||
pthread_mutex_unlock(&(REMOTE_ThreadHandle(myworker_id).tlock));
|
pthread_mutex_unlock(&(REMOTE_ThreadHandle(myworker_id).tlock));
|
||||||
#ifdef TABLING
|
#ifdef TABLING
|
||||||
DepFr_cons_cp(LOCAL_top_dep_fr) = B; /* same as in Yap_init_root_frames() */
|
new_dependency_frame(LOCAL_top_dep_fr, FALSE, NULL, NULL, B, NULL, FALSE, NULL); /* same as in Yap_init_root_frames() */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -226,7 +243,14 @@ thread_run(void *widp)
|
|||||||
Term tgoal, t;
|
Term tgoal, t;
|
||||||
Term tgs[2];
|
Term tgs[2];
|
||||||
int myworker_id = *((int *)widp);
|
int myworker_id = *((int *)widp);
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
|
char thread_name[25];
|
||||||
|
char filename[YAP_FILENAME_MAX];
|
||||||
|
sprintf(thread_name, "/thread_output_%d", myworker_id);
|
||||||
|
strcpy(filename, YAP_BINDIR);
|
||||||
|
strncat(filename, thread_name, 25);
|
||||||
|
LOCAL_thread_output = fopen(filename, "w");
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
start_thread(myworker_id);
|
start_thread(myworker_id);
|
||||||
regcache = ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key));
|
regcache = ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key));
|
||||||
do {
|
do {
|
||||||
@ -772,8 +796,8 @@ p_thread_stacks( USES_REGS1 )
|
|||||||
Int status= TRUE;
|
Int status= TRUE;
|
||||||
|
|
||||||
LOCK(GLOBAL_ThreadHandlesLock);
|
LOCK(GLOBAL_ThreadHandlesLock);
|
||||||
if (!REMOTE_ThreadHandle(tid).in_use &&
|
if (!Yap_local[tid] ||
|
||||||
!REMOTE_ThreadHandle(tid).zombie) {
|
(!REMOTE_ThreadHandle(tid).in_use && !REMOTE_ThreadHandle(tid).zombie)) {
|
||||||
UNLOCK(GLOBAL_ThreadHandlesLock);
|
UNLOCK(GLOBAL_ThreadHandlesLock);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -344,6 +344,9 @@
|
|||||||
OPCODE(table_new_answer ,s),
|
OPCODE(table_new_answer ,s),
|
||||||
OPCODE(table_answer_resolution ,Otapl),
|
OPCODE(table_answer_resolution ,Otapl),
|
||||||
OPCODE(table_completion ,Otapl),
|
OPCODE(table_completion ,Otapl),
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
OPCODE(table_answer_resolution_completion,Otapl),
|
||||||
|
#endif
|
||||||
OPCODE(trie_do_var ,e),
|
OPCODE(trie_do_var ,e),
|
||||||
OPCODE(trie_trust_var ,e),
|
OPCODE(trie_trust_var ,e),
|
||||||
OPCODE(trie_try_var ,e),
|
OPCODE(trie_try_var ,e),
|
||||||
|
@ -179,6 +179,9 @@
|
|||||||
#define TRY_ANSWER Yap_heap_regs->table_try_answer_code
|
#define TRY_ANSWER Yap_heap_regs->table_try_answer_code
|
||||||
#define ANSWER_RESOLUTION Yap_heap_regs->table_answer_resolution_code
|
#define ANSWER_RESOLUTION Yap_heap_regs->table_answer_resolution_code
|
||||||
#define COMPLETION Yap_heap_regs->table_completion_code
|
#define COMPLETION Yap_heap_regs->table_completion_code
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
#define ANSWER_RESOLUTION_COMPLETION Yap_heap_regs->table_answer_resolution_completion_code
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,6 +179,9 @@
|
|||||||
yamop table_try_answer_code[1];
|
yamop table_try_answer_code[1];
|
||||||
yamop table_answer_resolution_code[1];
|
yamop table_answer_resolution_code[1];
|
||||||
yamop table_completion_code[1];
|
yamop table_completion_code[1];
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
yamop table_answer_resolution_completion_code[1];
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,6 +179,9 @@
|
|||||||
InitOtaplInst(TRY_ANSWER,_table_try_answer,PredFail);
|
InitOtaplInst(TRY_ANSWER,_table_try_answer,PredFail);
|
||||||
InitOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail);
|
InitOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail);
|
||||||
InitOtaplInst(COMPLETION,_table_completion,PredFail);
|
InitOtaplInst(COMPLETION,_table_completion,PredFail);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
InitOtaplInst(ANSWER_RESOLUTION_COMPLETION,_table_answer_resolution_completion,PredFail);
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
|
|
||||||
|
@ -815,6 +815,9 @@ restore_opcodes(yamop *pc, yamop *max USES_REGS)
|
|||||||
/* instructions type Otapl */
|
/* instructions type Otapl */
|
||||||
case _table_answer_resolution:
|
case _table_answer_resolution:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
case _table_load_answer:
|
case _table_load_answer:
|
||||||
case _table_retry:
|
case _table_retry:
|
||||||
case _table_retry_me:
|
case _table_retry_me:
|
||||||
|
@ -179,6 +179,9 @@
|
|||||||
RestoreOtaplInst(TRY_ANSWER,_table_try_answer,PredFail);
|
RestoreOtaplInst(TRY_ANSWER,_table_try_answer,PredFail);
|
||||||
RestoreOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail);
|
RestoreOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail);
|
||||||
RestoreOtaplInst(COMPLETION,_table_completion,PredFail);
|
RestoreOtaplInst(COMPLETION,_table_completion,PredFail);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
RestoreOtaplInst(ANSWER_RESOLUTION_COMPLETION,_table_answer_resolution_completion,PredFail);
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
|
|
||||||
|
@ -835,6 +835,9 @@
|
|||||||
/* instructions type Otapl */
|
/* instructions type Otapl */
|
||||||
case _table_answer_resolution:
|
case _table_answer_resolution:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
case _table_load_answer:
|
case _table_load_answer:
|
||||||
case _table_retry:
|
case _table_retry:
|
||||||
case _table_retry_me:
|
case _table_retry_me:
|
||||||
|
@ -614,6 +614,9 @@
|
|||||||
/* instructions type Otapl */
|
/* instructions type Otapl */
|
||||||
case _table_answer_resolution:
|
case _table_answer_resolution:
|
||||||
case _table_completion:
|
case _table_completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
case _table_answer_resolution_completion:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
case _table_load_answer:
|
case _table_load_answer:
|
||||||
case _table_retry:
|
case _table_retry:
|
||||||
case _table_retry_me:
|
case _table_retry_me:
|
||||||
|
@ -22,8 +22,9 @@
|
|||||||
****************************/
|
****************************/
|
||||||
#define MAX_TABLE_VARS 1000
|
#define MAX_TABLE_VARS 1000
|
||||||
#define TRIE_LOCK_BUCKETS 512
|
#define TRIE_LOCK_BUCKETS 512
|
||||||
#define THREADS_FIRST_LEVEL_BUCKETS 16
|
#define THREADS_DIRECT_BUCKETS 32
|
||||||
#define THREADS_SECOND_LEVEL_BUCKETS (MAX_THREADS / THREADS_FIRST_LEVEL_BUCKETS) /* 64 (1024/16) */
|
#define THREADS_INDIRECT_BUCKETS ((MAX_THREADS - THREADS_DIRECT_BUCKETS) / THREADS_DIRECT_BUCKETS) /* (1024 - 32) / 32 = 31 */
|
||||||
|
#define THREADS_NUM_BUCKETS (THREADS_DIRECT_BUCKETS + THREADS_INDIRECT_BUCKETS)
|
||||||
#define TG_ANSWER_SLOTS 20
|
#define TG_ANSWER_SLOTS 20
|
||||||
#define MAX_LENGTH_ANSWER 1000
|
#define MAX_LENGTH_ANSWER 1000
|
||||||
#define MAX_BRANCH_DEPTH 1000
|
#define MAX_BRANCH_DEPTH 1000
|
||||||
@ -48,9 +49,9 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
** multithreading design for tabling (mandatory, define one) **
|
** multithreading design for tabling (mandatory, define one) **
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#define THREADS_NO_SHARING 1
|
//#define THREADS_NO_SHARING 1
|
||||||
/* #define THREADS_SUBGOAL_SHARING 1 */
|
#define THREADS_SUBGOAL_SHARING 1
|
||||||
/* #define THREADS_FULL_SHARING 1 */
|
//#define THREADS_FULL_SHARING 1
|
||||||
/* #define THREADS_CONSUMER_SHARING 1 */
|
/* #define THREADS_CONSUMER_SHARING 1 */
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@ -327,11 +328,7 @@
|
|||||||
#undef TIMESTAMP_CHECK
|
#undef TIMESTAMP_CHECK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TABLING) && defined(THREADS)
|
#if !defined(TABLING) || !defined(THREADS)
|
||||||
#if THREADS_FIRST_LEVEL_BUCKETS > THREADS_SECOND_LEVEL_BUCKETS
|
|
||||||
#error THREADS_FIRST_LEVEL_BUCKETS cannot exceed THREADS_SECOND_LEVEL_BUCKETS
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#undef OUTPUT_THREADS_TABLING
|
#undef OUTPUT_THREADS_TABLING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -344,10 +341,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(YAPOR) || defined(THREADS)
|
||||||
|
#undef MODE_DIRECTED_TABLING
|
||||||
#undef TABLING_EARLY_COMPLETION
|
#undef TABLING_EARLY_COMPLETION
|
||||||
#undef INCOMPLETE_TABLING
|
#undef INCOMPLETE_TABLING
|
||||||
#undef LIMIT_TABLING
|
#undef LIMIT_TABLING
|
||||||
#undef DETERMINISTIC_TABLING
|
#undef DETERMINISTIC_TABLING
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ void Yap_init_global_optyap_data(int max_table_size, int n_workers, int sch_loop
|
|||||||
GLOBAL_check_sg_fr = NULL;
|
GLOBAL_check_sg_fr = NULL;
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
#ifdef YAPOR
|
#ifdef YAPOR
|
||||||
new_dependency_frame(GLOBAL_root_dep_fr, FALSE, NULL, NULL, NULL, NULL, NULL);
|
new_dependency_frame(GLOBAL_root_dep_fr, FALSE, NULL, NULL, NULL, NULL, FALSE, NULL);
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
for (i = 0; i < MAX_TABLE_VARS; i++) {
|
for (i = 0; i < MAX_TABLE_VARS; i++) {
|
||||||
CELL *pt = GLOBAL_table_var_enumerator_addr(i);
|
CELL *pt = GLOBAL_table_var_enumerator_addr(i);
|
||||||
@ -165,7 +165,9 @@ void Yap_init_global_optyap_data(int max_table_size, int n_workers, int sch_loop
|
|||||||
|
|
||||||
|
|
||||||
void Yap_init_local_optyap_data(int wid) {
|
void Yap_init_local_optyap_data(int wid) {
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
#if defined(TABLING) && (defined(YAPOR) || defined(THREADS))
|
#if defined(TABLING) && (defined(YAPOR) || defined(THREADS))
|
||||||
/* local data related to memory management */
|
/* local data related to memory management */
|
||||||
@ -216,9 +218,13 @@ void Yap_init_local_optyap_data(int wid) {
|
|||||||
REMOTE_top_dep_fr(wid) = GLOBAL_root_dep_fr;
|
REMOTE_top_dep_fr(wid) = GLOBAL_root_dep_fr;
|
||||||
Set_REMOTE_top_cp_on_stack(wid, (choiceptr) LOCAL_LocalBase); /* ??? */
|
Set_REMOTE_top_cp_on_stack(wid, (choiceptr) LOCAL_LocalBase); /* ??? */
|
||||||
REMOTE_top_susp_or_fr(wid) = GLOBAL_root_or_fr;
|
REMOTE_top_susp_or_fr(wid) = GLOBAL_root_or_fr;
|
||||||
#else
|
|
||||||
new_dependency_frame(REMOTE_top_dep_fr(wid), FALSE, NULL, NULL, NULL, NULL, NULL);
|
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) = 0;
|
||||||
|
ThDepFr_next(GLOBAL_th_dep_fr(wid)) = wid;
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
INIT_LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid)));
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -256,7 +262,7 @@ void Yap_init_root_frames(void) {
|
|||||||
#ifdef YAPOR
|
#ifdef YAPOR
|
||||||
DepFr_cons_cp(GLOBAL_root_dep_fr) = B; /* with YAPOR, at that point, LOCAL_top_dep_fr shouldn't be the same as GLOBAL_root_dep_fr ? */
|
DepFr_cons_cp(GLOBAL_root_dep_fr) = B; /* with YAPOR, at that point, LOCAL_top_dep_fr shouldn't be the same as GLOBAL_root_dep_fr ? */
|
||||||
#else
|
#else
|
||||||
DepFr_cons_cp(LOCAL_top_dep_fr) = B;
|
new_dependency_frame(LOCAL_top_dep_fr, FALSE, NULL, NULL, B, NULL, FALSE, NULL);
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
}
|
}
|
||||||
|
@ -76,14 +76,19 @@ extern int Yap_page_size;
|
|||||||
free(block_ptr); \
|
free(block_ptr); \
|
||||||
}
|
}
|
||||||
#endif /******************************************************************************/
|
#endif /******************************************************************************/
|
||||||
#define ALLOC_HASH_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \
|
#define INIT_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \
|
||||||
{ int i; void **bucket_ptr; \
|
{ int i; void **init_bucket_ptr; \
|
||||||
ALLOC_BLOCK(bucket_ptr, NUM_BUCKETS * sizeof(void *), void *); \
|
init_bucket_ptr = (void **) BUCKET_PTR; \
|
||||||
BUCKET_PTR = (void *) bucket_ptr; \
|
|
||||||
for (i = NUM_BUCKETS; i != 0; i--) \
|
for (i = NUM_BUCKETS; i != 0; i--) \
|
||||||
*bucket_ptr++ = NULL; \
|
*init_bucket_ptr++ = NULL; \
|
||||||
}
|
}
|
||||||
#define FREE_HASH_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR)
|
#define ALLOC_BUCKETS(BUCKET_PTR, NUM_BUCKETS) \
|
||||||
|
{ void **alloc_bucket_ptr; \
|
||||||
|
ALLOC_BLOCK(alloc_bucket_ptr, NUM_BUCKETS * sizeof(void *), void *); \
|
||||||
|
INIT_BUCKETS(alloc_bucket_ptr, NUM_BUCKETS); \
|
||||||
|
BUCKET_PTR = (void *) alloc_bucket_ptr; \
|
||||||
|
}
|
||||||
|
#define FREE_BUCKETS(BUCKET_PTR) FREE_BLOCK(BUCKET_PTR)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -435,3 +440,13 @@ extern int Yap_page_size;
|
|||||||
#else
|
#else
|
||||||
#define OPTYAP_ERROR_CHECKING(PROCEDURE,TEST)
|
#define OPTYAP_ERROR_CHECKING(PROCEDURE,TEST)
|
||||||
#endif /* DEBUG_OPTYAP */
|
#endif /* DEBUG_OPTYAP */
|
||||||
|
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
|
#define INFO_THREADS(MESSAGE, ARGS...) \
|
||||||
|
fprintf(LOCAL_thread_output, "[ " MESSAGE " ]\n", ##ARGS)
|
||||||
|
#define INFO_THREADS_MAIN_THREAD(MESSAGE, ARGS...) \
|
||||||
|
Sfprintf(Serror, "[ " MESSAGE " ]\n", ##ARGS)
|
||||||
|
#else
|
||||||
|
#define INFO_THREADS(MESG, ARGS...)
|
||||||
|
#define INFO_THREADS_MAIN_THREAD(MESSAGE, ARGS...)
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
|
@ -42,11 +42,9 @@ static Int p_table( USES_REGS1 );
|
|||||||
static Int p_tabling_mode( USES_REGS1 );
|
static Int p_tabling_mode( USES_REGS1 );
|
||||||
static Int p_abolish_table( USES_REGS1 );
|
static Int p_abolish_table( USES_REGS1 );
|
||||||
static Int p_abolish_all_tables( USES_REGS1 );
|
static Int p_abolish_all_tables( USES_REGS1 );
|
||||||
static Int p_abolish_all_local_tables( USES_REGS1 );
|
|
||||||
static Int p_show_tabled_predicates( USES_REGS1 );
|
static Int p_show_tabled_predicates( USES_REGS1 );
|
||||||
static Int p_show_table( USES_REGS1 );
|
static Int p_show_table( USES_REGS1 );
|
||||||
static Int p_show_all_tables( USES_REGS1 );
|
static Int p_show_all_tables( USES_REGS1 );
|
||||||
static Int p_show_all_local_tables( USES_REGS1 );
|
|
||||||
static Int p_show_global_trie( USES_REGS1 );
|
static Int p_show_global_trie( USES_REGS1 );
|
||||||
static Int p_show_statistics_table( USES_REGS1 );
|
static Int p_show_statistics_table( USES_REGS1 );
|
||||||
static Int p_show_statistics_tabling( USES_REGS1 );
|
static Int p_show_statistics_tabling( USES_REGS1 );
|
||||||
@ -185,7 +183,7 @@ struct page_statistics {
|
|||||||
INCREMENT_PAGE_STATS(STATS, STR_PAGES(wid)); \
|
INCREMENT_PAGE_STATS(STATS, STR_PAGES(wid)); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
UNLOCK(GLOBAL_ThreadHandlesLock); \
|
UNLOCK(GLOBAL_ThreadHandlesLock); \
|
||||||
Pg_bytes_in_use(STATS) = Pg_str_in_use(STATS) * sizeof(STR_TYPE)
|
Pg_bytes_in_use(STATS) = Pg_str_in_use(STATS) * sizeof(STR_TYPE)
|
||||||
|
|
||||||
@ -218,11 +216,9 @@ void Yap_init_optyap_preds(void) {
|
|||||||
Yap_InitCPred("$c_tabling_mode", 3, p_tabling_mode, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
Yap_InitCPred("$c_tabling_mode", 3, p_tabling_mode, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
||||||
Yap_InitCPred("$c_abolish_table", 2, p_abolish_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
Yap_InitCPred("$c_abolish_table", 2, p_abolish_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
||||||
Yap_InitCPred("abolish_all_tables", 0, p_abolish_all_tables, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("abolish_all_tables", 0, p_abolish_all_tables, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("abolish_all_local_tables", 0, p_abolish_all_local_tables, SafePredFlag|SyncPredFlag);
|
|
||||||
Yap_InitCPred("show_tabled_predicates", 1, p_show_tabled_predicates, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("show_tabled_predicates", 1, p_show_tabled_predicates, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("$c_show_table", 3, p_show_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
Yap_InitCPred("$c_show_table", 3, p_show_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
||||||
Yap_InitCPred("show_all_tables", 1, p_show_all_tables, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("show_all_tables", 1, p_show_all_tables, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("show_all_local_tables", 1, p_show_all_local_tables, SafePredFlag|SyncPredFlag);
|
|
||||||
Yap_InitCPred("show_global_trie", 1, p_show_global_trie, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("show_global_trie", 1, p_show_global_trie, SafePredFlag|SyncPredFlag);
|
||||||
Yap_InitCPred("$c_table_statistics", 3, p_show_statistics_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
Yap_InitCPred("$c_table_statistics", 3, p_show_statistics_table, SafePredFlag|SyncPredFlag|HiddenPredFlag);
|
||||||
Yap_InitCPred("tabling_statistics", 1, p_show_statistics_tabling, SafePredFlag|SyncPredFlag);
|
Yap_InitCPred("tabling_statistics", 1, p_show_statistics_tabling, SafePredFlag|SyncPredFlag);
|
||||||
@ -467,8 +463,6 @@ static Int p_tabling_mode( USES_REGS1 ) {
|
|||||||
static Int p_abolish_table( USES_REGS1 ) {
|
static Int p_abolish_table( USES_REGS1 ) {
|
||||||
Term mod, t;
|
Term mod, t;
|
||||||
tab_ent_ptr tab_ent;
|
tab_ent_ptr tab_ent;
|
||||||
sg_hash_ptr hash;
|
|
||||||
sg_node_ptr sg_node;
|
|
||||||
|
|
||||||
mod = Deref(ARG1);
|
mod = Deref(ARG1);
|
||||||
t = Deref(ARG2);
|
t = Deref(ARG2);
|
||||||
@ -478,67 +472,23 @@ static Int p_abolish_table( USES_REGS1 ) {
|
|||||||
tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
|
tab_ent = RepPredProp(PredPropByFunc(FunctorOfTerm(t), mod))->TableOfPred;
|
||||||
else
|
else
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
hash = TabEnt_hash_chain(tab_ent);
|
abolish_table(tab_ent);
|
||||||
TabEnt_hash_chain(tab_ent) = NULL;
|
|
||||||
free_subgoal_hash_chain(hash);
|
|
||||||
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
|
|
||||||
if (sg_node) {
|
|
||||||
if (TabEnt_arity(tab_ent)) {
|
|
||||||
free_subgoal_trie(sg_node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
|
||||||
} else {
|
|
||||||
sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(sg_node);
|
|
||||||
FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
|
|
||||||
#ifdef LIMIT_TABLING
|
|
||||||
remove_from_global_sg_fr_list(sg_fr);
|
|
||||||
#endif /* LIMIT_TABLING */
|
|
||||||
FREE_SUBGOAL_FRAME(sg_fr);
|
|
||||||
}
|
|
||||||
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
|
|
||||||
}
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int p_abolish_all_tables( USES_REGS1 ) {
|
static Int p_abolish_all_tables( USES_REGS1 ) {
|
||||||
tab_ent_ptr tab_ent;
|
tab_ent_ptr tab_ent;
|
||||||
sg_hash_ptr hash;
|
|
||||||
sg_node_ptr sg_node;
|
|
||||||
|
|
||||||
tab_ent = GLOBAL_root_tab_ent;
|
tab_ent = GLOBAL_root_tab_ent;
|
||||||
while (tab_ent) {
|
while (tab_ent) {
|
||||||
hash = TabEnt_hash_chain(tab_ent);
|
abolish_table(tab_ent);
|
||||||
TabEnt_hash_chain(tab_ent) = NULL;
|
|
||||||
free_subgoal_hash_chain(hash);
|
|
||||||
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
|
|
||||||
if (sg_node) {
|
|
||||||
if (TabEnt_arity(tab_ent)) {
|
|
||||||
free_subgoal_trie(sg_node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
|
||||||
} else {
|
|
||||||
sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(sg_node);
|
|
||||||
FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
|
|
||||||
#ifdef LIMIT_TABLING
|
|
||||||
remove_from_global_sg_fr_list(sg_fr);
|
|
||||||
#endif /* LIMIT_TABLING */
|
|
||||||
FREE_SUBGOAL_FRAME(sg_fr);
|
|
||||||
}
|
|
||||||
TrNode_child(TabEnt_subgoal_trie(tab_ent)) = NULL;
|
|
||||||
}
|
|
||||||
tab_ent = TabEnt_next(tab_ent);
|
tab_ent = TabEnt_next(tab_ent);
|
||||||
}
|
}
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int p_abolish_all_local_tables( USES_REGS1 ) {
|
|
||||||
#ifdef THREADS
|
|
||||||
p_abolish_all_tables( PASS_REGS1 );
|
|
||||||
#else
|
|
||||||
p_abolish_all_tables();
|
|
||||||
#endif /* THREADS */
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Int p_show_tabled_predicates( USES_REGS1 ) {
|
static Int p_show_tabled_predicates( USES_REGS1 ) {
|
||||||
IOSTREAM *out;
|
IOSTREAM *out;
|
||||||
tab_ent_ptr tab_ent;
|
tab_ent_ptr tab_ent;
|
||||||
@ -597,26 +547,6 @@ static Int p_show_all_tables( USES_REGS1 ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Int p_show_all_local_tables( USES_REGS1 ) {
|
|
||||||
#ifdef THREADS
|
|
||||||
IOSTREAM *out;
|
|
||||||
tab_ent_ptr tab_ent;
|
|
||||||
|
|
||||||
if (!PL_get_stream_handle(Yap_InitSlot(Deref(ARG1) PASS_REGS), &out))
|
|
||||||
return (FALSE);
|
|
||||||
tab_ent = GLOBAL_root_tab_ent;
|
|
||||||
while(tab_ent) {
|
|
||||||
show_table(tab_ent, SHOW_MODE_STRUCTURE, out);
|
|
||||||
tab_ent = TabEnt_next(tab_ent);
|
|
||||||
}
|
|
||||||
PL_release_stream(out);
|
|
||||||
#else
|
|
||||||
p_show_all_tables();
|
|
||||||
#endif /* THREADS */
|
|
||||||
return (TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Int p_show_global_trie( USES_REGS1 ) {
|
static Int p_show_global_trie( USES_REGS1 ) {
|
||||||
IOSTREAM *out;
|
IOSTREAM *out;
|
||||||
|
|
||||||
@ -1197,12 +1127,14 @@ static inline struct page_statistics show_statistics_table_entries(IOSTREAM *out
|
|||||||
SHOW_GLOBAL_PAGE_STATS(out, struct table_entry, GLOBAL_pages_tab_ent, "Table entries: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct table_entry, GLOBAL_pages_tab_ent, "Table entries: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
static inline struct page_statistics show_statistics_subgoal_entries(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_subgoal_entries(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_entry, GLOBAL_pages_sg_ent, "Subgoal entries: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_entry, GLOBAL_pages_sg_ent, "Subgoal entries: ");
|
||||||
}
|
}
|
||||||
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_subgoal_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_subgoal_frames(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
|
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_frame, GLOBAL_pages_sg_fr, "Subgoal frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_frame, GLOBAL_pages_sg_fr, "Subgoal frames: ");
|
||||||
@ -1211,6 +1143,7 @@ static inline struct page_statistics show_statistics_subgoal_frames(IOSTREAM *ou
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_dependency_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_dependency_frames(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
|
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING) && !defined(THREADS_FULL_SHARING) && !defined(THREADS_CONSUMER_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct dependency_frame, GLOBAL_pages_dep_fr, "Dependency frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct dependency_frame, GLOBAL_pages_dep_fr, "Dependency frames: ");
|
||||||
@ -1219,6 +1152,7 @@ static inline struct page_statistics show_statistics_dependency_frames(IOSTREAM
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_subgoal_trie_nodes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_subgoal_trie_nodes(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING)
|
#if !defined(THREADS_NO_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_trie_node, GLOBAL_pages_sg_node, "Subgoal trie nodes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_trie_node, GLOBAL_pages_sg_node, "Subgoal trie nodes: ");
|
||||||
@ -1227,6 +1161,7 @@ static inline struct page_statistics show_statistics_subgoal_trie_nodes(IOSTREAM
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_subgoal_trie_hashes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_subgoal_trie_hashes(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING)
|
#if !defined(THREADS_NO_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_trie_hash, GLOBAL_pages_sg_hash, "Subgoal trie hashes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct subgoal_trie_hash, GLOBAL_pages_sg_hash, "Subgoal trie hashes: ");
|
||||||
@ -1235,6 +1170,7 @@ static inline struct page_statistics show_statistics_subgoal_trie_hashes(IOSTREA
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_answer_trie_nodes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_answer_trie_nodes(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING)
|
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct answer_trie_node, GLOBAL_pages_ans_node, "Answer trie nodes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct answer_trie_node, GLOBAL_pages_ans_node, "Answer trie nodes: ");
|
||||||
@ -1243,6 +1179,7 @@ static inline struct page_statistics show_statistics_answer_trie_nodes(IOSTREAM
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_answer_trie_hashes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_answer_trie_hashes(IOSTREAM *out) {
|
||||||
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING)
|
#if !defined(THREADS_NO_SHARING) && !defined(THREADS_SUBGOAL_SHARING)
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct answer_trie_hash, GLOBAL_pages_ans_hash, "Answer trie hashes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct answer_trie_hash, GLOBAL_pages_ans_hash, "Answer trie hashes: ");
|
||||||
@ -1251,16 +1188,19 @@ static inline struct page_statistics show_statistics_answer_trie_hashes(IOSTREAM
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(THREADS_FULL_SHARING)
|
#if defined(THREADS_FULL_SHARING)
|
||||||
static inline struct page_statistics show_statistics_answer_ref_nodes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_answer_ref_nodes(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct answer_ref_node, REMOTE_pages_ans_ref_node, "Answer ref nodes: ");
|
SHOW_REMOTE_PAGE_STATS(out, struct answer_ref_node, REMOTE_pages_ans_ref_node, "Answer ref nodes: ");
|
||||||
}
|
}
|
||||||
#endif /* THREADS_FULL_SHARING */
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_global_trie_nodes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_global_trie_nodes(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct global_trie_node, GLOBAL_pages_gt_node, "Global trie nodes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct global_trie_node, GLOBAL_pages_gt_node, "Global trie nodes: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_global_trie_hashes(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_global_trie_hashes(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct global_trie_hash, GLOBAL_pages_gt_hash, "Global trie hashes: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct global_trie_hash, GLOBAL_pages_gt_hash, "Global trie hashes: ");
|
||||||
}
|
}
|
||||||
@ -1272,10 +1212,12 @@ static inline struct page_statistics show_statistics_or_frames(IOSTREAM *out) {
|
|||||||
SHOW_GLOBAL_PAGE_STATS(out, struct or_frame, GLOBAL_pages_or_fr, "Or-frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct or_frame, GLOBAL_pages_or_fr, "Or-frames: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_query_goal_solution_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_query_goal_solution_frames(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct query_goal_solution_frame, GLOBAL_pages_qg_sol_fr, "Query goal solution frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct query_goal_solution_frame, GLOBAL_pages_qg_sol_fr, "Query goal solution frames: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_query_goal_answer_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_query_goal_answer_frames(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct query_goal_answer_frame, GLOBAL_pages_qg_ans_fr, "Query goal answer frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct query_goal_answer_frame, GLOBAL_pages_qg_ans_fr, "Query goal answer frames: ");
|
||||||
}
|
}
|
||||||
@ -1287,11 +1229,13 @@ static inline struct page_statistics show_statistics_suspension_frames(IOSTREAM
|
|||||||
SHOW_GLOBAL_PAGE_STATS(out, struct suspension_frame, GLOBAL_pages_susp_fr, "Suspension frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct suspension_frame, GLOBAL_pages_susp_fr, "Suspension frames: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TABLING_INNER_CUTS
|
#ifdef TABLING_INNER_CUTS
|
||||||
static inline struct page_statistics show_statistics_table_subgoal_solution_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_table_subgoal_solution_frames(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct table_subgoal_solution_frame, GLOBAL_pages_tg_sol_fr, "Table subgoal solution frames:");
|
SHOW_GLOBAL_PAGE_STATS(out, struct table_subgoal_solution_frame, GLOBAL_pages_tg_sol_fr, "Table subgoal solution frames:");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline struct page_statistics show_statistics_table_subgoal_answer_frames(IOSTREAM *out) {
|
static inline struct page_statistics show_statistics_table_subgoal_answer_frames(IOSTREAM *out) {
|
||||||
SHOW_GLOBAL_PAGE_STATS(out, struct table_subgoal_answer_frame, GLOBAL_pages_tg_ans_fr, "Table subgoal answer frames: ");
|
SHOW_GLOBAL_PAGE_STATS(out, struct table_subgoal_answer_frame, GLOBAL_pages_tg_ans_fr, "Table subgoal answer frames: ");
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,8 @@ CELL *exec_substitution(gt_node_ptr, CELL *);
|
|||||||
void update_answer_trie(sg_fr_ptr);
|
void update_answer_trie(sg_fr_ptr);
|
||||||
void free_subgoal_trie(sg_node_ptr, int, int);
|
void free_subgoal_trie(sg_node_ptr, int, int);
|
||||||
void free_answer_trie(ans_node_ptr, int, int);
|
void free_answer_trie(ans_node_ptr, int, int);
|
||||||
void free_subgoal_hash_chain(sg_hash_ptr);
|
|
||||||
void free_answer_hash_chain(ans_hash_ptr);
|
void free_answer_hash_chain(ans_hash_ptr);
|
||||||
|
void abolish_table(tab_ent_ptr);
|
||||||
void show_table(tab_ent_ptr, int, IOSTREAM *);
|
void show_table(tab_ent_ptr, int, IOSTREAM *);
|
||||||
void show_global_trie(int, IOSTREAM *);
|
void show_global_trie(int, IOSTREAM *);
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
@ -466,6 +466,9 @@ struct local_optyap_data {
|
|||||||
#endif /* YAPOR_THREADS */
|
#endif /* YAPOR_THREADS */
|
||||||
struct or_frame *top_or_frame_with_suspensions;
|
struct or_frame *top_or_frame_with_suspensions;
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
|
FILE *thread_output;
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
#if (defined(TABLING) || !defined(YAPOR_COW)) && defined(MULTI_ASSIGNMENT_VARIABLES)
|
#if (defined(TABLING) || !defined(YAPOR_COW)) && defined(MULTI_ASSIGNMENT_VARIABLES)
|
||||||
@ -529,6 +532,7 @@ struct local_optyap_data {
|
|||||||
#define Set_LOCAL_top_cp_on_stack(cpt) (LOCAL_optyap_data.top_choice_point_on_stack = cpt)
|
#define Set_LOCAL_top_cp_on_stack(cpt) (LOCAL_optyap_data.top_choice_point_on_stack = cpt)
|
||||||
#endif /* YAPOR_THREADS */
|
#endif /* YAPOR_THREADS */
|
||||||
#define LOCAL_top_susp_or_fr (LOCAL_optyap_data.top_or_frame_with_suspensions)
|
#define LOCAL_top_susp_or_fr (LOCAL_optyap_data.top_or_frame_with_suspensions)
|
||||||
|
#define LOCAL_thread_output (LOCAL_optyap_data.thread_output)
|
||||||
#define LOCAL_ma_timestamp (LOCAL_optyap_data.ma_timestamp)
|
#define LOCAL_ma_timestamp (LOCAL_optyap_data.ma_timestamp)
|
||||||
#define LOCAL_ma_h_top (LOCAL_optyap_data.ma_h_top)
|
#define LOCAL_ma_h_top (LOCAL_optyap_data.ma_h_top)
|
||||||
#define LOCAL_ma_hash_table (LOCAL_optyap_data.ma_hash_table)
|
#define LOCAL_ma_hash_table (LOCAL_optyap_data.ma_hash_table)
|
||||||
@ -585,7 +589,10 @@ struct local_optyap_data {
|
|||||||
#define Set_REMOTE_top_cp_on_stack(wid, bptr) (REMOTE(wid)->optyap_data_.top_choice_point_on_stack = (bptr))
|
#define Set_REMOTE_top_cp_on_stack(wid, bptr) (REMOTE(wid)->optyap_data_.top_choice_point_on_stack = (bptr))
|
||||||
#endif /* YAPOR_THREADS */
|
#endif /* YAPOR_THREADS */
|
||||||
#define REMOTE_top_susp_or_fr(wid) (REMOTE(wid)->optyap_data_.top_or_frame_with_suspensions)
|
#define REMOTE_top_susp_or_fr(wid) (REMOTE(wid)->optyap_data_.top_or_frame_with_suspensions)
|
||||||
|
#define REMOTE_thread_output(wid) (REMOTE(wid)->optyap_data_.thread_output)
|
||||||
|
#define REMOTE_ma_timestamp(wid) (REMOTE(wid)->optyap_data_.ma_timestamp)
|
||||||
|
#define REMOTE_ma_h_top(wid) (REMOTE(wid)->optyap_data_.ma_h_top)
|
||||||
|
#define REMOTE_ma_hash_table(wid) (REMOTE(wid)->optyap_data_.ma_hash_table)
|
||||||
|
|
||||||
#ifdef YAPOR
|
#ifdef YAPOR
|
||||||
#include "or.structs.h"
|
#include "or.structs.h"
|
||||||
|
@ -105,6 +105,7 @@ static void complete_suspension_branch(susp_fr_ptr susp_fr, choiceptr top_cp, or
|
|||||||
|
|
||||||
void private_completion(sg_fr_ptr sg_fr) {
|
void private_completion(sg_fr_ptr sg_fr) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
|
||||||
/* complete subgoals */
|
/* complete subgoals */
|
||||||
#ifdef LIMIT_TABLING
|
#ifdef LIMIT_TABLING
|
||||||
sg_fr_ptr aux_sg_fr;
|
sg_fr_ptr aux_sg_fr;
|
||||||
@ -137,6 +138,11 @@ void private_completion(sg_fr_ptr sg_fr) {
|
|||||||
/* adjust freeze registers */
|
/* adjust freeze registers */
|
||||||
adjust_freeze_registers();
|
adjust_freeze_registers();
|
||||||
|
|
||||||
|
/* adjust thread dependency */
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(worker_id)) = working;
|
||||||
|
ThDepFr_next(GLOBAL_th_dep_fr(worker_id)) = worker_id;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,58 +22,58 @@
|
|||||||
#define store_low_level_trace_info(CP, TAB_ENT)
|
#define store_low_level_trace_info(CP, TAB_ENT)
|
||||||
#endif /* LOW_LEVEL_TRACER */
|
#endif /* LOW_LEVEL_TRACER */
|
||||||
|
|
||||||
#define TABLING_ERROR_CHECKING_STACK \
|
#define TABLING_ERROR_CHECKING_STACK \
|
||||||
TABLING_ERROR_CHECKING(store_node, Unsigned(H) + 1024 > Unsigned(B)); \
|
TABLING_ERROR_CHECKING(store_node, Unsigned(H) + 1024 > Unsigned(B)); \
|
||||||
TABLING_ERROR_CHECKING(store_node, Unsigned(H_FZ) + 1024 > Unsigned(B))
|
TABLING_ERROR_CHECKING(store_node, Unsigned(H_FZ) + 1024 > Unsigned(B))
|
||||||
|
|
||||||
|
|
||||||
#define store_generator_node(TAB_ENT, SG_FR, ARITY, AP) \
|
#define store_generator_node(TAB_ENT, SG_FR, ARITY, AP) \
|
||||||
{ register CELL *pt_args; \
|
{ register CELL *pt_args; \
|
||||||
register choiceptr gcp; \
|
register choiceptr gcp; \
|
||||||
/* store args */ \
|
/* store args */ \
|
||||||
pt_args = XREGS + (ARITY); \
|
pt_args = XREGS + (ARITY); \
|
||||||
while (pt_args > XREGS) { \
|
while (pt_args > XREGS) { \
|
||||||
register CELL aux_arg = pt_args[0]; \
|
register CELL aux_arg = pt_args[0]; \
|
||||||
--YENV; \
|
--YENV; \
|
||||||
--pt_args; \
|
--pt_args; \
|
||||||
*YENV = aux_arg; \
|
*YENV = aux_arg; \
|
||||||
} \
|
} \
|
||||||
/* initialize gcp and adjust subgoal frame field */ \
|
/* initialize gcp and adjust subgoal frame field */ \
|
||||||
YENV = (CELL *) (GEN_CP(YENV) - 1); \
|
YENV = (CELL *) (GEN_CP(YENV) - 1); \
|
||||||
gcp = NORM_CP(YENV); \
|
gcp = NORM_CP(YENV); \
|
||||||
SgFr_gen_cp(SG_FR) = gcp; \
|
SgFr_gen_cp(SG_FR) = gcp; \
|
||||||
/* store generator choice point */ \
|
/* store generator choice point */ \
|
||||||
HBREG = H; \
|
HBREG = H; \
|
||||||
store_yaam_reg_cpdepth(gcp); \
|
store_yaam_reg_cpdepth(gcp); \
|
||||||
gcp->cp_tr = TR; \
|
gcp->cp_tr = TR; \
|
||||||
gcp->cp_ap = (yamop *)(AP); \
|
gcp->cp_ap = (yamop *)(AP); \
|
||||||
gcp->cp_h = H; \
|
gcp->cp_h = H; \
|
||||||
gcp->cp_b = B; \
|
gcp->cp_b = B; \
|
||||||
gcp->cp_env = ENV; \
|
gcp->cp_env = ENV; \
|
||||||
gcp->cp_cp = CPREG; \
|
gcp->cp_cp = CPREG; \
|
||||||
if (IsMode_Local(TabEnt_mode(TAB_ENT))) { \
|
if (IsMode_Local(TabEnt_mode(TAB_ENT))) { \
|
||||||
/* go local */ \
|
/* go local */ \
|
||||||
register dep_fr_ptr new_dep_fr; \
|
register dep_fr_ptr new_dep_fr; \
|
||||||
/* adjust freeze registers */ \
|
/* adjust freeze registers */ \
|
||||||
H_FZ = H; \
|
H_FZ = H; \
|
||||||
B_FZ = gcp; \
|
B_FZ = gcp; \
|
||||||
TR_FZ = TR; \
|
TR_FZ = TR; \
|
||||||
/* store dependency frame */ \
|
/* store dependency frame */ \
|
||||||
new_dependency_frame(new_dep_fr, TRUE, LOCAL_top_or_fr, \
|
new_dependency_frame(new_dep_fr, TRUE, LOCAL_top_or_fr, gcp, \
|
||||||
gcp, gcp, SG_FR, LOCAL_top_dep_fr); \
|
gcp, SG_FR, FALSE, LOCAL_top_dep_fr); \
|
||||||
LOCAL_top_dep_fr = new_dep_fr; \
|
LOCAL_top_dep_fr = new_dep_fr; \
|
||||||
GEN_CP(gcp)->cp_dep_fr = LOCAL_top_dep_fr; \
|
GEN_CP(gcp)->cp_dep_fr = LOCAL_top_dep_fr; \
|
||||||
} else { \
|
} else { \
|
||||||
/* go batched */ \
|
/* go batched */ \
|
||||||
GEN_CP(gcp)->cp_dep_fr = NULL; \
|
GEN_CP(gcp)->cp_dep_fr = NULL; \
|
||||||
} \
|
} \
|
||||||
GEN_CP(gcp)->cp_sg_fr = SG_FR; \
|
GEN_CP(gcp)->cp_sg_fr = SG_FR; \
|
||||||
store_low_level_trace_info(GEN_CP(gcp), TAB_ENT); \
|
store_low_level_trace_info(GEN_CP(gcp), TAB_ENT); \
|
||||||
set_cut((CELL *)gcp, B); \
|
set_cut((CELL *)gcp, B); \
|
||||||
B = gcp; \
|
B = gcp; \
|
||||||
YAPOR_SET_LOAD(B); \
|
YAPOR_SET_LOAD(B); \
|
||||||
SET_BB(B); \
|
SET_BB(B); \
|
||||||
TABLING_ERROR_CHECKING_STACK; \
|
TABLING_ERROR_CHECKING_STACK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -102,6 +102,52 @@
|
|||||||
#endif /* DETERMINISTIC_TABLING */
|
#endif /* DETERMINISTIC_TABLING */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
#define store_generator_consumer_node(TAB_ENT, SG_FR, DEP_ON_STACK,ARITY) \
|
||||||
|
{ register CELL *pt_args; \
|
||||||
|
register choiceptr gccp; \
|
||||||
|
register dep_fr_ptr new_dep_fr; \
|
||||||
|
/* store args */ \
|
||||||
|
pt_args = XREGS + (ARITY); \
|
||||||
|
while (pt_args > XREGS) { \
|
||||||
|
register CELL aux_arg = pt_args[0]; \
|
||||||
|
--YENV; \
|
||||||
|
--pt_args; \
|
||||||
|
*YENV = aux_arg; \
|
||||||
|
} \
|
||||||
|
/* initialize gcp and adjust subgoal frame field */ \
|
||||||
|
YENV = (CELL *) (GEN_CP(YENV) - 1); \
|
||||||
|
gccp = NORM_CP(YENV); \
|
||||||
|
SgFr_gen_cp(SG_FR) = gccp; \
|
||||||
|
/* store generator choice point */ \
|
||||||
|
HBREG = H; \
|
||||||
|
store_yaam_reg_cpdepth(gccp); \
|
||||||
|
gccp->cp_tr = TR; \
|
||||||
|
gccp->cp_ap = ANSWER_RESOLUTION_COMPLETION; \
|
||||||
|
gccp->cp_h = H; \
|
||||||
|
gccp->cp_b = B; \
|
||||||
|
gccp->cp_env = ENV; \
|
||||||
|
gccp->cp_cp = CPREG; \
|
||||||
|
/* store dependency frame */ \
|
||||||
|
new_dependency_frame(new_dep_fr, DEP_ON_STACK, LOCAL_top_or_fr, \
|
||||||
|
gccp, gccp, SG_FR, TRUE, LOCAL_top_dep_fr); \
|
||||||
|
LOCAL_top_dep_fr = new_dep_fr; \
|
||||||
|
GEN_CP(gccp)->cp_dep_fr = LOCAL_top_dep_fr; \
|
||||||
|
GEN_CP(gccp)->cp_sg_fr = SG_FR; \
|
||||||
|
/* adjust freeze registers */ \
|
||||||
|
H_FZ = H; \
|
||||||
|
B_FZ = gccp; \
|
||||||
|
TR_FZ = TR; \
|
||||||
|
store_low_level_trace_info(GEN_CP(gccp), TAB_ENT); \
|
||||||
|
set_cut((CELL *)gccp, B); \
|
||||||
|
B = gccp; \
|
||||||
|
YAPOR_SET_LOAD(B); \
|
||||||
|
SET_BB(B); \
|
||||||
|
TABLING_ERROR_CHECKING_STACK; \
|
||||||
|
}
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
|
||||||
#define restore_generator_node(ARITY, AP) \
|
#define restore_generator_node(ARITY, AP) \
|
||||||
{ register CELL *pt_args, *x_args; \
|
{ register CELL *pt_args, *x_args; \
|
||||||
register choiceptr gcp = B; \
|
register choiceptr gcp = B; \
|
||||||
@ -149,39 +195,65 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define store_consumer_node(TAB_ENT, SG_FR, LEADER_CP, DEP_ON_STACK) \
|
#define store_consumer_node(TAB_ENT, SG_FR, LEADER_CP, DEP_ON_STACK) \
|
||||||
{ register choiceptr ccp; \
|
{ register choiceptr ccp; \
|
||||||
register dep_fr_ptr new_dep_fr; \
|
register dep_fr_ptr new_dep_fr; \
|
||||||
/* initialize ccp */ \
|
/* initialize ccp */ \
|
||||||
YENV = (CELL *) (CONS_CP(YENV) - 1); \
|
YENV = (CELL *) (CONS_CP(YENV) - 1); \
|
||||||
ccp = NORM_CP(YENV); \
|
ccp = NORM_CP(YENV); \
|
||||||
/* adjust freeze registers */ \
|
/* adjust freeze registers */ \
|
||||||
H_FZ = H; \
|
H_FZ = H; \
|
||||||
B_FZ = ccp; \
|
B_FZ = ccp; \
|
||||||
TR_FZ = TR; \
|
TR_FZ = TR; \
|
||||||
/* store dependency frame */ \
|
/* store dependency frame */ \
|
||||||
new_dependency_frame(new_dep_fr, DEP_ON_STACK, LOCAL_top_or_fr, \
|
new_dependency_frame(new_dep_fr, DEP_ON_STACK, LOCAL_top_or_fr, \
|
||||||
LEADER_CP, ccp, SG_FR, LOCAL_top_dep_fr); \
|
LEADER_CP, ccp, SG_FR, FALSE, LOCAL_top_dep_fr); \
|
||||||
LOCAL_top_dep_fr = new_dep_fr; \
|
LOCAL_top_dep_fr = new_dep_fr; \
|
||||||
/* store consumer choice point */ \
|
/* store consumer choice point */ \
|
||||||
HBREG = H; \
|
HBREG = H; \
|
||||||
store_yaam_reg_cpdepth(ccp); \
|
store_yaam_reg_cpdepth(ccp); \
|
||||||
ccp->cp_tr = TR; \
|
ccp->cp_tr = TR; \
|
||||||
ccp->cp_ap = ANSWER_RESOLUTION; \
|
ccp->cp_ap = ANSWER_RESOLUTION; \
|
||||||
ccp->cp_h = H; \
|
ccp->cp_h = H; \
|
||||||
ccp->cp_b = B; \
|
ccp->cp_b = B; \
|
||||||
ccp->cp_env= ENV; \
|
ccp->cp_env= ENV; \
|
||||||
ccp->cp_cp = CPREG; \
|
ccp->cp_cp = CPREG; \
|
||||||
CONS_CP(ccp)->cp_dep_fr = LOCAL_top_dep_fr; \
|
CONS_CP(ccp)->cp_dep_fr = LOCAL_top_dep_fr; \
|
||||||
store_low_level_trace_info(CONS_CP(ccp), TAB_ENT); \
|
store_low_level_trace_info(CONS_CP(ccp), TAB_ENT); \
|
||||||
/* set_cut((CELL *)ccp, B); --> no effect */ \
|
/* set_cut((CELL *)ccp, B); --> no effect */ \
|
||||||
B = ccp; \
|
B = ccp; \
|
||||||
YAPOR_SET_LOAD(B); \
|
YAPOR_SET_LOAD(B); \
|
||||||
SET_BB(B); \
|
SET_BB(B); \
|
||||||
TABLING_ERROR_CHECKING_STACK; \
|
TABLING_ERROR_CHECKING_STACK; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
#define consume_answer_and_procceed(DEP_FR, ANSWER) \
|
||||||
|
{ CELL *subs_ptr; \
|
||||||
|
/* restore consumer choice point */ \
|
||||||
|
H = HBREG = PROTECT_FROZEN_H(B); \
|
||||||
|
restore_yaam_reg_cpdepth(B); \
|
||||||
|
CPREG = B->cp_cp; \
|
||||||
|
ENV = B->cp_env; \
|
||||||
|
/* set_cut(YENV, B->cp_b); --> no effect */ \
|
||||||
|
PREG = (yamop *) CPREG; \
|
||||||
|
PREFETCH_OP(PREG); \
|
||||||
|
/* load answer from table to global stack */ \
|
||||||
|
if (B == DepFr_leader_cp(DEP_FR) || DepFr_external(DEP_FR)) { \
|
||||||
|
/* B is a generator-consumer node */ \
|
||||||
|
TABLING_ERROR_CHECKING(generator_consumer, IS_BATCHED_GEN_CP(B)); \
|
||||||
|
subs_ptr = (CELL *) (GEN_CP(B) + 1); \
|
||||||
|
subs_ptr += SgFr_arity(GEN_CP(B)->cp_sg_fr); \
|
||||||
|
} else { \
|
||||||
|
subs_ptr = (CELL *) (CONS_CP(B) + 1); \
|
||||||
|
} \
|
||||||
|
load_answer(ANSWER, subs_ptr); \
|
||||||
|
/* procceed */ \
|
||||||
|
YENV = ENV; \
|
||||||
|
GONext(); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
#define consume_answer_and_procceed(DEP_FR, ANSWER) \
|
#define consume_answer_and_procceed(DEP_FR, ANSWER) \
|
||||||
{ CELL *subs_ptr; \
|
{ CELL *subs_ptr; \
|
||||||
/* restore consumer choice point */ \
|
/* restore consumer choice point */ \
|
||||||
@ -207,6 +279,7 @@
|
|||||||
YENV = ENV; \
|
YENV = ENV; \
|
||||||
GONext(); \
|
GONext(); \
|
||||||
}
|
}
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
|
||||||
#define store_loader_node(TAB_ENT, ANSWER) \
|
#define store_loader_node(TAB_ENT, ANSWER) \
|
||||||
@ -401,7 +474,27 @@
|
|||||||
YENV2MEM;
|
YENV2MEM;
|
||||||
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
||||||
MEM2YENV;
|
MEM2YENV;
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_state(sg_fr) <= ready) {
|
||||||
|
LOCK_SG_FR(sg_fr);
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) >= complete)
|
||||||
|
SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
|
||||||
|
else
|
||||||
|
SgFr_active_workers(sg_fr)++;
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
if (SgFr_state(sg_fr) == ready_external) {
|
||||||
|
init_subgoal_frame(sg_fr);
|
||||||
|
store_generator_consumer_node(tab_ent, sg_fr, TRUE, PREG->u.Otapl.s);
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
allocate_environment();
|
||||||
|
check_for_deadlock(sg_fr);
|
||||||
|
goto answer_resolution_completion;
|
||||||
|
} else
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
if (SgFr_state(sg_fr) == ready) {
|
if (SgFr_state(sg_fr) == ready) {
|
||||||
/* subgoal new */
|
/* subgoal new */
|
||||||
init_subgoal_frame(sg_fr);
|
init_subgoal_frame(sg_fr);
|
||||||
@ -478,7 +571,11 @@
|
|||||||
TRAIL_FRAME(sg_fr);
|
TRAIL_FRAME(sg_fr);
|
||||||
}
|
}
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
|
||||||
|
#else
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
/* load answers from the trie */
|
/* load answers from the trie */
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
if(TrNode_child(ans_node) != NULL) {
|
if(TrNode_child(ans_node) != NULL) {
|
||||||
@ -491,7 +588,11 @@
|
|||||||
GONext();
|
GONext();
|
||||||
} else {
|
} else {
|
||||||
/* execute compiled code from the trie */
|
/* execute compiled code from the trie */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < compiled)
|
||||||
|
#else
|
||||||
if (SgFr_state(sg_fr) < compiled)
|
if (SgFr_state(sg_fr) < compiled)
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
update_answer_trie(sg_fr);
|
update_answer_trie(sg_fr);
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
@ -519,7 +620,28 @@
|
|||||||
YENV2MEM;
|
YENV2MEM;
|
||||||
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
||||||
MEM2YENV;
|
MEM2YENV;
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_state(sg_fr) <= ready) {
|
||||||
|
LOCK_SG_FR(sg_fr);
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) >= complete)
|
||||||
|
SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
|
||||||
|
else
|
||||||
|
SgFr_active_workers(sg_fr)++;
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
if (SgFr_state(sg_fr) == ready_external) {
|
||||||
|
init_subgoal_frame(sg_fr);
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
store_generator_consumer_node(tab_ent, sg_fr, TRUE, PREG->u.Otapl.s);
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
allocate_environment();
|
||||||
|
check_for_deadlock(sg_fr);
|
||||||
|
goto answer_resolution_completion;
|
||||||
|
} else
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
if (SgFr_state(sg_fr) == ready) {
|
if (SgFr_state(sg_fr) == ready) {
|
||||||
/* subgoal new */
|
/* subgoal new */
|
||||||
init_subgoal_frame(sg_fr);
|
init_subgoal_frame(sg_fr);
|
||||||
@ -589,7 +711,11 @@
|
|||||||
TRAIL_FRAME(sg_fr);
|
TRAIL_FRAME(sg_fr);
|
||||||
}
|
}
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
|
||||||
|
#else
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
/* load answers from the trie */
|
/* load answers from the trie */
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
if(TrNode_child(ans_node) != NULL) {
|
if(TrNode_child(ans_node) != NULL) {
|
||||||
@ -602,7 +728,11 @@
|
|||||||
GONext();
|
GONext();
|
||||||
} else {
|
} else {
|
||||||
/* execute compiled code from the trie */
|
/* execute compiled code from the trie */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < compiled)
|
||||||
|
#else
|
||||||
if (SgFr_state(sg_fr) < compiled)
|
if (SgFr_state(sg_fr) < compiled)
|
||||||
|
#endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING*/
|
||||||
update_answer_trie(sg_fr);
|
update_answer_trie(sg_fr);
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
@ -630,7 +760,28 @@
|
|||||||
YENV2MEM;
|
YENV2MEM;
|
||||||
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
sg_fr = subgoal_search(PREG, YENV_ADDRESS);
|
||||||
MEM2YENV;
|
MEM2YENV;
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_state(sg_fr) <= ready) {
|
||||||
|
LOCK_SG_FR(sg_fr);
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) >= complete)
|
||||||
|
SgFr_state(sg_fr) = SgFr_sg_ent_state(sg_fr);
|
||||||
|
else
|
||||||
|
SgFr_active_workers(sg_fr)++;
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
if (SgFr_state(sg_fr) == ready_external) {
|
||||||
|
init_subgoal_frame(sg_fr);
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
store_generator_consumer_node(tab_ent, sg_fr, TRUE , PREG->u.Otapl.s);
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
allocate_environment();
|
||||||
|
check_for_deadlock(sg_fr);
|
||||||
|
goto answer_resolution_completion;
|
||||||
|
} else
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
if (SgFr_state(sg_fr) == ready) {
|
if (SgFr_state(sg_fr) == ready) {
|
||||||
/* subgoal new */
|
/* subgoal new */
|
||||||
init_subgoal_frame(sg_fr);
|
init_subgoal_frame(sg_fr);
|
||||||
@ -700,7 +851,11 @@
|
|||||||
TRAIL_FRAME(sg_fr);
|
TRAIL_FRAME(sg_fr);
|
||||||
}
|
}
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent)) || SgFr_active_workers(sg_fr) > 0) {
|
||||||
|
#else
|
||||||
|
if (IsMode_LoadAnswers(TabEnt_mode(tab_ent))) {
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
/* load answers from the trie */
|
/* load answers from the trie */
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
if(TrNode_child(ans_node) != NULL) {
|
if(TrNode_child(ans_node) != NULL) {
|
||||||
@ -713,7 +868,11 @@
|
|||||||
GONext();
|
GONext();
|
||||||
} else {
|
} else {
|
||||||
/* execute compiled code from the trie */
|
/* execute compiled code from the trie */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < compiled)
|
||||||
|
#else
|
||||||
if (SgFr_state(sg_fr) < compiled)
|
if (SgFr_state(sg_fr) < compiled)
|
||||||
|
#endif /*THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
update_answer_trie(sg_fr);
|
update_answer_trie(sg_fr);
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
@ -997,6 +1156,14 @@
|
|||||||
}
|
}
|
||||||
#endif /* TABLING_INNER_CUTS */
|
#endif /* TABLING_INNER_CUTS */
|
||||||
TAG_AS_ANSWER_LEAF_NODE(ans_node);
|
TAG_AS_ANSWER_LEAF_NODE(ans_node);
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
INFO_THREADS("new answer (1) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
|
||||||
|
if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
||||||
|
ANSWER_LEAF_NODE_INSTR_RELATIVE(ans_node);
|
||||||
|
if (worker_id < ANSWER_LEAF_NODE_MAX_THREADS)
|
||||||
|
ANSWER_LEAF_NODE_SET_WID(ans_node,worker_id);
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
UNLOCK_ANSWER_NODE(ans_node);
|
UNLOCK_ANSWER_NODE(ans_node);
|
||||||
#ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
|
#ifndef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
@ -1017,6 +1184,10 @@
|
|||||||
#endif /* DEBUG_TABLING */
|
#endif /* DEBUG_TABLING */
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
if (IS_BATCHED_GEN_CP(gcp)) {
|
if (IS_BATCHED_GEN_CP(gcp)) {
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
if (worker_id >= ANSWER_LEAF_NODE_MAX_THREADS)
|
||||||
|
SgFr_batched_cached_answers_check_insert(sg_fr,ans_node); //add to buffer all answers except the ans_node
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
#ifdef TABLING_EARLY_COMPLETION
|
#ifdef TABLING_EARLY_COMPLETION
|
||||||
if (gcp == PROTECT_FROZEN_B(B) && (*subs_ptr == 0 || gcp->cp_ap == COMPLETION)) {
|
if (gcp == PROTECT_FROZEN_B(B) && (*subs_ptr == 0 || gcp->cp_ap == COMPLETION)) {
|
||||||
/* if the current generator choice point is the topmost choice point and the current */
|
/* if the current generator choice point is the topmost choice point and the current */
|
||||||
@ -1059,8 +1230,55 @@
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* repeated answer */
|
/* repeated answer */
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))){
|
||||||
|
if (worker_id >= ANSWER_LEAF_NODE_MAX_THREADS) {
|
||||||
|
UNLOCK_ANSWER_NODE(ans_node);
|
||||||
|
UNLOCK_ANSWER_TRIE(sg_fr);
|
||||||
|
SgFr_batched_cached_answers_check_insert(sg_fr,NULL);
|
||||||
|
INFO_THREADS("new answer (2) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
|
||||||
|
if (SgFr_batched_cached_answers_check_remove(sg_fr , ans_node) == 1){
|
||||||
|
INFO_THREADS("ans_node=%p not found", ans_node);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/* deallocate and procceed */
|
||||||
|
PREG = (yamop *) YENV[E_CP];
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
CPREG = PREG;
|
||||||
|
SREG = YENV;
|
||||||
|
ENV = YENV = (CELL *) YENV[E_E];
|
||||||
|
#ifdef DEPTH_LIMIT
|
||||||
|
DEPTH = YENV[E_DEPTH];
|
||||||
|
#endif /*DEPTH_LIMIT */
|
||||||
|
GONext();
|
||||||
|
} else {
|
||||||
|
if (!ANSWER_LEAF_NODE_CHECK_WID(ans_node,worker_id)){
|
||||||
|
ANSWER_LEAF_NODE_SET_WID(ans_node,worker_id);
|
||||||
|
UNLOCK_ANSWER_NODE(ans_node);
|
||||||
|
UNLOCK_ANSWER_TRIE(sg_fr);
|
||||||
|
/* deallocate and procceed */
|
||||||
|
INFO_THREADS("new answer (2) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
|
||||||
|
PREG = (yamop *) YENV[E_CP];
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
CPREG = PREG;
|
||||||
|
SREG = YENV;
|
||||||
|
ENV = YENV = (CELL *) YENV[E_E];
|
||||||
|
#ifdef DEPTH_LIMIT
|
||||||
|
DEPTH = YENV[E_DEPTH];
|
||||||
|
#endif /*DEPTH_LIMIT */
|
||||||
|
GONext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
UNLOCK_ANSWER_NODE(ans_node);
|
UNLOCK_ANSWER_NODE(ans_node);
|
||||||
UNLOCK_ANSWER_TRIE(sg_fr);
|
UNLOCK_ANSWER_TRIE(sg_fr);
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
INFO_THREADS("new answer(rep) sgfr=%p ans_node=%p",SgFr_sg_ent(sg_fr),ans_node);
|
||||||
|
#else
|
||||||
|
INFO_THREADS("new answer(rep) sgfr=%p ans_node=%p",sg_fr,ans_node);
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ENDPBOp();
|
ENDPBOp();
|
||||||
@ -1092,13 +1310,13 @@
|
|||||||
if (TrNode_child(ans_node)) {
|
if (TrNode_child(ans_node)) {
|
||||||
/* unconsumed answers */
|
/* unconsumed answers */
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
|
if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
|
||||||
ans_node_ptr old_ans_node;
|
ans_node_ptr old_ans_node;
|
||||||
old_ans_node = ans_node;
|
old_ans_node = ans_node;
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
do {
|
do {
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
} while (IS_INVALID_LEAF_NODE(ans_node));
|
} while (IS_ANSWER_INVALID_NODE(ans_node));
|
||||||
TrNode_child(old_ans_node) = ans_node;
|
TrNode_child(old_ans_node) = ans_node;
|
||||||
} else
|
} else
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
@ -1151,13 +1369,13 @@
|
|||||||
if (TrNode_child(ans_node)) {
|
if (TrNode_child(ans_node)) {
|
||||||
/* dependency frame with unconsumed answers */
|
/* dependency frame with unconsumed answers */
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
|
if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
|
||||||
ans_node_ptr old_ans_node;
|
ans_node_ptr old_ans_node;
|
||||||
old_ans_node = ans_node;
|
old_ans_node = ans_node;
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
do {
|
do {
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
} while (IS_INVALID_LEAF_NODE(ans_node));
|
} while (IS_ANSWER_INVALID_NODE(ans_node));
|
||||||
TrNode_child(old_ans_node) = ans_node;
|
TrNode_child(old_ans_node) = ans_node;
|
||||||
} else
|
} else
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
@ -1360,6 +1578,11 @@
|
|||||||
} else
|
} else
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
goto answer_resolution_completion;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
if (IS_BATCHED_GEN_CP(B)) {
|
if (IS_BATCHED_GEN_CP(B)) {
|
||||||
B->cp_ap = NULL;
|
B->cp_ap = NULL;
|
||||||
if (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
|
if (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
|
||||||
@ -1380,6 +1603,9 @@
|
|||||||
|
|
||||||
|
|
||||||
completion:
|
completion:
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
goto answer_resolution_completion;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
INIT_PREFETCH()
|
INIT_PREFETCH()
|
||||||
dep_fr_ptr dep_fr;
|
dep_fr_ptr dep_fr;
|
||||||
ans_node_ptr ans_node;
|
ans_node_ptr ans_node;
|
||||||
@ -1405,13 +1631,13 @@
|
|||||||
if (TrNode_child(ans_node)) {
|
if (TrNode_child(ans_node)) {
|
||||||
/* dependency frame with unconsumed answers */
|
/* dependency frame with unconsumed answers */
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
|
if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
|
||||||
ans_node_ptr old_ans_node;
|
ans_node_ptr old_ans_node;
|
||||||
old_ans_node = ans_node;
|
old_ans_node = ans_node;
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
do {
|
do {
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
} while (IS_INVALID_LEAF_NODE(ans_node));
|
} while (IS_ANSWER_INVALID_NODE(ans_node));
|
||||||
TrNode_child(old_ans_node) = ans_node;
|
TrNode_child(old_ans_node) = ans_node;
|
||||||
} else
|
} else
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
@ -1575,13 +1801,13 @@
|
|||||||
/* unconsumed answers */
|
/* unconsumed answers */
|
||||||
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
|
UNLOCK_OR_FRAME(LOCAL_top_or_fr);
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (IS_INVALID_LEAF_NODE(TrNode_child(ans_node))) {
|
if (IS_ANSWER_INVALID_NODE(TrNode_child(ans_node))) {
|
||||||
ans_node_ptr old_ans_node;
|
ans_node_ptr old_ans_node;
|
||||||
old_ans_node = ans_node;
|
old_ans_node = ans_node;
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
do {
|
do {
|
||||||
ans_node = TrNode_child(ans_node);
|
ans_node = TrNode_child(ans_node);
|
||||||
} while (IS_INVALID_LEAF_NODE(ans_node));
|
} while (IS_ANSWER_INVALID_NODE(ans_node));
|
||||||
TrNode_child(old_ans_node) = ans_node;
|
TrNode_child(old_ans_node) = ans_node;
|
||||||
} else
|
} else
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
@ -1594,7 +1820,7 @@
|
|||||||
UNLOCK_DEP_FR(LOCAL_top_dep_fr);
|
UNLOCK_DEP_FR(LOCAL_top_dep_fr);
|
||||||
if (OrFr_owners(LOCAL_top_or_fr) > 1) {
|
if (OrFr_owners(LOCAL_top_or_fr) > 1) {
|
||||||
/* more owners -> move up one node */
|
/* more owners -> move up one node */
|
||||||
Set_LOCAL_top_cp_on_stack( GetOrFr_node(OrFr_next_on_stack(LOCAL_top_or_fr)) );
|
Set_LOCAL_top_cp_on_stack(GetOrFr_node(OrFr_next_on_stack(LOCAL_top_or_fr)));
|
||||||
BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id);
|
BITMAP_delete(OrFr_members(LOCAL_top_or_fr), worker_id);
|
||||||
OrFr_owners(LOCAL_top_or_fr)--;
|
OrFr_owners(LOCAL_top_or_fr)--;
|
||||||
LOCAL_top_dep_fr = DepFr_next(LOCAL_top_dep_fr);
|
LOCAL_top_dep_fr = DepFr_next(LOCAL_top_dep_fr);
|
||||||
@ -1625,6 +1851,10 @@
|
|||||||
GONext();
|
GONext();
|
||||||
} else
|
} else
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
complete_all:
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
{
|
{
|
||||||
/* complete all */
|
/* complete all */
|
||||||
sg_fr_ptr sg_fr;
|
sg_fr_ptr sg_fr;
|
||||||
@ -1636,7 +1866,11 @@
|
|||||||
#endif /* DETERMINISTIC_TABLING */
|
#endif /* DETERMINISTIC_TABLING */
|
||||||
sg_fr = GEN_CP(B)->cp_sg_fr;
|
sg_fr = GEN_CP(B)->cp_sg_fr;
|
||||||
private_completion(sg_fr);
|
private_completion(sg_fr);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
if (IS_BATCHED_GEN_CP(B) || SgFr_gen_worker(sg_fr) != worker_id) { /* if it is an gen_cons node then all the answers were already consumed */
|
||||||
|
#else
|
||||||
if (IS_BATCHED_GEN_CP(B)) {
|
if (IS_BATCHED_GEN_CP(B)) {
|
||||||
|
#endif /*THREADS_CONSUMER_SHARING */
|
||||||
/* backtrack */
|
/* backtrack */
|
||||||
B = B->cp_b;
|
B = B->cp_b;
|
||||||
SET_BB(PROTECT_FROZEN_B(B));
|
SET_BB(PROTECT_FROZEN_B(B));
|
||||||
@ -1678,9 +1912,28 @@
|
|||||||
YENV = ENV;
|
YENV = ENV;
|
||||||
GONext();
|
GONext();
|
||||||
} else {
|
} else {
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
LOCK_SG_FR(sg_fr);
|
||||||
|
if (SgFr_active_workers(sg_fr) > 0) {
|
||||||
|
/* load answers from the trie */
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
if(TrNode_child(ans_node) != NULL) {
|
||||||
|
store_loader_node(tab_ent, ans_node);
|
||||||
|
}
|
||||||
|
PREG = (yamop *) CPREG;
|
||||||
|
PREFETCH_OP(PREG);
|
||||||
|
load_answer(ans_node, YENV);
|
||||||
|
YENV = ENV;
|
||||||
|
GONext();
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
/* execute compiled code from the trie */
|
/* execute compiled code from the trie */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < compiled)
|
||||||
|
#else
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
if (SgFr_state(sg_fr) < compiled)
|
if (SgFr_state(sg_fr) < compiled)
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
update_answer_trie(sg_fr);
|
update_answer_trie(sg_fr);
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
PREG = (yamop *) TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
@ -1694,3 +1947,192 @@
|
|||||||
}
|
}
|
||||||
END_PREFETCH()
|
END_PREFETCH()
|
||||||
ENDBOp();
|
ENDBOp();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
** table_answer_resolution_completion **
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
BOp(table_answer_resolution_completion, Otapl)
|
||||||
|
answer_resolution_completion:
|
||||||
|
{
|
||||||
|
INIT_PREFETCH()
|
||||||
|
int do_not_complete_tables;
|
||||||
|
int wid = worker_id ;
|
||||||
|
do {
|
||||||
|
dep_fr_ptr dep_fr;
|
||||||
|
ans_node_ptr ans_node;
|
||||||
|
|
||||||
|
|
||||||
|
do_not_complete_tables = 0; /* 0 - complete all the tables 1 - do not complete all the tables */
|
||||||
|
if (B->cp_ap == ANSWER_RESOLUTION_COMPLETION ){
|
||||||
|
/* generator consumer node (external node) */
|
||||||
|
if ((IS_BATCHED_GEN_CP(B) && (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr))) ||
|
||||||
|
(B != DepFr_leader_cp(LOCAL_top_dep_fr))) {
|
||||||
|
/* not leader on that node */
|
||||||
|
INFO_THREADS("ans_reso_com (1) : not leader on that node dep_fr = %p leader_node =%p", LOCAL_top_dep_fr, GEN_CP(DepFr_leader_cp(LOCAL_top_dep_fr))->cp_dep_fr);
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
B->cp_ap = ANSWER_RESOLUTION;
|
||||||
|
goto answer_resolution;
|
||||||
|
}
|
||||||
|
/* leader on that node */
|
||||||
|
dep_fr = GEN_CP(B)->cp_dep_fr;
|
||||||
|
ans_node = DepFr_last_answer(dep_fr);
|
||||||
|
if (TrNode_child(ans_node)) {
|
||||||
|
/* unconsumed answer */
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
|
||||||
|
INFO_THREADS("ans_reso_com (2) : consume_answer =%p dep_fr = %p leader_node =%p", ans_node, dep_fr, GEN_CP(DepFr_leader_cp(dep_fr))->cp_dep_fr);
|
||||||
|
consume_answer_and_procceed(dep_fr, ans_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_fr_ptr sg_fr = GEN_CP(B)->cp_sg_fr;
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < complete || (SgFr_sg_ent_state(sg_fr) >= complete && TrNode_child(ans_node)!= NULL))
|
||||||
|
do_not_complete_tables = 1;
|
||||||
|
|
||||||
|
} else { /* using the B->cp_ap == ANSWER_RESOLUTION_COMPLETION to distinguish gen_cons nodes from gen */
|
||||||
|
/* generator node */
|
||||||
|
if (IS_BATCHED_GEN_CP(B)) {
|
||||||
|
if (EQUAL_OR_YOUNGER_CP(B_FZ, B) && B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
|
||||||
|
/* not leader on that node */
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
B->cp_ap = NULL;
|
||||||
|
B = B->cp_b;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (B != DepFr_leader_cp(LOCAL_top_dep_fr)) {
|
||||||
|
/* not leader on that node */
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
B->cp_ap = ANSWER_RESOLUTION;
|
||||||
|
B = B->cp_b;
|
||||||
|
INFO_THREADS("ans_reso_com (3) : not leader on that node dep_fr = %p leader_node =%p", LOCAL_top_dep_fr, GEN_CP(DepFr_leader_cp(LOCAL_top_dep_fr))->cp_dep_fr);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* leader on that node */
|
||||||
|
|
||||||
|
/* no unconsumed answers */
|
||||||
|
|
||||||
|
dep_fr = LOCAL_top_dep_fr;
|
||||||
|
|
||||||
|
/* check for dependency frames with unconsumed answers */
|
||||||
|
while (YOUNGER_CP(DepFr_cons_cp(dep_fr), B)) {
|
||||||
|
ans_node = DepFr_last_answer(dep_fr);
|
||||||
|
if (TrNode_child(ans_node)) {
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = working;
|
||||||
|
/*dependency frame with unconsumed answers */
|
||||||
|
ans_node = DepFr_last_answer(dep_fr) = TrNode_child(ans_node);
|
||||||
|
if (IS_BATCHED_GEN_CP(B))
|
||||||
|
DepFr_backchain_cp(dep_fr) = B->cp_b;
|
||||||
|
else
|
||||||
|
DepFr_backchain_cp(dep_fr) = B;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*rebind variables, update registers, consume answer and procceed */
|
||||||
|
|
||||||
|
TABLING_ERROR_CHECKING(answer_resolution_completion, EQUAL_OR_YOUNGER_CP(B, DepFr_cons_cp(dep_fr)));
|
||||||
|
TABLING_ERROR_CHECKING(answer_resolution_completion, B->cp_tr > DepFr_cons_cp(dep_fr)->cp_tr);
|
||||||
|
rebind_variables(DepFr_cons_cp(dep_fr)->cp_tr,B->cp_tr); //don't know if it is the same unbind_variables(DepFr_cons_cp(dep_fr)->cp_tr, B->cp_tr);
|
||||||
|
|
||||||
|
TABLING_ERROR_CHECKING(answer_resolution_completion, TR != B->cp_tr && !IsPairTerm((CELL)TrailTerm(TR - 1)));
|
||||||
|
TABLING_ERROR_CHECKING(answer_resolution_completion, TR != B->cp_tr && (tr_fr_ptr) RepPair((CELL)TrailTerm(TR - 1)) != B->cp_tr);
|
||||||
|
B = DepFr_cons_cp(dep_fr);
|
||||||
|
TR = TR_FZ;
|
||||||
|
if (TR != B->cp_tr)
|
||||||
|
TRAIL_LINK(B->cp_tr);
|
||||||
|
INFO_THREADS("ans_reso_com (4) : consume_answer =%p dep_fr = %p leader_node =%p", ans_node, dep_fr, GEN_CP(DepFr_leader_cp(dep_fr))->cp_dep_fr);
|
||||||
|
consume_answer_and_procceed(dep_fr, ans_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (DepFr_external(dep_fr) == TRUE){
|
||||||
|
sg_fr_ptr sg_fr = GEN_CP(DepFr_cons_cp(dep_fr))->cp_sg_fr;
|
||||||
|
if (SgFr_sg_ent_state(sg_fr) < complete || (SgFr_sg_ent_state(sg_fr) >= complete && TrNode_child(ans_node)!= NULL))
|
||||||
|
do_not_complete_tables = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
dep_fr = DepFr_next(dep_fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************** a terminaçao das threads *************************************/
|
||||||
|
|
||||||
|
if (do_not_complete_tables == 1){
|
||||||
|
/*all the dependency frames have consumed all answers and we have external tables */
|
||||||
|
if (ThDepFr_next(GLOBAL_th_dep_fr(wid)) == wid)
|
||||||
|
/* worker_id is not inside an SCC */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == working) {
|
||||||
|
int c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
do {
|
||||||
|
ThDepFr_terminator(GLOBAL_th_dep_fr(c_wid)) = 1;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
}while(c_wid != wid);
|
||||||
|
ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) = 1;
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = idle;
|
||||||
|
|
||||||
|
}else if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == idle){
|
||||||
|
int l_wid = wid; /* leader wid */
|
||||||
|
int c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
int jump_state = TRUE;
|
||||||
|
do{
|
||||||
|
if (ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) != idle){
|
||||||
|
jump_state = FALSE;
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
if (l_wid > c_wid)
|
||||||
|
l_wid = c_wid;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
} while(c_wid != wid);
|
||||||
|
|
||||||
|
if (jump_state && l_wid == wid){
|
||||||
|
/* wid is the current leader thread */
|
||||||
|
ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) = 0;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
do {
|
||||||
|
dep_fr_ptr remote_dep_fr = REMOTE_top_dep_fr(c_wid);
|
||||||
|
while(YOUNGER_CP(DepFr_cons_cp(remote_dep_fr),DepFr_leader_cp(REMOTE_top_dep_fr(c_wid)))){
|
||||||
|
if (TrNode_child(DepFr_last_answer(remote_dep_fr))){
|
||||||
|
/* dependency frame with unconsumed answers */
|
||||||
|
jump_state = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
remote_dep_fr = DepFr_next(remote_dep_fr);
|
||||||
|
}
|
||||||
|
if (ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) != idle){
|
||||||
|
jump_state = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
} while(c_wid != wid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jump_state && ThDepFr_terminator(GLOBAL_th_dep_fr(wid)) == 0){
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
do {
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(c_wid)) = completing;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
}while(c_wid != wid);
|
||||||
|
ThDepFr_state(GLOBAL_th_dep_fr(wid)) = completing;
|
||||||
|
}
|
||||||
|
}else if (ThDepFr_state(GLOBAL_th_dep_fr(wid)) == completing){
|
||||||
|
INFO_THREADS("ans_reso_com (5) : completing thread_state =%d",ThDepFr_state(GLOBAL_th_dep_fr(wid)));
|
||||||
|
break; /*do_not_complete_tables = 0; -- same as "break;" */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(do_not_complete_tables);
|
||||||
|
|
||||||
|
END_PREFETCH()
|
||||||
|
INFO_THREADS("ans_reso_com (6) : completing thread_state =%d",ThDepFr_state(GLOBAL_th_dep_fr(worker_id)));
|
||||||
|
|
||||||
|
goto complete_all;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENDBOp();
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
@ -21,6 +21,26 @@
|
|||||||
#endif /* HAVE_STRING_H */
|
#endif /* HAVE_STRING_H */
|
||||||
#include "opt.mavar.h"
|
#include "opt.mavar.h"
|
||||||
|
|
||||||
|
#ifdef THREADS
|
||||||
|
static inline void **get_insert_thread_bucket(void **, lockvar *);
|
||||||
|
static inline void **get_thread_bucket(void **);
|
||||||
|
static inline void abolish_thread_buckets(void **);
|
||||||
|
#endif /* THREADS */
|
||||||
|
static inline sg_node_ptr get_insert_subgoal_trie(tab_ent_ptr USES_REGS);
|
||||||
|
static inline sg_node_ptr get_subgoal_trie(tab_ent_ptr);
|
||||||
|
static inline sg_node_ptr get_subgoal_trie_for_abolish(tab_ent_ptr USES_REGS);
|
||||||
|
static inline sg_fr_ptr *get_insert_subgoal_frame_addr(sg_node_ptr USES_REGS);
|
||||||
|
static inline sg_fr_ptr get_subgoal_frame(sg_node_ptr);
|
||||||
|
static inline sg_fr_ptr get_subgoal_frame_for_abolish(sg_node_ptr USES_REGS);
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
static inline void SgFr_batched_cached_answers_check_insert(sg_fr_ptr, ans_node_ptr);
|
||||||
|
static inline int SgFr_batched_cached_answers_check_remove(sg_fr_ptr, ans_node_ptr);
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
static inline void add_to_tdv(int, int);
|
||||||
|
static inline void check_for_deadlock(sg_fr_ptr);
|
||||||
|
static inline sg_fr_ptr deadlock_detection(sg_fr_ptr);
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
static inline Int freeze_current_cp(void);
|
static inline Int freeze_current_cp(void);
|
||||||
static inline void wake_frozen_cp(Int);
|
static inline void wake_frozen_cp(Int);
|
||||||
static inline void abolish_frozen_cps_until(Int);
|
static inline void abolish_frozen_cps_until(Int);
|
||||||
@ -148,8 +168,8 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
#else
|
#else
|
||||||
#define ANSWER_LEAF_NODE_MAX_THREADS OOOOPPS!!! Unknown Pointer Sizeof
|
#define ANSWER_LEAF_NODE_MAX_THREADS OOOOPPS!!! Unknown Pointer Sizeof
|
||||||
#endif /* SIZEOF_INT_P */
|
#endif /* SIZEOF_INT_P */
|
||||||
#define ANSWER_LEAF_NODE_INSTR_RELATIVE(NODE) TrNode_instr(NODE) = TrNode_instr(NODE) - _trie_do_var + 1
|
#define ANSWER_LEAF_NODE_INSTR_RELATIVE(NODE) (TrNode_instr(NODE) = TrNode_instr(NODE) - _trie_do_var + 1)
|
||||||
#define ANSWER_LEAF_NODE_INSTR_ABSOLUTE(NODE) TrNode_instr(NODE) = (TrNode_instr(NODE) & ANSWER_LEAF_NODE_INSTR_MASK) + _trie_do_var - 1
|
#define ANSWER_LEAF_NODE_INSTR_ABSOLUTE(NODE) (TrNode_instr(NODE) = (TrNode_instr(NODE) & ANSWER_LEAF_NODE_INSTR_MASK) + _trie_do_var - 1)
|
||||||
#define ANSWER_LEAF_NODE_SET_WID(NODE,WID) BITMAP_insert(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
#define ANSWER_LEAF_NODE_SET_WID(NODE,WID) BITMAP_insert(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
||||||
#define ANSWER_LEAF_NODE_DEL_WID(NODE,WID) BITMAP_delete(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
#define ANSWER_LEAF_NODE_DEL_WID(NODE,WID) BITMAP_delete(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
||||||
#define ANSWER_LEAF_NODE_CHECK_WID(NODE,WID) BITMAP_member(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
#define ANSWER_LEAF_NODE_CHECK_WID(NODE,WID) BITMAP_member(TrNode_instr(NODE), WID + ANSWER_LEAF_NODE_INSTR_BITS)
|
||||||
@ -165,18 +185,22 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
#define IS_BATCHED_NORM_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
|
#define IS_BATCHED_NORM_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
|
||||||
#define IS_BATCHED_GEN_CP(CP) (IS_DET_GEN_CP(CP) || IS_BATCHED_NORM_GEN_CP(CP))
|
#define IS_BATCHED_GEN_CP(CP) (IS_DET_GEN_CP(CP) || IS_BATCHED_NORM_GEN_CP(CP))
|
||||||
#else
|
#else
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
#define IS_BATCHED_GEN_CP(CP) (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(GEN_CP(CP)->cp_sg_fr))))
|
||||||
|
#else
|
||||||
#define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
|
#define IS_BATCHED_GEN_CP(CP) (GEN_CP(CP)->cp_dep_fr == NULL)
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* DETERMINISTIC_TABLING */
|
#endif /* DETERMINISTIC_TABLING */
|
||||||
|
|
||||||
/* leaf nodes */
|
/* tagging nodes */
|
||||||
#define TAG_AS_SUBGOAL_LEAF_NODE(NODE) TrNode_child(NODE) = (sg_node_ptr)((unsigned long int) TrNode_child(NODE) | 0x1)
|
#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)
|
||||||
#define IS_SUBGOAL_LEAF_NODE(NODE) ((unsigned long int) TrNode_child(NODE) & 0x1)
|
#define TAG_AS_ANSWER_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x1)
|
||||||
#define TAG_AS_ANSWER_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x1)
|
#define IS_ANSWER_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x1)
|
||||||
#define UNTAG_ANSWER_LEAF_NODE(NODE) ((ans_node_ptr)((unsigned long int) (NODE) & ~(0x1)))
|
#define TAG_AS_ANSWER_INVALID_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2)
|
||||||
#define IS_ANSWER_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x1)
|
#define IS_ANSWER_INVALID_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2)
|
||||||
#define TAG_AS_INVALID_LEAF_NODE(NODE) TrNode_parent(NODE) = (ans_node_ptr)((unsigned long int) TrNode_parent(NODE) | 0x2)
|
#define UNTAG_SUBGOAL_NODE(NODE) ((sg_fr_ptr)((unsigned long int) (NODE) & ~(0x1)))
|
||||||
#define IS_INVALID_LEAF_NODE(NODE) ((unsigned long int) TrNode_parent(NODE) & 0x2)
|
#define UNTAG_ANSWER_NODE(NODE) ((ans_node_ptr)((unsigned long int) (NODE) & ~(0x3)))
|
||||||
|
|
||||||
/* trie hashes */
|
/* trie hashes */
|
||||||
#define MAX_NODES_PER_TRIE_LEVEL 8
|
#define MAX_NODES_PER_TRIE_LEVEL 8
|
||||||
@ -278,18 +302,21 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
#define TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY) \
|
#define TabEnt_init_mode_directed_field(TAB_ENT, MODE_ARRAY) \
|
||||||
TabEnt_mode_directed(TAB_ENT) = MODE_ARRAY
|
TabEnt_mode_directed(TAB_ENT) = MODE_ARRAY
|
||||||
#define SgFr_init_mode_directed(SG_FR, MODE_ARRAY) \
|
#define SgEnt_init_mode_directed_fields(SG_ENT, MODE_ARRAY) \
|
||||||
SgFr_invalid_chain(SG_FR) = NULL; \
|
SgEnt_invalid_chain(SG_ENT) = NULL; \
|
||||||
|
SgEnt_mode_directed(SG_ENT) = MODE_ARRAY
|
||||||
|
#define SgFr_init_mode_directed_fields(SG_FR, MODE_ARRAY) \
|
||||||
|
SgFr_invalid_chain(SG_FR) = NULL; \
|
||||||
SgFr_mode_directed(SG_FR) = MODE_ARRAY
|
SgFr_mode_directed(SG_FR) = MODE_ARRAY
|
||||||
#define AnsHash_init_previous_field(HASH, SG_FR) \
|
#define AnsHash_init_previous_field(HASH, SG_FR) \
|
||||||
if (SgFr_hash_chain(SG_FR)) \
|
if (SgFr_hash_chain(SG_FR)) \
|
||||||
Hash_previous(SgFr_hash_chain(SG_FR)) = HASH; \
|
Hash_previous(SgFr_hash_chain(SG_FR)) = HASH; \
|
||||||
Hash_previous(HASH) = NULL
|
Hash_previous(HASH) = NULL
|
||||||
#else
|
#else
|
||||||
#define TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY)
|
#define TabEnt_init_mode_directed_field(TAB_ENT, MODE_ARRAY)
|
||||||
#define SgFr_init_mode_directed(SG_FR, MODE_ARRAY)
|
#define SgFr_init_mode_directed_fields(SG_FR, MODE_ARRAY)
|
||||||
#define AnsHash_init_previous_field(HASH, SG_FR)
|
#define AnsHash_init_previous_field(HASH, SG_FR)
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
|
|
||||||
@ -315,20 +342,18 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
#define IS_UNLOCKED_DEP_FR(DEP_FR)
|
#define IS_UNLOCKED_DEP_FR(DEP_FR)
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
|
||||||
|
#if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) || defined(THREADS_NO_SHARING)
|
||||||
|
#define INIT_LOCK_TAB_ENT(TAB_ENT) INIT_LOCK(TabEnt_lock(TAB_ENT))
|
||||||
|
#else
|
||||||
|
#define INIT_LOCK_TAB_ENT(TAB_ENT)
|
||||||
|
#endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL || THREADS_NO_SHARING */
|
||||||
|
|
||||||
#ifdef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL
|
#ifdef SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL
|
||||||
#define LOCK_SUBGOAL_TRIE(TAB_ENT) LOCK(TabEnt_lock(TAB_ENT))
|
#define LOCK_SUBGOAL_TRIE(TAB_ENT) LOCK(TabEnt_lock(TAB_ENT))
|
||||||
#define UNLOCK_SUBGOAL_TRIE(TAB_ENT) UNLOCK(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
|
|
||||||
#else
|
#else
|
||||||
#define LOCK_SUBGOAL_TRIE(TAB_ENT)
|
#define LOCK_SUBGOAL_TRIE(TAB_ENT)
|
||||||
#define UNLOCK_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))
|
|
||||||
#endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL */
|
#endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL */
|
||||||
|
|
||||||
#ifdef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
|
#ifdef ANSWER_TRIE_LOCK_AT_ENTRY_LEVEL
|
||||||
@ -391,63 +416,137 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
#define GtNode_init_lock_field(NODE)
|
#define GtNode_init_lock_field(NODE)
|
||||||
#endif /* GLOBAL_TRIE_LOCK_LEVEL */
|
#endif /* GLOBAL_TRIE_LOCK_LEVEL */
|
||||||
|
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
#define TabEnt_init_subgoal_trie_field(TAB_ENT) \
|
||||||
|
INIT_BUCKETS(&TabEnt_subgoal_trie(TAB_ENT), THREADS_NUM_BUCKETS)
|
||||||
|
#else
|
||||||
|
#define TabEnt_init_subgoal_trie_field(TAB_ENT) \
|
||||||
|
{ register sg_node_ptr sg_node; \
|
||||||
|
new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \
|
||||||
|
TabEnt_subgoal_trie(TAB_ENT) = sg_node; \
|
||||||
|
}
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
|
|
||||||
|
#if defined(THREADS_FULL_SHARING)
|
||||||
|
#define SgFr_init_batched_fields(SG_FR) \
|
||||||
|
SgFr_batched_last_answer(SG_FR) = NULL; \
|
||||||
|
SgFr_batched_cached_answers(SG_FR) = NULL;
|
||||||
|
#else
|
||||||
|
#define SgFr_init_batched_fields(SG_FR)
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
#define DepFr_init_external_field(DEP_FR, IS_EXTERNAL) \
|
||||||
|
DepFr_external(DEP_FR) = IS_EXTERNAL
|
||||||
|
#else
|
||||||
|
#define DepFr_init_external_field(DEP_FR, IS_EXTERNAL)
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
#define DepFr_init_last_answer_field(DEP_FR, SG_FR) \
|
||||||
|
/* start with TrNode_child(DepFr_last_answer(DEP_FR)) ... */ \
|
||||||
|
/* ... pointing to SgEnt_first_answer(SgFr_sg_ent(SG_FR)) */ \
|
||||||
|
if (SG_FR) \
|
||||||
|
DepFr_last_answer(DEP_FR) = (ans_node_ptr) ( \
|
||||||
|
(unsigned long int) (SgFr_sg_ent((sg_fr_ptr)SG_FR)) + \
|
||||||
|
(unsigned long int) (&SgEnt_first_answer((sg_ent_ptr)DEP_FR)) - \
|
||||||
|
(unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \
|
||||||
|
else \
|
||||||
|
DepFr_last_answer(DEP_FR) = NULL
|
||||||
|
#else
|
||||||
|
#define DepFr_init_last_answer_field(DEP_FR, SG_FR) \
|
||||||
|
/* start with TrNode_child(DepFr_last_answer(DEP_FR)) ... */ \
|
||||||
|
/* ... pointing to SgFr_first_answer(SG_FR) */ \
|
||||||
|
if (SG_FR) \
|
||||||
|
DepFr_last_answer(DEP_FR) = (ans_node_ptr) ( \
|
||||||
|
(unsigned long int) (SG_FR) + \
|
||||||
|
(unsigned long int) (&SgFr_first_answer((sg_fr_ptr)DEP_FR)) - \
|
||||||
|
(unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \
|
||||||
|
else \
|
||||||
|
DepFr_last_answer(DEP_FR) = NULL
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \
|
#define new_table_entry(TAB_ENT, PRED_ENTRY, ATOM, ARITY, MODE_ARRAY) \
|
||||||
{ register sg_node_ptr sg_node; \
|
ALLOC_TABLE_ENTRY(TAB_ENT); \
|
||||||
new_subgoal_trie_node(sg_node, 0, NULL, NULL, NULL); \
|
INIT_LOCK_TAB_ENT(TAB_ENT); \
|
||||||
ALLOC_TABLE_ENTRY(TAB_ENT); \
|
TabEnt_pe(TAB_ENT) = PRED_ENTRY; \
|
||||||
INIT_LOCK(TabEnt_lock(TAB_ENT)); \
|
TabEnt_atom(TAB_ENT) = ATOM; \
|
||||||
TabEnt_pe(TAB_ENT) = PRED_ENTRY; \
|
TabEnt_arity(TAB_ENT) = ARITY; \
|
||||||
TabEnt_atom(TAB_ENT) = ATOM; \
|
TabEnt_flags(TAB_ENT) = 0; \
|
||||||
TabEnt_arity(TAB_ENT) = ARITY; \
|
SetMode_Batched(TabEnt_flags(TAB_ENT)); \
|
||||||
TabEnt_flags(TAB_ENT) = 0; \
|
SetMode_ExecAnswers(TabEnt_flags(TAB_ENT)); \
|
||||||
SetMode_Batched(TabEnt_flags(TAB_ENT)); \
|
SetMode_LocalTrie(TabEnt_flags(TAB_ENT)); \
|
||||||
SetMode_ExecAnswers(TabEnt_flags(TAB_ENT)); \
|
TabEnt_mode(TAB_ENT) = TabEnt_flags(TAB_ENT); \
|
||||||
SetMode_LocalTrie(TabEnt_flags(TAB_ENT)); \
|
if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) \
|
||||||
TabEnt_mode(TAB_ENT) = TabEnt_flags(TAB_ENT); \
|
SetMode_Local(TabEnt_mode(TAB_ENT)); \
|
||||||
if (IsMode_Local(yap_flags[TABLING_MODE_FLAG])) \
|
if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) \
|
||||||
SetMode_Local(TabEnt_mode(TAB_ENT)); \
|
SetMode_LoadAnswers(TabEnt_mode(TAB_ENT)); \
|
||||||
if (IsMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG])) \
|
if (IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) \
|
||||||
SetMode_LoadAnswers(TabEnt_mode(TAB_ENT)); \
|
SetMode_GlobalTrie(TabEnt_mode(TAB_ENT)); \
|
||||||
if (IsMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG])) \
|
TabEnt_init_mode_directed_field(TAB_ENT, MODE_ARRAY); \
|
||||||
SetMode_GlobalTrie(TabEnt_mode(TAB_ENT)); \
|
TabEnt_init_subgoal_trie_field(TAB_ENT); \
|
||||||
TabEnt_init_mode_directed(TAB_ENT, MODE_ARRAY); \
|
TabEnt_next(TAB_ENT) = GLOBAL_root_tab_ent; \
|
||||||
TabEnt_subgoal_trie(TAB_ENT) = sg_node; \
|
GLOBAL_root_tab_ent = TAB_ENT
|
||||||
TabEnt_hash_chain(TAB_ENT) = NULL; \
|
|
||||||
TabEnt_next(TAB_ENT) = GLOBAL_root_tab_ent; \
|
#define new_subgoal_entry(SG_ENT) \
|
||||||
GLOBAL_root_tab_ent = TAB_ENT; \
|
{ register ans_node_ptr ans_node; \
|
||||||
|
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
|
||||||
|
ALLOC_SUBGOAL_ENTRY(SG_ENT); \
|
||||||
|
INIT_LOCK(SgEnt_lock(SG_ENT)); \
|
||||||
|
SgEnt_hash_chain(SG_ENT) = NULL; \
|
||||||
|
SgEnt_answer_trie(SG_ENT) = ans_node; \
|
||||||
|
SgEnt_first_answer(SG_ENT) = NULL; \
|
||||||
|
SgEnt_last_answer(SG_ENT) = NULL; \
|
||||||
|
SgEnt_sg_ent_state(SG_ENT) = ready; \
|
||||||
|
SgEnt_active_workers(SG_ENT) = 0; \
|
||||||
|
INIT_BUCKETS(&SgEnt_sg_fr(SG_ENT), THREADS_NUM_BUCKETS); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
#define new_subgoal_frame(SG_FR, SG_ENT) \
|
||||||
|
{ ALLOC_SUBGOAL_FRAME(SG_FR); \
|
||||||
|
SgFr_sg_ent(SG_FR) = SG_ENT ; \
|
||||||
|
SgFr_init_batched_fields(SG_FR); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define init_subgoal_frame(SG_FR) \
|
||||||
|
{ SgFr_state(SG_FR) = evaluating; \
|
||||||
|
SgFr_next(SG_FR) = LOCAL_top_sg_fr; \
|
||||||
|
LOCAL_top_sg_fr = SG_FR; \
|
||||||
|
}
|
||||||
|
#else
|
||||||
#define new_subgoal_frame(SG_FR, CODE, MODE_ARRAY) \
|
#define new_subgoal_frame(SG_FR, CODE, MODE_ARRAY) \
|
||||||
{ register ans_node_ptr ans_node; \
|
{ register ans_node_ptr ans_node; \
|
||||||
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
|
new_answer_trie_node(ans_node, 0, 0, NULL, NULL, NULL); \
|
||||||
ALLOC_SUBGOAL_FRAME(SG_FR); \
|
ALLOC_SUBGOAL_FRAME(SG_FR); \
|
||||||
INIT_LOCK_SG_FR(SG_FR); \
|
INIT_LOCK_SG_FR(SG_FR); \
|
||||||
SgFr_code(SG_FR) = CODE; \
|
SgFr_code(SG_FR) = CODE; \
|
||||||
SgFr_state(SG_FR) = ready; \
|
|
||||||
SgFr_hash_chain(SG_FR) = NULL; \
|
SgFr_hash_chain(SG_FR) = NULL; \
|
||||||
SgFr_answer_trie(SG_FR) = ans_node; \
|
SgFr_answer_trie(SG_FR) = ans_node; \
|
||||||
SgFr_first_answer(SG_FR) = NULL; \
|
SgFr_first_answer(SG_FR) = NULL; \
|
||||||
SgFr_last_answer(SG_FR) = NULL; \
|
SgFr_last_answer(SG_FR) = NULL; \
|
||||||
SgFr_init_mode_directed(SG_FR, MODE_ARRAY); \
|
SgFr_init_mode_directed_fields(SG_FR, MODE_ARRAY); \
|
||||||
|
SgFr_state(SG_FR) = ready; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define init_subgoal_frame(SG_FR) \
|
#define init_subgoal_frame(SG_FR) \
|
||||||
{ SgFr_init_yapor_fields(SG_FR); \
|
{ SgFr_init_yapor_fields(SG_FR); \
|
||||||
SgFr_state(SG_FR) = evaluating; \
|
SgFr_state(SG_FR) = evaluating; \
|
||||||
SgFr_next(SG_FR) = LOCAL_top_sg_fr; \
|
SgFr_next(SG_FR) = LOCAL_top_sg_fr; \
|
||||||
LOCAL_top_sg_fr = SG_FR; \
|
LOCAL_top_sg_fr = SG_FR; \
|
||||||
}
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING) || THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
#define new_dependency_frame(DEP_FR, DEP_ON_STACK, TOP_OR_FR, LEADER_CP, CONS_CP, SG_FR, NEXT) \
|
#define new_dependency_frame(DEP_FR, DEP_ON_STACK, TOP_OR_FR, LEADER_CP, CONS_CP, SG_FR, IS_EXTERNAL, NEXT) \
|
||||||
ALLOC_DEPENDENCY_FRAME(DEP_FR); \
|
ALLOC_DEPENDENCY_FRAME(DEP_FR); \
|
||||||
DepFr_init_yapor_fields(DEP_FR, DEP_ON_STACK, TOP_OR_FR); \
|
DepFr_init_yapor_fields(DEP_FR, DEP_ON_STACK, TOP_OR_FR); \
|
||||||
DepFr_backchain_cp(DEP_FR) = NULL; \
|
DepFr_init_external_field(DEP_FR, IS_EXTERNAL); \
|
||||||
DepFr_leader_cp(DEP_FR) = NORM_CP(LEADER_CP); \
|
DepFr_backchain_cp(DEP_FR) = NULL; \
|
||||||
DepFr_cons_cp(DEP_FR) = NORM_CP(CONS_CP); \
|
DepFr_leader_cp(DEP_FR) = NORM_CP(LEADER_CP); \
|
||||||
/* start with TrNode_child(DepFr_last_answer(DEP_FR)) pointing to SgFr_first_answer(SG_FR) */ \
|
DepFr_cons_cp(DEP_FR) = NORM_CP(CONS_CP); \
|
||||||
DepFr_last_answer(DEP_FR) = (ans_node_ptr) ((unsigned long int) (SG_FR) + \
|
DepFr_init_last_answer_field(DEP_FR, SG_FR); \
|
||||||
(unsigned long int) (&SgFr_first_answer((sg_fr_ptr)DEP_FR)) - \
|
|
||||||
(unsigned long int) (&TrNode_child((ans_node_ptr)DEP_FR))); \
|
|
||||||
DepFr_next(DEP_FR) = NEXT
|
DepFr_next(DEP_FR) = NEXT
|
||||||
|
|
||||||
#define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \
|
#define new_suspension_frame(SUSP_FR, TOP_OR_FR_ON_STACK, TOP_DEP, TOP_SG, \
|
||||||
@ -478,7 +577,7 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
SgNode_init_lock_field(NODE)
|
SgNode_init_lock_field(NODE)
|
||||||
|
|
||||||
#define new_answer_trie_node(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \
|
#define new_answer_trie_node(NODE, INSTR, ENTRY, CHILD, PARENT, NEXT) \
|
||||||
ALLOC_ANSWER_TRIE_NODE(NODE); \
|
ALLOC_ANSWER_TRIE_NODE(NODE); \
|
||||||
TrNode_instr(NODE) = INSTR; \
|
TrNode_instr(NODE) = INSTR; \
|
||||||
TrNode_entry(NODE) = ENTRY; \
|
TrNode_entry(NODE) = ENTRY; \
|
||||||
TrNode_child(NODE) = CHILD; \
|
TrNode_child(NODE) = CHILD; \
|
||||||
@ -494,27 +593,32 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
TrNode_next(NODE) = NEXT; \
|
TrNode_next(NODE) = NEXT; \
|
||||||
GtNode_init_lock_field(NODE)
|
GtNode_init_lock_field(NODE)
|
||||||
|
|
||||||
#define new_subgoal_trie_hash(HASH, NUM_NODES, TAB_ENT) \
|
#define new_answer_ref_node(NODE, ANSWER, NEXT, PREVIOUS) \
|
||||||
ALLOC_SUBGOAL_TRIE_HASH(HASH); \
|
ALLOC_ANSWER_REF_NODE(NODE); \
|
||||||
Hash_mark(HASH) = SUBGOAL_TRIE_HASH_MARK; \
|
RefNode_answer(NODE) = ANSWER; \
|
||||||
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
RefNode_next(NODE) = NEXT; \
|
||||||
ALLOC_HASH_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
RefNode_previous(NODE) = PREVIOUS
|
||||||
Hash_num_nodes(HASH) = NUM_NODES; \
|
|
||||||
SgHash_init_next_field(HASH, TAB_ENT)
|
|
||||||
|
|
||||||
#define new_answer_trie_hash(HASH, NUM_NODES, SG_FR) \
|
#define new_subgoal_trie_hash(HASH, NUM_NODES, TAB_ENT) \
|
||||||
ALLOC_ANSWER_TRIE_HASH(HASH); \
|
ALLOC_SUBGOAL_TRIE_HASH(HASH); \
|
||||||
Hash_mark(HASH) = ANSWER_TRIE_HASH_MARK; \
|
Hash_mark(HASH) = SUBGOAL_TRIE_HASH_MARK; \
|
||||||
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
||||||
ALLOC_HASH_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
ALLOC_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
||||||
Hash_num_nodes(HASH) = NUM_NODES; \
|
Hash_num_nodes(HASH) = NUM_NODES
|
||||||
|
|
||||||
|
#define new_answer_trie_hash(HASH, NUM_NODES, SG_FR) \
|
||||||
|
ALLOC_ANSWER_TRIE_HASH(HASH); \
|
||||||
|
Hash_mark(HASH) = ANSWER_TRIE_HASH_MARK; \
|
||||||
|
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
||||||
|
ALLOC_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
||||||
|
Hash_num_nodes(HASH) = NUM_NODES; \
|
||||||
AnsHash_init_chain_fields(HASH, SG_FR)
|
AnsHash_init_chain_fields(HASH, SG_FR)
|
||||||
|
|
||||||
#define new_global_trie_hash(HASH, NUM_NODES) \
|
#define new_global_trie_hash(HASH, NUM_NODES) \
|
||||||
ALLOC_GLOBAL_TRIE_HASH(HASH); \
|
ALLOC_GLOBAL_TRIE_HASH(HASH); \
|
||||||
Hash_mark(HASH) = GLOBAL_TRIE_HASH_MARK; \
|
Hash_mark(HASH) = GLOBAL_TRIE_HASH_MARK; \
|
||||||
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
Hash_num_buckets(HASH) = BASE_HASH_BUCKETS; \
|
||||||
ALLOC_HASH_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
ALLOC_BUCKETS(Hash_buckets(HASH), BASE_HASH_BUCKETS); \
|
||||||
Hash_num_nodes(HASH) = NUM_NODES
|
Hash_num_nodes(HASH) = NUM_NODES
|
||||||
|
|
||||||
#ifdef LIMIT_TABLING
|
#ifdef LIMIT_TABLING
|
||||||
@ -551,6 +655,327 @@ static inline tg_sol_fr_ptr CUT_prune_tg_solution_frames(tg_sol_fr_ptr, int);
|
|||||||
** Inline funcions **
|
** Inline funcions **
|
||||||
******************************/
|
******************************/
|
||||||
|
|
||||||
|
#ifdef THREADS
|
||||||
|
static inline void **get_insert_thread_bucket(void **buckets, lockvar *buckets_lock) {
|
||||||
|
CACHE_REGS
|
||||||
|
|
||||||
|
/* direct bucket */
|
||||||
|
if (worker_id < THREADS_DIRECT_BUCKETS)
|
||||||
|
return buckets + worker_id;
|
||||||
|
|
||||||
|
/* indirect bucket */
|
||||||
|
buckets = buckets + THREADS_DIRECT_BUCKETS + (worker_id - THREADS_DIRECT_BUCKETS) / THREADS_DIRECT_BUCKETS;
|
||||||
|
if (*buckets)
|
||||||
|
return *buckets + (worker_id - THREADS_DIRECT_BUCKETS) % THREADS_DIRECT_BUCKETS;
|
||||||
|
|
||||||
|
/* insert indirect bucket */
|
||||||
|
LOCK(*buckets_lock);
|
||||||
|
if (*buckets == NULL)
|
||||||
|
ALLOC_BUCKETS(*buckets, THREADS_DIRECT_BUCKETS);
|
||||||
|
UNLOCK(*buckets_lock);
|
||||||
|
return *buckets + (worker_id - THREADS_DIRECT_BUCKETS) % THREADS_DIRECT_BUCKETS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void **get_thread_bucket(void **buckets) {
|
||||||
|
CACHE_REGS
|
||||||
|
|
||||||
|
/* direct bucket */
|
||||||
|
if (worker_id < THREADS_DIRECT_BUCKETS)
|
||||||
|
return buckets + worker_id;
|
||||||
|
|
||||||
|
/* indirect bucket */
|
||||||
|
buckets = buckets + THREADS_DIRECT_BUCKETS + (worker_id - THREADS_DIRECT_BUCKETS) / THREADS_DIRECT_BUCKETS;
|
||||||
|
if (*buckets)
|
||||||
|
return *buckets + (worker_id - THREADS_DIRECT_BUCKETS) % THREADS_DIRECT_BUCKETS;
|
||||||
|
|
||||||
|
/* empty indirect bucket */
|
||||||
|
return buckets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void abolish_thread_buckets(void **buckets) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* abolish indirect buckets */
|
||||||
|
buckets += THREADS_NUM_BUCKETS;
|
||||||
|
for (i = 0; i < THREADS_INDIRECT_BUCKETS; i++) {
|
||||||
|
if (*--buckets) {
|
||||||
|
FREE_BUCKETS(*buckets);
|
||||||
|
*buckets = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING)
|
||||||
|
/* abolish direct buckets */
|
||||||
|
buckets -= THREADS_DIRECT_BUCKETS;
|
||||||
|
FREE_BUCKETS(buckets);
|
||||||
|
#endif /* THREADS_SUBGOAL_SHARING */
|
||||||
|
}
|
||||||
|
#endif /* THREADS */
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_node_ptr get_insert_subgoal_trie(tab_ent_ptr tab_ent USES_REGS) {
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
sg_node_ptr *sg_node_addr = (sg_node_ptr *) get_insert_thread_bucket((void **) &TabEnt_subgoal_trie(tab_ent), &TabEnt_lock(tab_ent));
|
||||||
|
if (*sg_node_addr == NULL) {
|
||||||
|
new_subgoal_trie_node(*sg_node_addr, 0, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
return *sg_node_addr;
|
||||||
|
#else
|
||||||
|
return TabEnt_subgoal_trie(tab_ent);
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_node_ptr get_subgoal_trie(tab_ent_ptr tab_ent) {
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
sg_node_ptr *sg_node_addr = (sg_node_ptr *) get_thread_bucket((void **) &TabEnt_subgoal_trie(tab_ent));
|
||||||
|
return *sg_node_addr;
|
||||||
|
#else
|
||||||
|
return TabEnt_subgoal_trie(tab_ent);
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_node_ptr get_subgoal_trie_for_abolish(tab_ent_ptr tab_ent USES_REGS) {
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
sg_node_ptr *sg_node_addr = (sg_node_ptr *) get_thread_bucket((void **) &TabEnt_subgoal_trie(tab_ent));
|
||||||
|
sg_node_ptr sg_node = *sg_node_addr;
|
||||||
|
*sg_node_addr = NULL;
|
||||||
|
if (worker_id == 0)
|
||||||
|
abolish_thread_buckets((void **) &TabEnt_subgoal_trie(tab_ent));
|
||||||
|
return sg_node;
|
||||||
|
#else
|
||||||
|
return TabEnt_subgoal_trie(tab_ent);
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_fr_ptr *get_insert_subgoal_frame_addr(sg_node_ptr sg_node USES_REGS) {
|
||||||
|
sg_fr_ptr *sg_fr_addr = (sg_fr_ptr *) &TrNode_sg_fr(sg_node);
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING) || defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
if (*sg_fr_addr == NULL) {
|
||||||
|
LOCK_SUBGOAL_NODE(sg_node);
|
||||||
|
if (*sg_fr_addr == NULL) {
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING)
|
||||||
|
ALLOC_BUCKETS(TrNode_sg_fr(sg_node), THREADS_NUM_BUCKETS);
|
||||||
|
#elif defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
sg_ent_ptr sg_ent;
|
||||||
|
new_subgoal_entry(sg_ent);
|
||||||
|
TrNode_sg_ent(sg_node) = (sg_node_ptr) sg_ent;
|
||||||
|
#endif
|
||||||
|
TAG_AS_SUBGOAL_LEAF_NODE(sg_node);
|
||||||
|
}
|
||||||
|
UNLOCK_SUBGOAL_NODE(sg_node);
|
||||||
|
}
|
||||||
|
sg_fr_addr = (sg_fr_ptr *) get_insert_thread_bucket(
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING)
|
||||||
|
(void **) UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node)),
|
||||||
|
#elif defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
(void **) &SgEnt_sg_fr(UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node))),
|
||||||
|
#endif
|
||||||
|
#ifdef SUBGOAL_TRIE_LOCK_USING_NODE_FIELD
|
||||||
|
&TrNode_lock(sg_node)
|
||||||
|
#elif defined(SUBGOAL_TRIE_LOCK_USING_GLOBAL_ARRAY)
|
||||||
|
&HASH_TRIE_LOCK(sg_node)
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
#endif /* THREADS_SUBGOAL_SHARING || THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
return sg_fr_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_fr_ptr get_subgoal_frame(sg_node_ptr sg_node) {
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING)
|
||||||
|
sg_fr_ptr *sg_fr_addr = (sg_fr_ptr *) get_thread_bucket((void **) UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node)));
|
||||||
|
return *sg_fr_addr;
|
||||||
|
#elif defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
sg_fr_ptr *sg_fr_addr = (sg_fr_ptr *) get_thread_bucket((void **) &SgEnt_sg_fr(UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node))));
|
||||||
|
return *sg_fr_addr;
|
||||||
|
#else
|
||||||
|
return UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_fr_ptr get_subgoal_frame_for_abolish(sg_node_ptr sg_node USES_REGS) {
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING)
|
||||||
|
sg_fr_ptr *sg_fr_addr = (sg_fr_ptr *) get_thread_bucket((void **) UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node)));
|
||||||
|
sg_fr_ptr sg_fr = *sg_fr_addr;
|
||||||
|
if (worker_id == 0)
|
||||||
|
abolish_thread_buckets((void **) UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node)));
|
||||||
|
else
|
||||||
|
*sg_fr_addr = NULL;
|
||||||
|
return sg_fr;
|
||||||
|
#elif defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
sg_fr_ptr *sg_fr_addr = (sg_fr_ptr *) get_thread_bucket((void **) &SgEnt_sg_fr(UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node))));
|
||||||
|
sg_fr_ptr sg_fr = *sg_fr_addr;
|
||||||
|
if (worker_id == 0)
|
||||||
|
abolish_thread_buckets((void **) &SgEnt_sg_fr(UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node))));
|
||||||
|
else
|
||||||
|
*sg_fr_addr = NULL;
|
||||||
|
return sg_fr;
|
||||||
|
#else
|
||||||
|
return UNTAG_SUBGOAL_NODE(TrNode_sg_fr(sg_node));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
static inline void SgFr_batched_cached_answers_check_insert(sg_fr_ptr sg_fr, ans_node_ptr ans_node) {
|
||||||
|
CACHE_REGS
|
||||||
|
|
||||||
|
if (SgFr_batched_last_answer(sg_fr) == NULL)
|
||||||
|
SgFr_batched_last_answer(sg_fr) = SgFr_first_answer(sg_fr);
|
||||||
|
else
|
||||||
|
SgFr_batched_last_answer(sg_fr) = TrNode_child(SgFr_batched_last_answer(sg_fr)) ;
|
||||||
|
|
||||||
|
while (SgFr_batched_last_answer(sg_fr) != ans_node) {
|
||||||
|
struct answer_ref_node *ref_node = NULL;
|
||||||
|
if (SgFr_batched_cached_answers(sg_fr) == NULL) {
|
||||||
|
new_answer_ref_node(ref_node, SgFr_batched_last_answer(sg_fr), NULL, NULL);
|
||||||
|
} else {
|
||||||
|
new_answer_ref_node(ref_node, SgFr_batched_last_answer(sg_fr), SgFr_batched_cached_answers(sg_fr), NULL);
|
||||||
|
RefNode_previous(SgFr_batched_cached_answers(sg_fr)) = ref_node;
|
||||||
|
}
|
||||||
|
SgFr_batched_cached_answers(sg_fr) = ref_node;
|
||||||
|
SgFr_batched_last_answer(sg_fr) = TrNode_child(SgFr_batched_last_answer(sg_fr)) ;
|
||||||
|
}
|
||||||
|
if (ans_node != NULL)
|
||||||
|
/* new answer */
|
||||||
|
SgFr_batched_last_answer(sg_fr) = ans_node;
|
||||||
|
else
|
||||||
|
/* repeated answer */
|
||||||
|
SgFr_batched_last_answer(sg_fr) = SgFr_last_answer(sg_fr);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int SgFr_batched_cached_answers_check_remove(sg_fr_ptr sg_fr, ans_node_ptr ans_node) {
|
||||||
|
CACHE_REGS
|
||||||
|
struct answer_ref_node *local_uncons_ans;
|
||||||
|
|
||||||
|
local_uncons_ans = SgFr_batched_cached_answers(sg_fr) ;
|
||||||
|
while ( local_uncons_ans != NULL ) {
|
||||||
|
if ( RefNode_answer(local_uncons_ans) == ans_node )
|
||||||
|
break;
|
||||||
|
local_uncons_ans = RefNode_next(local_uncons_ans) ;
|
||||||
|
}
|
||||||
|
if ( local_uncons_ans == NULL )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/*remove node from buffer */
|
||||||
|
if (RefNode_previous(local_uncons_ans) == NULL) {
|
||||||
|
SgFr_batched_cached_answers(sg_fr) = RefNode_next(local_uncons_ans) ;
|
||||||
|
if (SgFr_batched_cached_answers(sg_fr) != NULL)
|
||||||
|
RefNode_previous(SgFr_batched_cached_answers(sg_fr)) = NULL;
|
||||||
|
} else{
|
||||||
|
RefNode_next(RefNode_previous(local_uncons_ans)) = RefNode_next(local_uncons_ans);
|
||||||
|
if (RefNode_next(local_uncons_ans) != NULL)
|
||||||
|
RefNode_previous(RefNode_next(local_uncons_ans)) = RefNode_previous(local_uncons_ans);
|
||||||
|
}
|
||||||
|
FREE_ANSWER_REF_NODE(local_uncons_ans);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
static inline void add_to_tdv(int wid, int wid_dep) {
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
|
CACHE_REGS
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
|
// thread wid next of thread wid_dep
|
||||||
|
/* check before insert */
|
||||||
|
int c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
do {
|
||||||
|
if (c_wid == wid_dep)
|
||||||
|
break;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
} while( c_wid != wid );
|
||||||
|
if (c_wid == wid_dep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wid < wid_dep) {
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid)));
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid_dep)));
|
||||||
|
} else {
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid_dep)));
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid)));
|
||||||
|
}
|
||||||
|
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
do {
|
||||||
|
if (c_wid == wid_dep)
|
||||||
|
break;
|
||||||
|
c_wid = ThDepFr_next(GLOBAL_th_dep_fr(c_wid));
|
||||||
|
} while( c_wid != wid );
|
||||||
|
if ( c_wid == wid ){
|
||||||
|
// joining the two different SCCs
|
||||||
|
int t = ThDepFr_next(GLOBAL_th_dep_fr(wid));
|
||||||
|
ThDepFr_next(GLOBAL_th_dep_fr(wid)) = ThDepFr_next(GLOBAL_th_dep_fr(wid_dep));
|
||||||
|
ThDepFr_next(GLOBAL_th_dep_fr(wid_dep)) = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO_THREADS("add_to_tdv (2) :tdv_next[%d] = %d tdv_next[%d]= %d", wid, ThDepFr_next(GLOBAL_th_dep_fr(wid)), wid_dep, ThDepFr_next(GLOBAL_th_dep_fr(wid_dep)));
|
||||||
|
|
||||||
|
UNLOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid)));
|
||||||
|
UNLOCK(ThDepFr_lock(GLOBAL_th_dep_fr(wid_dep)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void check_for_deadlock(sg_fr_ptr sg_fr) {
|
||||||
|
CACHE_REGS
|
||||||
|
sg_fr_ptr local_sg_fr = deadlock_detection(sg_fr);
|
||||||
|
|
||||||
|
if (local_sg_fr){
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(worker_id)));
|
||||||
|
if (YOUNGER_CP(DepFr_leader_cp(LOCAL_top_dep_fr),SgFr_gen_cp(local_sg_fr)))
|
||||||
|
DepFr_leader_cp(LOCAL_top_dep_fr) = SgFr_gen_cp(local_sg_fr);
|
||||||
|
|
||||||
|
UNLOCK(ThDepFr_lock(GLOBAL_th_dep_fr(worker_id)));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline sg_fr_ptr deadlock_detection(sg_fr_ptr sg_fr) {
|
||||||
|
CACHE_REGS
|
||||||
|
sg_fr_ptr remote_sg_fr = REMOTE_top_sg_fr(SgFr_gen_worker(sg_fr));
|
||||||
|
|
||||||
|
while( SgFr_sg_ent(remote_sg_fr) != SgFr_sg_ent(sg_fr)){
|
||||||
|
sg_fr_ptr local_sg_fr = SgFr_next(LOCAL_top_sg_fr);
|
||||||
|
while(local_sg_fr){
|
||||||
|
if ( SgFr_sg_ent(local_sg_fr) == SgFr_sg_ent(remote_sg_fr) ||
|
||||||
|
( SgFr_gen_worker(remote_sg_fr) != SgFr_gen_worker(sg_fr) && /* jump to other chain */
|
||||||
|
SgFr_gen_worker(remote_sg_fr) != worker_id && /* not jumping to the chain of the thread that is detecting the deadlock */
|
||||||
|
deadlock_detection(remote_sg_fr))){
|
||||||
|
|
||||||
|
sg_fr_ptr leader_remote_sg_fr;
|
||||||
|
do
|
||||||
|
leader_remote_sg_fr = SgFr_next(remote_sg_fr);
|
||||||
|
while(SgFr_sg_ent(leader_remote_sg_fr) != SgFr_sg_ent(sg_fr));
|
||||||
|
LOCK(ThDepFr_lock(GLOBAL_th_dep_fr(SgFr_gen_worker(leader_remote_sg_fr))));
|
||||||
|
|
||||||
|
if (YOUNGER_CP(DepFr_leader_cp(REMOTE_top_dep_fr(SgFr_gen_worker(leader_remote_sg_fr))),SgFr_gen_cp(leader_remote_sg_fr)))
|
||||||
|
DepFr_leader_cp(REMOTE_top_dep_fr(SgFr_gen_worker(leader_remote_sg_fr))) = SgFr_gen_cp(leader_remote_sg_fr);
|
||||||
|
UNLOCK(ThDepFr_lock(GLOBAL_th_dep_fr(SgFr_gen_worker(leader_remote_sg_fr))));
|
||||||
|
|
||||||
|
add_to_tdv(SgFr_gen_worker(local_sg_fr),SgFr_gen_worker(leader_remote_sg_fr));
|
||||||
|
|
||||||
|
return local_sg_fr;
|
||||||
|
}
|
||||||
|
local_sg_fr = SgFr_next(local_sg_fr);
|
||||||
|
}
|
||||||
|
remote_sg_fr = SgFr_next(remote_sg_fr);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
|
||||||
static inline Int freeze_current_cp(void) {
|
static inline Int freeze_current_cp(void) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
choiceptr freeze_cp = B;
|
choiceptr freeze_cp = B;
|
||||||
@ -606,8 +1031,17 @@ static inline void adjust_freeze_registers(void) {
|
|||||||
|
|
||||||
|
|
||||||
static inline void mark_as_completed(sg_fr_ptr sg_fr) {
|
static inline void mark_as_completed(sg_fr_ptr sg_fr) {
|
||||||
|
#ifdef OUTPUT_THREADS_TABLING
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
#endif /* OUTPUT_THREADS_TABLING */
|
||||||
|
|
||||||
LOCK_SG_FR(sg_fr);
|
LOCK_SG_FR(sg_fr);
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
INFO_THREADS(" mark_as_completed sgfr=%p ", SgFr_sg_ent(sg_fr));
|
||||||
|
TABLING_ERROR_CHECKING(mark_as_completed, SgFr_sg_ent_state(sg_fr) > complete);
|
||||||
|
SgFr_active_workers(sg_fr)--;
|
||||||
|
SgFr_sg_ent_state(sg_fr) = complete;
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
SgFr_state(sg_fr) = complete;
|
SgFr_state(sg_fr) = complete;
|
||||||
UNLOCK_SG_FR(sg_fr);
|
UNLOCK_SG_FR(sg_fr);
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
@ -615,13 +1049,13 @@ static inline void mark_as_completed(sg_fr_ptr sg_fr) {
|
|||||||
ans_node_ptr current_node, next_node;
|
ans_node_ptr current_node, next_node;
|
||||||
/* find first valid answer */
|
/* find first valid answer */
|
||||||
current_node = SgFr_first_answer(sg_fr);
|
current_node = SgFr_first_answer(sg_fr);
|
||||||
while (IS_INVALID_LEAF_NODE(current_node))
|
while (IS_ANSWER_INVALID_NODE(current_node))
|
||||||
current_node = TrNode_child(current_node);
|
current_node = TrNode_child(current_node);
|
||||||
SgFr_first_answer(sg_fr) = current_node;
|
SgFr_first_answer(sg_fr) = current_node;
|
||||||
/* chain next valid answers */
|
/* chain next valid answers */
|
||||||
next_node = TrNode_child(current_node);
|
next_node = TrNode_child(current_node);
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
if (! IS_INVALID_LEAF_NODE(next_node)) {
|
if (! IS_ANSWER_INVALID_NODE(next_node)) {
|
||||||
TrNode_child(current_node) = next_node;
|
TrNode_child(current_node) = next_node;
|
||||||
current_node = next_node;
|
current_node = next_node;
|
||||||
}
|
}
|
||||||
@ -850,13 +1284,13 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) {
|
|||||||
ans_node_ptr current_node, next_node;
|
ans_node_ptr current_node, next_node;
|
||||||
/* find first valid answer */
|
/* find first valid answer */
|
||||||
current_node = SgFr_first_answer(sg_fr);
|
current_node = SgFr_first_answer(sg_fr);
|
||||||
while (IS_INVALID_LEAF_NODE(current_node))
|
while (IS_ANSWER_INVALID_NODE(current_node))
|
||||||
current_node = TrNode_child(current_node);
|
current_node = TrNode_child(current_node);
|
||||||
SgFr_first_answer(sg_fr) = current_node;
|
SgFr_first_answer(sg_fr) = current_node;
|
||||||
/* chain next valid answers */
|
/* chain next valid answers */
|
||||||
next_node = TrNode_child(current_node);
|
next_node = TrNode_child(current_node);
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
if (! IS_INVALID_LEAF_NODE(next_node)) {
|
if (! IS_ANSWER_INVALID_NODE(next_node)) {
|
||||||
TrNode_child(current_node) = next_node;
|
TrNode_child(current_node) = next_node;
|
||||||
current_node = next_node;
|
current_node = next_node;
|
||||||
}
|
}
|
||||||
@ -882,14 +1316,50 @@ static inline void abolish_incomplete_subgoals(choiceptr prune_cp) {
|
|||||||
SgFr_invalid_chain(sg_fr) = NULL;
|
SgFr_invalid_chain(sg_fr) = NULL;
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
SgFr_state(sg_fr) = ready;
|
SgFr_state(sg_fr) = ready;
|
||||||
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
SgFr_hash_chain(sg_fr) = NULL;
|
if (SgFr_active_workers(sg_fr) == 0) {
|
||||||
SgFr_first_answer(sg_fr) = NULL;
|
SgFr_sg_ent_state(sg_fr) = ready;
|
||||||
SgFr_last_answer(sg_fr) = NULL;
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
node = TrNode_child(SgFr_answer_trie(sg_fr));
|
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
||||||
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL;
|
SgFr_hash_chain(sg_fr) = NULL;
|
||||||
UNLOCK_SG_FR(sg_fr);
|
SgFr_first_answer(sg_fr) = NULL;
|
||||||
free_answer_trie(node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
SgFr_last_answer(sg_fr) = NULL;
|
||||||
|
node = TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
|
TrNode_child(SgFr_answer_trie(sg_fr)) = NULL;
|
||||||
|
UNLOCK_SG_FR(sg_fr);
|
||||||
|
free_answer_trie(node, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
||||||
|
SgFr_batched_last_answer(sg_fr) = NULL;
|
||||||
|
struct answer_ref_node *local_uncons_ans = SgFr_batched_cached_answers(sg_fr) ;
|
||||||
|
while ( local_uncons_ans ) {
|
||||||
|
SgFr_batched_cached_answers(sg_fr) = RefNode_next(SgFr_batched_cached_answers(sg_fr));
|
||||||
|
FREE_ANSWER_REF_NODE(local_uncons_ans);
|
||||||
|
local_uncons_ans = SgFr_batched_cached_answers(sg_fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else{ /* SgFr_active_workers(sg_fr) != 0 */
|
||||||
|
if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))){
|
||||||
|
SgFr_batched_last_answer(sg_fr) = NULL;
|
||||||
|
if ( worker_id >= ANSWER_LEAF_NODE_MAX_THREADS ) {
|
||||||
|
struct answer_ref_node *local_uncons_ans = SgFr_batched_cached_answers(sg_fr) ;
|
||||||
|
while ( local_uncons_ans ) {
|
||||||
|
SgFr_batched_cached_answers(sg_fr) = RefNode_next(SgFr_batched_cached_answers(sg_fr));
|
||||||
|
FREE_ANSWER_REF_NODE(local_uncons_ans);
|
||||||
|
local_uncons_ans = SgFr_batched_cached_answers(sg_fr);
|
||||||
|
}
|
||||||
|
} else { /* worker_id < ANSWER_LEAF_NODE_MAX_THREADS */
|
||||||
|
ans_node_ptr leaf_ans_trie_node = SgFr_first_answer(sg_fr);
|
||||||
|
while( leaf_ans_trie_node ){
|
||||||
|
ANSWER_LEAF_NODE_DEL_WID(leaf_ans_trie_node,worker_id);
|
||||||
|
leaf_ans_trie_node = TrNode_child(leaf_ans_trie_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
#if defined(MODE_DIRECTED_TABLING) && ! defined(YAPOR)
|
#if defined(MODE_DIRECTED_TABLING) && ! defined(YAPOR)
|
||||||
/* free invalid answer nodes */
|
/* free invalid answer nodes */
|
||||||
while (invalid_node) {
|
while (invalid_node) {
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
**************************/
|
**************************/
|
||||||
|
|
||||||
typedef struct table_entry {
|
typedef struct table_entry {
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL) || defined(THREADS_NO_SHARING)
|
||||||
lockvar lock;
|
lockvar lock;
|
||||||
#endif /* YAPOR || THREADS */
|
#endif /* SUBGOAL_TRIE_LOCK_AT_ENTRY_LEVEL || THREADS_NO_SHARING */
|
||||||
struct pred_entry *pred_entry;
|
struct pred_entry *pred_entry;
|
||||||
Atom pred_atom;
|
Atom pred_atom;
|
||||||
int pred_arity;
|
int pred_arity;
|
||||||
@ -32,7 +32,7 @@ typedef struct table_entry {
|
|||||||
int* mode_directed_array;
|
int* mode_directed_array;
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
#ifdef THREADS_NO_SHARING
|
#ifdef THREADS_NO_SHARING
|
||||||
struct subgoal_trie_node *subgoal_trie[THREADS_FIRST_LEVEL_BUCKETS];
|
struct subgoal_trie_node *subgoal_trie[THREADS_NUM_BUCKETS];
|
||||||
#else
|
#else
|
||||||
struct subgoal_trie_node *subgoal_trie;
|
struct subgoal_trie_node *subgoal_trie;
|
||||||
#endif /* THREADS_NO_SHARING */
|
#endif /* THREADS_NO_SHARING */
|
||||||
@ -47,12 +47,7 @@ typedef struct table_entry {
|
|||||||
#define TabEnt_flags(X) ((X)->pred_flags)
|
#define TabEnt_flags(X) ((X)->pred_flags)
|
||||||
#define TabEnt_mode(X) ((X)->execution_mode)
|
#define TabEnt_mode(X) ((X)->execution_mode)
|
||||||
#define TabEnt_mode_directed(X) ((X)->mode_directed_array)
|
#define TabEnt_mode_directed(X) ((X)->mode_directed_array)
|
||||||
#ifdef THREADS_NO_SHARING
|
|
||||||
#define TabEnt_subgoal_trie(X) ((X)->subgoal_trie[worker_id])
|
|
||||||
//#define TabEnt_subgoal_trie(X,I) ((X)->subgoal_trie[I])
|
|
||||||
#else
|
|
||||||
#define TabEnt_subgoal_trie(X) ((X)->subgoal_trie)
|
#define TabEnt_subgoal_trie(X) ((X)->subgoal_trie)
|
||||||
#endif /* THREADS_NO_SHARING */
|
|
||||||
#define TabEnt_hash_chain(X) ((X)->hash_chain)
|
#define TabEnt_hash_chain(X) ((X)->hash_chain)
|
||||||
#define TabEnt_next(X) ((X)->next)
|
#define TabEnt_next(X) ((X)->next)
|
||||||
|
|
||||||
@ -102,11 +97,30 @@ typedef struct global_trie_node {
|
|||||||
#define TrNode_parent(X) ((X)->parent)
|
#define TrNode_parent(X) ((X)->parent)
|
||||||
#define TrNode_child(X) ((X)->child)
|
#define TrNode_child(X) ((X)->child)
|
||||||
#define TrNode_sg_fr(X) ((X)->child)
|
#define TrNode_sg_fr(X) ((X)->child)
|
||||||
|
#define TrNode_sg_ent(X) ((X)->child)
|
||||||
#define TrNode_next(X) ((X)->next)
|
#define TrNode_next(X) ((X)->next)
|
||||||
#define TrNode_lock(X) ((X)->lock)
|
#define TrNode_lock(X) ((X)->lock)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
** answer_ref_node **
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
typedef struct answer_ref_node {
|
||||||
|
struct answer_trie_node *ans_node;
|
||||||
|
struct answer_ref_node *next;
|
||||||
|
struct answer_ref_node *previous;
|
||||||
|
} *ans_ref_ptr;
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
|
||||||
|
#define RefNode_answer(X) ((X)->ans_node)
|
||||||
|
#define RefNode_next(X) ((X)->next)
|
||||||
|
#define RefNode_previous(X) ((X)->previous)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
** subgoal_trie_hash, answer_trie_hash and global_trie_hash **
|
** subgoal_trie_hash, answer_trie_hash and global_trie_hash **
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@ -118,7 +132,9 @@ typedef struct subgoal_trie_hash {
|
|||||||
int number_of_buckets;
|
int number_of_buckets;
|
||||||
struct subgoal_trie_node **buckets;
|
struct subgoal_trie_node **buckets;
|
||||||
int number_of_nodes;
|
int number_of_nodes;
|
||||||
|
#ifdef USE_PAGES_MALLOC
|
||||||
struct subgoal_trie_hash *next;
|
struct subgoal_trie_hash *next;
|
||||||
|
#endif /* USE_PAGES_MALLOC */
|
||||||
} *sg_hash_ptr;
|
} *sg_hash_ptr;
|
||||||
|
|
||||||
typedef struct answer_trie_hash {
|
typedef struct answer_trie_hash {
|
||||||
@ -155,24 +171,6 @@ typedef struct global_trie_hash {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************
|
|
||||||
** answer_ref_node **
|
|
||||||
******************************/
|
|
||||||
|
|
||||||
#ifdef THREADS_FULL_SHARING
|
|
||||||
typedef struct answer_ref_node {
|
|
||||||
struct answer_trie_node *ans_node;
|
|
||||||
struct answer_ref_node *next;
|
|
||||||
struct answer_ref_node *previous;
|
|
||||||
} *ans_ref_ptr;
|
|
||||||
#endif /* THREADS_FULL_SHARING */
|
|
||||||
|
|
||||||
#define RefNode_answer(X) ((X)->ans_node)
|
|
||||||
#define RefNode_next(X) ((X)->next)
|
|
||||||
#define RefNode_previous(X) ((X)->previous)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
** Execution Data Structures **
|
** Execution Data Structures **
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
@ -267,7 +265,7 @@ typedef struct subgoal_entry {
|
|||||||
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
subgoal_state_flag state_flag;
|
subgoal_state_flag state_flag;
|
||||||
int active_workers;
|
int active_workers;
|
||||||
struct subgoal_frame *subgoal_frame[THREADS_FIRST_LEVEL_BUCKETS];
|
struct subgoal_frame *subgoal_frame[THREADS_NUM_BUCKETS];
|
||||||
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
}* sg_ent_ptr;
|
}* sg_ent_ptr;
|
||||||
|
|
||||||
@ -287,7 +285,7 @@ typedef struct subgoal_entry {
|
|||||||
#define SgEnt_gen_worker(X) ((X)->generator_worker)
|
#define SgEnt_gen_worker(X) ((X)->generator_worker)
|
||||||
#define SgEnt_sg_ent_state(X) ((X)->state_flag)
|
#define SgEnt_sg_ent_state(X) ((X)->state_flag)
|
||||||
#define SgEnt_active_workers(X) ((X)->active_workers)
|
#define SgEnt_active_workers(X) ((X)->active_workers)
|
||||||
#define SgEnt_sg_fr(X,I) ((X)->subgoal_frame[I])
|
#define SgEnt_sg_fr(X) ((X)->subgoal_frame)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -312,10 +310,10 @@ typedef struct subgoal_frame {
|
|||||||
|
|
||||||
/* subgoal_entry fields */
|
/* subgoal_entry fields */
|
||||||
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
#define SUBGOAL_ENTRY(X) SgFr_subgoal_entry(X)->
|
#define SUBGOAL_ENTRY(X) SgFr_sg_ent(X)->
|
||||||
#else
|
#else
|
||||||
#define SUBGOAL_ENTRY(X) (X)->subgoal_entry.
|
#define SUBGOAL_ENTRY(X) (X)->subgoal_entry.
|
||||||
#endif /* THREADS */
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
#define SgFr_lock(X) (SUBGOAL_ENTRY(X) lock)
|
#define SgFr_lock(X) (SUBGOAL_ENTRY(X) lock)
|
||||||
#define SgFr_code(X) (SUBGOAL_ENTRY(X) code_of_subgoal)
|
#define SgFr_code(X) (SUBGOAL_ENTRY(X) code_of_subgoal)
|
||||||
#define SgFr_tab_ent(X) ((SUBGOAL_ENTRY(X) code_of_subgoal)->u.Otapl.te)
|
#define SgFr_tab_ent(X) ((SUBGOAL_ENTRY(X) code_of_subgoal)->u.Otapl.te)
|
||||||
@ -333,7 +331,7 @@ typedef struct subgoal_frame {
|
|||||||
#define SgFr_sg_ent_state(X) (SUBGOAL_ENTRY(X) state_flag)
|
#define SgFr_sg_ent_state(X) (SUBGOAL_ENTRY(X) state_flag)
|
||||||
#define SgFr_active_workers(X) (SUBGOAL_ENTRY(X) active_workers)
|
#define SgFr_active_workers(X) (SUBGOAL_ENTRY(X) active_workers)
|
||||||
/* subgoal_frame fields */
|
/* subgoal_frame fields */
|
||||||
#define SgFr_subgoal_entry(X) ((X)->subgoal_entry)
|
#define SgFr_sg_ent(X) ((X)->subgoal_entry)
|
||||||
#define SgFr_batched_last_answer(X) ((X)->batched_last_answer)
|
#define SgFr_batched_last_answer(X) ((X)->batched_last_answer)
|
||||||
#define SgFr_batched_cached_answers(X) ((X)->batched_cached_answers)
|
#define SgFr_batched_cached_answers(X) ((X)->batched_cached_answers)
|
||||||
#define SgFr_state(X) ((X)->state_flag)
|
#define SgFr_state(X) ((X)->state_flag)
|
||||||
@ -363,7 +361,7 @@ typedef struct subgoal_frame {
|
|||||||
SgFr_gen_worker: the id of the worker that had allocated the frame.
|
SgFr_gen_worker: the id of the worker that had allocated the frame.
|
||||||
SgFr_sg_ent_state: a flag that indicates the subgoal entry state.
|
SgFr_sg_ent_state: a flag that indicates the subgoal entry state.
|
||||||
SgFr_active_workers: the number of workers evaluating the subgoal.
|
SgFr_active_workers: the number of workers evaluating the subgoal.
|
||||||
SgFr_subgoal_entry: a pointer to the corresponding subgoal entry.
|
SgFr_sg_ent: a pointer to the corresponding subgoal entry.
|
||||||
SgFr_batched_last_answer: a pointer to the leaf answer trie node of the last checked answer
|
SgFr_batched_last_answer: a pointer to the leaf answer trie node of the last checked answer
|
||||||
when using batched scheduling.
|
when using batched scheduling.
|
||||||
SgFr_batched_cached_answers: a pointer to the chain of answers already inserted in the trie, but not
|
SgFr_batched_cached_answers: a pointer to the chain of answers already inserted in the trie, but not
|
||||||
@ -389,13 +387,13 @@ typedef struct dependency_frame {
|
|||||||
long timestamp;
|
long timestamp;
|
||||||
#endif /* TIMESTAMP_CHECK */
|
#endif /* TIMESTAMP_CHECK */
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
int generator_is_external;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
choiceptr backchain_choice_point;
|
choiceptr backchain_choice_point;
|
||||||
choiceptr leader_choice_point;
|
choiceptr leader_choice_point;
|
||||||
choiceptr consumer_choice_point;
|
choiceptr consumer_choice_point;
|
||||||
struct answer_trie_node *last_consumed_answer;
|
struct answer_trie_node *last_consumed_answer;
|
||||||
#ifdef THREADS_CONSUMER_SHARING
|
|
||||||
int generator_is_external;
|
|
||||||
#endif /* THREADS_CONSUMER_SHARING */
|
|
||||||
struct dependency_frame *next;
|
struct dependency_frame *next;
|
||||||
} *dep_fr_ptr;
|
} *dep_fr_ptr;
|
||||||
|
|
||||||
@ -403,11 +401,11 @@ typedef struct dependency_frame {
|
|||||||
#define DepFr_leader_dep_is_on_stack(X) ((X)->leader_dependency_is_on_stack)
|
#define DepFr_leader_dep_is_on_stack(X) ((X)->leader_dependency_is_on_stack)
|
||||||
#define DepFr_top_or_fr(X) ((X)->top_or_frame)
|
#define DepFr_top_or_fr(X) ((X)->top_or_frame)
|
||||||
#define DepFr_timestamp(X) ((X)->timestamp)
|
#define DepFr_timestamp(X) ((X)->timestamp)
|
||||||
|
#define DepFr_external(X) ((X)->generator_is_external)
|
||||||
#define DepFr_backchain_cp(X) ((X)->backchain_choice_point)
|
#define DepFr_backchain_cp(X) ((X)->backchain_choice_point)
|
||||||
#define DepFr_leader_cp(X) ((X)->leader_choice_point)
|
#define DepFr_leader_cp(X) ((X)->leader_choice_point)
|
||||||
#define DepFr_cons_cp(X) ((X)->consumer_choice_point)
|
#define DepFr_cons_cp(X) ((X)->consumer_choice_point)
|
||||||
#define DepFr_last_answer(X) ((X)->last_consumed_answer)
|
#define DepFr_last_answer(X) ((X)->last_consumed_answer)
|
||||||
#define DepFr_external(X) ((X)->generator_is_external)
|
|
||||||
#define DepFr_next(X) ((X)->next)
|
#define DepFr_next(X) ((X)->next)
|
||||||
|
|
||||||
/*********************************************************************************************************
|
/*********************************************************************************************************
|
||||||
@ -421,13 +419,13 @@ typedef struct dependency_frame {
|
|||||||
backtracks through answers.
|
backtracks through answers.
|
||||||
DepFr_timestamp: a timestamp used to optimize the search for suspension frames to be
|
DepFr_timestamp: a timestamp used to optimize the search for suspension frames to be
|
||||||
resumed.
|
resumed.
|
||||||
|
DepFr_external: the generator choice point is external to the current thread (FALSE/TRUE).
|
||||||
DepFr_backchain_cp: a pointer to the nearest choice point with untried alternatives.
|
DepFr_backchain_cp: a pointer to the nearest choice point with untried alternatives.
|
||||||
It is used to efficiently return (backtrack) to the leader node where
|
It is used to efficiently return (backtrack) to the leader node where
|
||||||
we perform the last backtracking through answers operation.
|
we perform the last backtracking through answers operation.
|
||||||
DepFr_leader_cp: a pointer to the leader choice point.
|
DepFr_leader_cp: a pointer to the leader choice point.
|
||||||
DepFr_cons_cp: a pointer to the correspondent consumer choice point.
|
DepFr_cons_cp: a pointer to the correspondent consumer choice point.
|
||||||
DepFr_last_answer: a pointer to the last consumed answer.
|
DepFr_last_answer: a pointer to the last consumed answer.
|
||||||
DepFr_external: the generator choice point is external to the current thread (FALSE/TRUE).
|
|
||||||
DepFr_next: a pointer to the next dependency frame on the chain.
|
DepFr_next: a pointer to the next dependency frame on the chain.
|
||||||
|
|
||||||
*********************************************************************************************************/
|
*********************************************************************************************************/
|
||||||
|
@ -58,7 +58,6 @@ static void free_global_trie_branch(gt_node_ptr, int);
|
|||||||
#else
|
#else
|
||||||
static void free_global_trie_branch(gt_node_ptr);
|
static void free_global_trie_branch(gt_node_ptr);
|
||||||
#endif /* GLOBAL_TRIE_FOR_SUBTERMS */
|
#endif /* GLOBAL_TRIE_FOR_SUBTERMS */
|
||||||
|
|
||||||
static void traverse_subgoal_trie(sg_node_ptr, char *, int, int *, int, int);
|
static void traverse_subgoal_trie(sg_node_ptr, char *, int, int *, int, int);
|
||||||
static void traverse_answer_trie(ans_node_ptr, char *, int, int *, int, int, int);
|
static void traverse_answer_trie(ans_node_ptr, char *, int, int *, int, int, int);
|
||||||
static void traverse_global_trie(gt_node_ptr, char *, int, int *, int, int);
|
static void traverse_global_trie(gt_node_ptr, char *, int, int *, int, int);
|
||||||
@ -88,7 +87,25 @@ static struct trie_statistics{
|
|||||||
long global_trie_terms;
|
long global_trie_terms;
|
||||||
long global_trie_nodes;
|
long global_trie_nodes;
|
||||||
long global_trie_references;
|
long global_trie_references;
|
||||||
} trie_stats;
|
}
|
||||||
|
#ifdef THREADS
|
||||||
|
trie_stats[MAX_THREADS];
|
||||||
|
|
||||||
|
#define TrStat_out trie_stats[worker_id].out
|
||||||
|
#define TrStat_show trie_stats[worker_id].show
|
||||||
|
#define TrStat_subgoals trie_stats[worker_id].subgoals
|
||||||
|
#define TrStat_sg_incomplete trie_stats[worker_id].subgoals_incomplete
|
||||||
|
#define TrStat_sg_nodes trie_stats[worker_id].subgoal_trie_nodes
|
||||||
|
#define TrStat_answers trie_stats[worker_id].answers
|
||||||
|
#define TrStat_answers_true trie_stats[worker_id].answers_true
|
||||||
|
#define TrStat_answers_no trie_stats[worker_id].answers_no
|
||||||
|
#define TrStat_answers_pruned trie_stats[worker_id].answers_pruned
|
||||||
|
#define TrStat_ans_nodes trie_stats[worker_id].answer_trie_nodes
|
||||||
|
#define TrStat_gt_terms trie_stats[worker_id].global_trie_terms
|
||||||
|
#define TrStat_gt_nodes trie_stats[worker_id].global_trie_nodes
|
||||||
|
#define TrStat_gt_refs trie_stats[worker_id].global_trie_references
|
||||||
|
#else /*!THREADS */
|
||||||
|
trie_stats;
|
||||||
|
|
||||||
#define TrStat_out trie_stats.out
|
#define TrStat_out trie_stats.out
|
||||||
#define TrStat_show trie_stats.show
|
#define TrStat_show trie_stats.show
|
||||||
@ -103,6 +120,20 @@ static struct trie_statistics{
|
|||||||
#define TrStat_gt_terms trie_stats.global_trie_terms
|
#define TrStat_gt_terms trie_stats.global_trie_terms
|
||||||
#define TrStat_gt_nodes trie_stats.global_trie_nodes
|
#define TrStat_gt_nodes trie_stats.global_trie_nodes
|
||||||
#define TrStat_gt_refs trie_stats.global_trie_references
|
#define TrStat_gt_refs trie_stats.global_trie_references
|
||||||
|
#endif /*THREADS */
|
||||||
|
|
||||||
|
#if defined(THREADS_SUBGOAL_SHARING) || defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
#define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES if (worker_id == 0)
|
||||||
|
#else
|
||||||
|
#define IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES
|
||||||
|
#endif /* THREADS_SUBGOAL_SHARING || THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
#define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES if (worker_id == 0)
|
||||||
|
#else
|
||||||
|
#define IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
|
||||||
#define SHOW_TABLE_STR_ARRAY_SIZE 100000
|
#define SHOW_TABLE_STR_ARRAY_SIZE 100000
|
||||||
#define SHOW_TABLE_ARITY_ARRAY_SIZE 10000
|
#define SHOW_TABLE_ARITY_ARRAY_SIZE 10000
|
||||||
#define SHOW_TABLE_STRUCTURE(MESG, ARGS...) \
|
#define SHOW_TABLE_STRUCTURE(MESG, ARGS...) \
|
||||||
@ -441,6 +472,7 @@ static void update_answer_trie_branch(ans_node_ptr current_node, int position) {
|
|||||||
TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node) - position);
|
TrNode_instr(current_node) = Yap_opcode(TrNode_instr(current_node) - position);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
|
|
||||||
|
|
||||||
@ -470,7 +502,7 @@ static void free_global_trie_branch(gt_node_ptr current_node) {
|
|||||||
CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
|
CHECK_DECREMENT_GLOBAL_TRIE_FOR_SUBTERMS_REFERENCE(t, mode);
|
||||||
FREE_GLOBAL_TRIE_NODE(current_node);
|
FREE_GLOBAL_TRIE_NODE(current_node);
|
||||||
if (num_nodes == 0) {
|
if (num_nodes == 0) {
|
||||||
FREE_HASH_BUCKETS(Hash_buckets(hash));
|
FREE_BUCKETS(Hash_buckets(hash));
|
||||||
FREE_GLOBAL_TRIE_HASH(hash);
|
FREE_GLOBAL_TRIE_HASH(hash);
|
||||||
if (parent_node != GLOBAL_root_gt) {
|
if (parent_node != GLOBAL_root_gt) {
|
||||||
#ifdef GLOBAL_TRIE_FOR_SUBTERMS
|
#ifdef GLOBAL_TRIE_FOR_SUBTERMS
|
||||||
@ -547,6 +579,7 @@ static void free_global_trie_branch(gt_node_ptr current_node) {
|
|||||||
|
|
||||||
|
|
||||||
static void traverse_subgoal_trie(sg_node_ptr current_node, char *str, int str_index, int *arity, int mode, int position) {
|
static void traverse_subgoal_trie(sg_node_ptr current_node, char *str, int str_index, int *arity, int mode, int position) {
|
||||||
|
CACHE_REGS
|
||||||
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
|
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
|
||||||
|
|
||||||
/* test if hashing */
|
/* test if hashing */
|
||||||
@ -589,35 +622,35 @@ static void traverse_subgoal_trie(sg_node_ptr current_node, char *str, int str_i
|
|||||||
|
|
||||||
/* show answers ... */
|
/* show answers ... */
|
||||||
if (IS_SUBGOAL_LEAF_NODE(current_node)) {
|
if (IS_SUBGOAL_LEAF_NODE(current_node)) {
|
||||||
sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(TrNode_sg_fr(current_node));
|
sg_fr_ptr sg_fr = get_subgoal_frame(current_node);
|
||||||
TrStat_subgoals++;
|
if (sg_fr) {
|
||||||
str[str_index] = 0;
|
TrStat_subgoals++;
|
||||||
SHOW_TABLE_STRUCTURE("%s.\n", str);
|
str[str_index] = 0;
|
||||||
TrStat_ans_nodes++;
|
SHOW_TABLE_STRUCTURE("%s.\n", str);
|
||||||
if (SgFr_first_answer(sg_fr) == NULL) {
|
TrStat_ans_nodes++;
|
||||||
if (SgFr_state(sg_fr) < complete) {
|
if (SgFr_first_answer(sg_fr) == NULL) {
|
||||||
TrStat_sg_incomplete++;
|
if (SgFr_state(sg_fr) < complete) {
|
||||||
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
TrStat_sg_incomplete++;
|
||||||
|
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
||||||
|
} else {
|
||||||
|
TrStat_answers_no++;
|
||||||
|
SHOW_TABLE_STRUCTURE(" NO\n");
|
||||||
|
}
|
||||||
|
} else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) {
|
||||||
|
TrStat_answers_true++;
|
||||||
|
SHOW_TABLE_STRUCTURE(" TRUE\n");
|
||||||
} else {
|
} else {
|
||||||
TrStat_answers_no++;
|
arity[0] = 0;
|
||||||
SHOW_TABLE_STRUCTURE(" NO\n");
|
traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
||||||
}
|
if (SgFr_state(sg_fr) < complete) {
|
||||||
} else if (SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr)) {
|
TrStat_sg_incomplete++;
|
||||||
TrStat_answers_true++;
|
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
||||||
SHOW_TABLE_STRUCTURE(" TRUE\n");
|
}
|
||||||
} else {
|
|
||||||
arity[0] = 0;
|
|
||||||
traverse_answer_trie(TrNode_child(SgFr_answer_trie(sg_fr)), &str[str_index], 0, arity, 0, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
|
||||||
if (SgFr_state(sg_fr) < complete) {
|
|
||||||
TrStat_sg_incomplete++;
|
|
||||||
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
/* ... or continue with child node */
|
/* ... or continue with child node */
|
||||||
else
|
|
||||||
traverse_subgoal_trie(TrNode_child(current_node), str, str_index, arity, mode, TRAVERSE_POSITION_FIRST);
|
traverse_subgoal_trie(TrNode_child(current_node), str, str_index, arity, mode, TRAVERSE_POSITION_FIRST);
|
||||||
|
|
||||||
/* restore the initial state and continue with sibling nodes */
|
/* restore the initial state and continue with sibling nodes */
|
||||||
if (position == TRAVERSE_POSITION_FIRST) {
|
if (position == TRAVERSE_POSITION_FIRST) {
|
||||||
str_index = current_str_index;
|
str_index = current_str_index;
|
||||||
@ -637,12 +670,12 @@ static void traverse_subgoal_trie(sg_node_ptr current_node, char *str, int str_i
|
|||||||
}
|
}
|
||||||
free(current_arity);
|
free(current_arity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void traverse_answer_trie(ans_node_ptr current_node, char *str, int str_index, int *arity, int var_index, int mode, int position) {
|
static void traverse_answer_trie(ans_node_ptr current_node, char *str, int str_index, int *arity, int var_index, int mode, int position) {
|
||||||
|
CACHE_REGS
|
||||||
int *current_arity = NULL, current_str_index = 0, current_var_index = 0, current_mode = 0;
|
int *current_arity = NULL, current_str_index = 0, current_var_index = 0, current_mode = 0;
|
||||||
|
|
||||||
/* test if hashing */
|
/* test if hashing */
|
||||||
@ -733,6 +766,7 @@ static void traverse_answer_trie(ans_node_ptr current_node, char *str, int str_i
|
|||||||
|
|
||||||
|
|
||||||
static void traverse_global_trie(gt_node_ptr current_node, char *str, int str_index, int *arity, int mode, int position) {
|
static void traverse_global_trie(gt_node_ptr current_node, char *str, int str_index, int *arity, int mode, int position) {
|
||||||
|
CACHE_REGS
|
||||||
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
|
int *current_arity = NULL, current_str_index = 0, current_mode = 0;
|
||||||
|
|
||||||
/* test if hashing */
|
/* test if hashing */
|
||||||
@ -816,6 +850,7 @@ static void traverse_global_trie_for_term(gt_node_ptr current_node, char *str, i
|
|||||||
|
|
||||||
|
|
||||||
static inline void traverse_trie_node(Term t, char *str, int *str_index_ptr, int *arity, int *mode_ptr, int type) {
|
static inline void traverse_trie_node(Term t, char *str, int *str_index_ptr, int *arity, int *mode_ptr, int type) {
|
||||||
|
CACHE_REGS
|
||||||
int mode = *mode_ptr;
|
int mode = *mode_ptr;
|
||||||
int str_index = *str_index_ptr;
|
int str_index = *str_index_ptr;
|
||||||
|
|
||||||
@ -993,7 +1028,7 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
|
|||||||
subs_arity = 0;
|
subs_arity = 0;
|
||||||
pred_arity = preg->u.Otapl.s;
|
pred_arity = preg->u.Otapl.s;
|
||||||
tab_ent = preg->u.Otapl.te;
|
tab_ent = preg->u.Otapl.te;
|
||||||
current_sg_node = TabEnt_subgoal_trie(tab_ent);
|
current_sg_node = get_insert_subgoal_trie(tab_ent PASS_REGS);
|
||||||
LOCK_SUBGOAL_TRIE(tab_ent);
|
LOCK_SUBGOAL_TRIE(tab_ent);
|
||||||
|
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
@ -1033,8 +1068,11 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
|
|||||||
RESET_VARIABLE(t);
|
RESET_VARIABLE(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sg_fr_ptr *sg_fr_end = get_insert_subgoal_frame_addr(current_sg_node PASS_REGS);
|
||||||
|
#ifndef THREADS
|
||||||
LOCK_SUBGOAL_NODE(current_sg_node);
|
LOCK_SUBGOAL_NODE(current_sg_node);
|
||||||
if (TrNode_sg_fr(current_sg_node) == NULL) {
|
#endif /* !THREADS */
|
||||||
|
if (*sg_fr_end == NULL) {
|
||||||
/* new tabled subgoal */
|
/* new tabled subgoal */
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (subs_pos) {
|
if (subs_pos) {
|
||||||
@ -1043,18 +1081,46 @@ sg_fr_ptr subgoal_search(yamop *preg, CELL **Yaddr) {
|
|||||||
} else
|
} else
|
||||||
mode_directed = NULL;
|
mode_directed = NULL;
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
|
#ifndef THREADS
|
||||||
new_subgoal_frame(sg_fr, preg, mode_directed);
|
new_subgoal_frame(sg_fr, preg, mode_directed);
|
||||||
TrNode_sg_fr(current_sg_node) = (sg_node_ptr) sg_fr;
|
*sg_fr_end = sg_fr;
|
||||||
TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node);
|
TAG_AS_SUBGOAL_LEAF_NODE(current_sg_node);
|
||||||
|
UNLOCK_SUBGOAL_NODE(current_sg_node);
|
||||||
|
#else /* THREADS */
|
||||||
|
sg_ent_ptr sg_ent = (sg_ent_ptr) TrNode_sg_ent(current_sg_node);
|
||||||
|
new_subgoal_frame(sg_fr, sg_ent);
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
SgFr_state(sg_fr) = ready_external;
|
||||||
|
#else
|
||||||
|
SgFr_state(sg_fr) = ready;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
if (SgEnt_state(sg_ent) == ready) {
|
||||||
|
LOCK(SgEnt_lock(sg_ent));
|
||||||
|
if (SgEnt_state(sg_ent) == ready) {
|
||||||
|
SgEnt_gen_worker(sg_ent) = worker_id;
|
||||||
|
SgEnt_code(sg_ent) = preg;
|
||||||
|
SgEnt_init_mode_directed_fields(sg_ent, mode_directed);
|
||||||
|
SgEnt_state(sg_ent) = evaluating;
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
SgFr_state(sg_fr) = ready;
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
|
}
|
||||||
|
UNLOCK(SgEnt_lock(sg_ent));
|
||||||
|
}
|
||||||
|
*sg_fr_end = sg_fr;
|
||||||
|
#endif /* !THREADS */
|
||||||
} else {
|
} else {
|
||||||
sg_fr = UNTAG_SUBGOAL_LEAF_NODE(TrNode_sg_fr(current_sg_node));
|
/* repeated tabled subgoal */
|
||||||
|
#ifndef THREADS
|
||||||
|
UNLOCK_SUBGOAL_NODE(current_sg_node);
|
||||||
|
#endif /* !THREADS */
|
||||||
|
sg_fr = UNTAG_SUBGOAL_NODE(*sg_fr_end);
|
||||||
#ifdef LIMIT_TABLING
|
#ifdef LIMIT_TABLING
|
||||||
if (SgFr_state(sg_fr) <= ready) { /* incomplete or ready */
|
if (SgFr_state(sg_fr) <= ready) { /* incomplete or ready */
|
||||||
remove_from_global_sg_fr_list(sg_fr);
|
remove_from_global_sg_fr_list(sg_fr);
|
||||||
}
|
}
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
}
|
}
|
||||||
UNLOCK_SUBGOAL_NODE(current_sg_node);
|
|
||||||
UNLOCK_SUBGOAL_TRIE(tab_ent);
|
UNLOCK_SUBGOAL_TRIE(tab_ent);
|
||||||
return sg_fr;
|
return sg_fr;
|
||||||
}
|
}
|
||||||
@ -1069,6 +1135,7 @@ ans_node_ptr answer_search(sg_fr_ptr sg_fr, CELL *subs_ptr) {
|
|||||||
|
|
||||||
vars_arity = 0;
|
vars_arity = 0;
|
||||||
current_ans_node = SgFr_answer_trie(sg_fr);
|
current_ans_node = SgFr_answer_trie(sg_fr);
|
||||||
|
|
||||||
if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
if (IsMode_GlobalTrie(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
||||||
for (i = subs_arity; i >= 1; i--) {
|
for (i = subs_arity; i >= 1; i--) {
|
||||||
TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
|
TABLING_ERROR_CHECKING(answer_search, IsNonVarTerm(subs_ptr[i]));
|
||||||
@ -1228,6 +1295,21 @@ void update_answer_trie(sg_fr_ptr sg_fr) {
|
|||||||
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
||||||
SgFr_hash_chain(sg_fr) = NULL;
|
SgFr_hash_chain(sg_fr) = NULL;
|
||||||
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
|
SgFr_state(sg_fr) += 2; /* complete --> compiled : complete_in_use --> compiled_in_use */
|
||||||
|
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
SgFr_sg_ent_state(sg_fr) += 2; /* complete --> compiled */
|
||||||
|
#ifdef THREADS_FULL_SHARING
|
||||||
|
if (IsMode_Batched(TabEnt_mode(SgFr_tab_ent(sg_fr)))) {
|
||||||
|
/* cleaning bits used by batched mode and shifting the instruction back to the original place */
|
||||||
|
ans_node_ptr leaf_ans_trie_node = SgFr_first_answer(sg_fr);
|
||||||
|
while (TrNode_child(leaf_ans_trie_node) != NULL) {
|
||||||
|
ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node);
|
||||||
|
leaf_ans_trie_node = TrNode_child(leaf_ans_trie_node);
|
||||||
|
}
|
||||||
|
ANSWER_LEAF_NODE_INSTR_ABSOLUTE(leaf_ans_trie_node);
|
||||||
|
}
|
||||||
|
#endif /* THREADS_FULL_SHARING */
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
current_node = TrNode_child(SgFr_answer_trie(sg_fr));
|
current_node = TrNode_child(SgFr_answer_trie(sg_fr));
|
||||||
if (current_node) {
|
if (current_node) {
|
||||||
#ifdef YAPOR
|
#ifdef YAPOR
|
||||||
@ -1248,6 +1330,28 @@ void update_answer_trie(sg_fr_ptr sg_fr) {
|
|||||||
void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) {
|
void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
|
||||||
|
if (IS_SUBGOAL_TRIE_HASH(current_node)) {
|
||||||
|
sg_node_ptr *bucket, *last_bucket;
|
||||||
|
sg_hash_ptr hash;
|
||||||
|
hash = (sg_hash_ptr) current_node;
|
||||||
|
bucket = Hash_buckets(hash);
|
||||||
|
last_bucket = bucket + Hash_num_buckets(hash);
|
||||||
|
do {
|
||||||
|
if (*bucket) {
|
||||||
|
sg_node_ptr next_node = *bucket;
|
||||||
|
do {
|
||||||
|
current_node = next_node;
|
||||||
|
next_node = TrNode_next(current_node);
|
||||||
|
free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
|
||||||
|
} while (next_node);
|
||||||
|
}
|
||||||
|
} while (++bucket != last_bucket);
|
||||||
|
IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
|
FREE_BUCKETS(Hash_buckets(hash));
|
||||||
|
FREE_SUBGOAL_TRIE_HASH(hash);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (! IS_SUBGOAL_LEAF_NODE(current_node)) {
|
if (! IS_SUBGOAL_LEAF_NODE(current_node)) {
|
||||||
int child_mode;
|
int child_mode;
|
||||||
if (mode == TRAVERSE_MODE_NORMAL) {
|
if (mode == TRAVERSE_MODE_NORMAL) {
|
||||||
@ -1274,43 +1378,53 @@ void free_subgoal_trie(sg_node_ptr current_node, int mode, int position) {
|
|||||||
child_mode = TRAVERSE_MODE_NORMAL;
|
child_mode = TRAVERSE_MODE_NORMAL;
|
||||||
free_subgoal_trie(TrNode_child(current_node), child_mode, TRAVERSE_POSITION_FIRST);
|
free_subgoal_trie(TrNode_child(current_node), child_mode, TRAVERSE_POSITION_FIRST);
|
||||||
} else {
|
} else {
|
||||||
sg_fr_ptr sg_fr;
|
sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(current_node PASS_REGS);
|
||||||
ans_node_ptr ans_node;
|
if (sg_fr) {
|
||||||
sg_fr = UNTAG_SUBGOAL_LEAF_NODE(TrNode_sg_fr(current_node));
|
ans_node_ptr ans_node;
|
||||||
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
free_answer_hash_chain(SgFr_hash_chain(sg_fr));
|
||||||
ans_node = SgFr_answer_trie(sg_fr);
|
ans_node = SgFr_answer_trie(sg_fr);
|
||||||
if (TrNode_child(ans_node))
|
if (TrNode_child(ans_node))
|
||||||
free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
free_answer_trie(TrNode_child(ans_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
||||||
FREE_ANSWER_TRIE_NODE(ans_node);
|
IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
#if defined(MODE_DIRECTED_TABLING) && defined(YAPOR)
|
FREE_ANSWER_TRIE_NODE(ans_node);
|
||||||
if (SgFr_invalid_chain(sg_fr)) {
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
ans_node_ptr next_node, invalid_node = SgFr_invalid_chain(sg_fr);
|
FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr));
|
||||||
SgFr_invalid_chain(sg_fr) = NULL;
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
/* free invalid answer nodes */
|
}
|
||||||
while (invalid_node) {
|
#if defined(MODE_DIRECTED_TABLING) && defined(YAPOR)
|
||||||
next_node = TrNode_next(invalid_node);
|
if (SgFr_invalid_chain(sg_fr)) {
|
||||||
FREE_ANSWER_TRIE_NODE(invalid_node);
|
ans_node_ptr next_node, invalid_node = SgFr_invalid_chain(sg_fr);
|
||||||
invalid_node = next_node;
|
SgFr_invalid_chain(sg_fr) = NULL;
|
||||||
|
/* free invalid answer nodes */
|
||||||
|
while (invalid_node) {
|
||||||
|
next_node = TrNode_next(invalid_node);
|
||||||
|
FREE_ANSWER_TRIE_NODE(invalid_node);
|
||||||
|
invalid_node = next_node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif /* MODE_DIRECTED_TABLING && YAPOR */
|
#endif /* MODE_DIRECTED_TABLING && YAPOR */
|
||||||
#ifdef LIMIT_TABLING
|
#ifdef LIMIT_TABLING
|
||||||
remove_from_global_sg_fr_list(sg_fr);
|
remove_from_global_sg_fr_list(sg_fr);
|
||||||
#endif /* LIMIT_TABLING */
|
#endif /* LIMIT_TABLING */
|
||||||
FREE_SUBGOAL_FRAME(sg_fr);
|
FREE_SUBGOAL_FRAME(sg_fr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (position == TRAVERSE_POSITION_FIRST) {
|
if (position == TRAVERSE_POSITION_FIRST) {
|
||||||
sg_node_ptr next_node = TrNode_next(current_node);
|
sg_node_ptr next_node = TrNode_next(current_node);
|
||||||
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
FREE_SUBGOAL_TRIE_NODE(current_node);
|
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
||||||
|
FREE_SUBGOAL_TRIE_NODE(current_node);
|
||||||
|
}
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
current_node = next_node;
|
current_node = next_node;
|
||||||
next_node = TrNode_next(current_node);
|
next_node = TrNode_next(current_node);
|
||||||
free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
|
free_subgoal_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
FREE_SUBGOAL_TRIE_NODE(current_node);
|
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
||||||
|
FREE_SUBGOAL_TRIE_NODE(current_node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1351,46 +1465,20 @@ void free_answer_trie(ans_node_ptr current_node, int mode, int position) {
|
|||||||
}
|
}
|
||||||
if (position == TRAVERSE_POSITION_FIRST) {
|
if (position == TRAVERSE_POSITION_FIRST) {
|
||||||
ans_node_ptr next_node = TrNode_next(current_node);
|
ans_node_ptr next_node = TrNode_next(current_node);
|
||||||
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
FREE_ANSWER_TRIE_NODE(current_node);
|
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
||||||
|
FREE_ANSWER_TRIE_NODE(current_node);
|
||||||
|
}
|
||||||
while (next_node) {
|
while (next_node) {
|
||||||
current_node = next_node;
|
current_node = next_node;
|
||||||
next_node = TrNode_next(current_node);
|
next_node = TrNode_next(current_node);
|
||||||
free_answer_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
|
free_answer_trie(current_node, mode, TRAVERSE_POSITION_NEXT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
FREE_ANSWER_TRIE_NODE(current_node);
|
CHECK_DECREMENT_GLOBAL_TRIE_REFERENCE(TrNode_entry(current_node), mode);
|
||||||
}
|
FREE_ANSWER_TRIE_NODE(current_node);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void free_subgoal_hash_chain(sg_hash_ptr hash) {
|
|
||||||
CACHE_REGS
|
|
||||||
|
|
||||||
while (hash) {
|
|
||||||
sg_node_ptr chain_node, *bucket, *last_bucket;
|
|
||||||
sg_hash_ptr next_hash;
|
|
||||||
|
|
||||||
bucket = Hash_buckets(hash);
|
|
||||||
last_bucket = bucket + Hash_num_buckets(hash);
|
|
||||||
while (! *bucket)
|
|
||||||
bucket++;
|
|
||||||
chain_node = *bucket;
|
|
||||||
TrNode_child(TrNode_parent(chain_node)) = chain_node;
|
|
||||||
while (++bucket != last_bucket) {
|
|
||||||
if (*bucket) {
|
|
||||||
while (TrNode_next(chain_node))
|
|
||||||
chain_node = TrNode_next(chain_node);
|
|
||||||
TrNode_next(chain_node) = *bucket;
|
|
||||||
chain_node = *bucket;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
next_hash = Hash_next(hash);
|
|
||||||
FREE_HASH_BUCKETS(Hash_buckets(hash));
|
|
||||||
FREE_SUBGOAL_TRIE_HASH(hash);
|
|
||||||
hash = next_hash;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1408,7 +1496,7 @@ void free_answer_hash_chain(ans_hash_ptr hash) {
|
|||||||
while (! *bucket)
|
while (! *bucket)
|
||||||
bucket++;
|
bucket++;
|
||||||
chain_node = *bucket;
|
chain_node = *bucket;
|
||||||
TrNode_child(UNTAG_ANSWER_LEAF_NODE(TrNode_parent(chain_node))) = chain_node;
|
TrNode_child(UNTAG_ANSWER_NODE(TrNode_parent(chain_node))) = chain_node;
|
||||||
while (++bucket != last_bucket) {
|
while (++bucket != last_bucket) {
|
||||||
if (*bucket) {
|
if (*bucket) {
|
||||||
while (TrNode_next(chain_node))
|
while (TrNode_next(chain_node))
|
||||||
@ -1418,7 +1506,7 @@ void free_answer_hash_chain(ans_hash_ptr hash) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
next_hash = Hash_next(hash);
|
next_hash = Hash_next(hash);
|
||||||
FREE_HASH_BUCKETS(Hash_buckets(hash));
|
FREE_BUCKETS(Hash_buckets(hash));
|
||||||
FREE_ANSWER_TRIE_HASH(hash);
|
FREE_ANSWER_TRIE_HASH(hash);
|
||||||
hash = next_hash;
|
hash = next_hash;
|
||||||
}
|
}
|
||||||
@ -1426,28 +1514,68 @@ void free_answer_hash_chain(ans_hash_ptr hash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************************************************************
|
||||||
|
** - main thread (worker_id 0) abolishes its local and all shared data structures. **
|
||||||
|
** - all other threads only abolish their local data structures. **
|
||||||
|
** - for the main thread, we assume that all other threads have the table clean (i.e., without local data structures) **
|
||||||
|
** and that they will be not using the table during the abolish operation. **
|
||||||
|
***********************************************************************************************************************/
|
||||||
|
void abolish_table(tab_ent_ptr tab_ent) {
|
||||||
|
CACHE_REGS
|
||||||
|
sg_node_ptr sg_node;
|
||||||
|
|
||||||
|
sg_node = get_subgoal_trie_for_abolish(tab_ent PASS_REGS);
|
||||||
|
if (sg_node) {
|
||||||
|
if (TrNode_child(sg_node)) {
|
||||||
|
if (TabEnt_arity(tab_ent)) {
|
||||||
|
free_subgoal_trie(TrNode_child(sg_node), TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
||||||
|
} else {
|
||||||
|
sg_fr_ptr sg_fr = get_subgoal_frame_for_abolish(sg_node PASS_REGS);
|
||||||
|
if (sg_fr) {
|
||||||
|
IF_ABOLISH_ANSWER_TRIE_SHARED_DATA_STRUCTURES {
|
||||||
|
FREE_ANSWER_TRIE_NODE(SgFr_answer_trie(sg_fr));
|
||||||
|
#if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
|
||||||
|
FREE_SUBGOAL_ENTRY(SgFr_sg_ent(sg_fr));
|
||||||
|
#endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
|
||||||
|
}
|
||||||
|
#ifdef LIMIT_TABLING
|
||||||
|
remove_from_global_sg_fr_list(sg_fr);
|
||||||
|
#endif /* LIMIT_TABLING */
|
||||||
|
FREE_SUBGOAL_FRAME(sg_fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IF_ABOLISH_SUBGOAL_TRIE_SHARED_DATA_STRUCTURES
|
||||||
|
TrNode_child(sg_node) = NULL;
|
||||||
|
}
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
FREE_SUBGOAL_TRIE_NODE(sg_node);
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) {
|
void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) {
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
sg_node_ptr sg_node;
|
sg_node_ptr sg_node;
|
||||||
|
|
||||||
TrStat_out = out;
|
TrStat_out = out;
|
||||||
TrStat_show = show_mode;
|
TrStat_show = show_mode;
|
||||||
if (show_mode == SHOW_MODE_STATISTICS) {
|
TrStat_subgoals = 0;
|
||||||
TrStat_subgoals = 0;
|
TrStat_sg_incomplete = 0;
|
||||||
TrStat_sg_incomplete = 0;
|
TrStat_sg_nodes = 1;
|
||||||
TrStat_sg_nodes = 1;
|
TrStat_answers = 0;
|
||||||
TrStat_answers = 0;
|
TrStat_answers_true = 0;
|
||||||
TrStat_answers_true = 0;
|
TrStat_answers_no = 0;
|
||||||
TrStat_answers_no = 0;
|
|
||||||
#ifdef TABLING_INNER_CUTS
|
#ifdef TABLING_INNER_CUTS
|
||||||
TrStat_answers_pruned = 0;
|
TrStat_answers_pruned = 0;
|
||||||
#endif /* TABLING_INNER_CUTS */
|
#endif /* TABLING_INNER_CUTS */
|
||||||
TrStat_ans_nodes = 0;
|
TrStat_ans_nodes = 0;
|
||||||
TrStat_gt_refs = 0;
|
TrStat_gt_refs = 0;
|
||||||
|
if (show_mode == SHOW_MODE_STATISTICS)
|
||||||
Sfprintf(TrStat_out, "Table statistics for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
Sfprintf(TrStat_out, "Table statistics for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
||||||
} else { /* SHOW_MODE_STRUCTURE */
|
else /* SHOW_MODE_STRUCTURE */
|
||||||
Sfprintf(TrStat_out, "Table structure for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
Sfprintf(TrStat_out, "Table structure for predicate '%s", AtomName(TabEnt_atom(tab_ent)));
|
||||||
}
|
|
||||||
#ifdef MODE_DIRECTED_TABLING
|
#ifdef MODE_DIRECTED_TABLING
|
||||||
if (TabEnt_mode_directed(tab_ent)) {
|
if (TabEnt_mode_directed(tab_ent)) {
|
||||||
int i, *mode_directed = TabEnt_mode_directed(tab_ent);
|
int i, *mode_directed = TabEnt_mode_directed(tab_ent);
|
||||||
@ -1475,36 +1603,41 @@ void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) {
|
|||||||
} else
|
} else
|
||||||
#endif /* MODE_DIRECTED_TABLING */
|
#endif /* MODE_DIRECTED_TABLING */
|
||||||
Sfprintf(TrStat_out, "/%d'\n", TabEnt_arity(tab_ent));
|
Sfprintf(TrStat_out, "/%d'\n", TabEnt_arity(tab_ent));
|
||||||
sg_node = TrNode_child(TabEnt_subgoal_trie(tab_ent));
|
sg_node = get_subgoal_trie(tab_ent);
|
||||||
if (sg_node) {
|
if (sg_node) {
|
||||||
if (TabEnt_arity(tab_ent)) {
|
if (TrNode_child(sg_node)) {
|
||||||
char *str = (char *) malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE);
|
if (TabEnt_arity(tab_ent)) {
|
||||||
int str_index = sprintf(str, " ?- %s(", AtomName(TabEnt_atom(tab_ent)));
|
char *str = (char *) malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE);
|
||||||
int *arity = (int *) malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
|
int *arity = (int *) malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
|
||||||
arity[0] = 1;
|
arity[0] = 1;
|
||||||
arity[1] = TabEnt_arity(tab_ent);
|
arity[1] = TabEnt_arity(tab_ent);
|
||||||
traverse_subgoal_trie(sg_node, str, str_index, arity, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
int str_index = sprintf(str, " ?- %s(", AtomName(TabEnt_atom(tab_ent)));
|
||||||
free(str);
|
traverse_subgoal_trie(TrNode_child(sg_node), str, str_index, arity, TRAVERSE_MODE_NORMAL, TRAVERSE_POSITION_FIRST);
|
||||||
free(arity);
|
free(str);
|
||||||
} else {
|
free(arity);
|
||||||
sg_fr_ptr sg_fr = UNTAG_SUBGOAL_LEAF_NODE(sg_node);
|
} else {
|
||||||
TrStat_subgoals++;
|
sg_fr_ptr sg_fr = get_subgoal_frame(sg_node);
|
||||||
SHOW_TABLE_STRUCTURE(" ?- %s.\n", AtomName(TabEnt_atom(tab_ent)));
|
if (sg_fr) {
|
||||||
TrStat_ans_nodes++;
|
TrStat_subgoals++;
|
||||||
if (SgFr_first_answer(sg_fr) == NULL) {
|
SHOW_TABLE_STRUCTURE(" ?- %s.\n", AtomName(TabEnt_atom(tab_ent)));
|
||||||
if (SgFr_state(sg_fr) < complete) {
|
TrStat_ans_nodes++;
|
||||||
TrStat_sg_incomplete++;
|
if (SgFr_first_answer(sg_fr) == NULL) {
|
||||||
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
if (SgFr_state(sg_fr) < complete) {
|
||||||
} else {
|
TrStat_sg_incomplete++;
|
||||||
TrStat_answers_no++;
|
SHOW_TABLE_STRUCTURE(" ---> INCOMPLETE\n");
|
||||||
SHOW_TABLE_STRUCTURE(" NO\n");
|
} else {
|
||||||
|
TrStat_answers_no++;
|
||||||
|
SHOW_TABLE_STRUCTURE(" NO\n");
|
||||||
|
}
|
||||||
|
} else { /* SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr) */
|
||||||
|
TrStat_answers_true++;
|
||||||
|
SHOW_TABLE_STRUCTURE(" TRUE\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { /* SgFr_first_answer(sg_fr) == SgFr_answer_trie(sg_fr) */
|
|
||||||
TrStat_answers_true++;
|
|
||||||
SHOW_TABLE_STRUCTURE(" TRUE\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
if (TrStat_subgoals == 0)
|
||||||
SHOW_TABLE_STRUCTURE(" EMPTY\n");
|
SHOW_TABLE_STRUCTURE(" EMPTY\n");
|
||||||
if (show_mode == SHOW_MODE_STATISTICS) {
|
if (show_mode == SHOW_MODE_STATISTICS) {
|
||||||
Sfprintf(TrStat_out, " Subgoal trie structure\n");
|
Sfprintf(TrStat_out, " Subgoal trie structure\n");
|
||||||
@ -1526,16 +1659,17 @@ void show_table(tab_ent_ptr tab_ent, int show_mode, IOSTREAM *out) {
|
|||||||
|
|
||||||
|
|
||||||
void show_global_trie(int show_mode, IOSTREAM *out) {
|
void show_global_trie(int show_mode, IOSTREAM *out) {
|
||||||
|
CACHE_REGS
|
||||||
|
|
||||||
TrStat_out = out;
|
TrStat_out = out;
|
||||||
TrStat_show = show_mode;
|
TrStat_show = show_mode;
|
||||||
if (show_mode == SHOW_MODE_STATISTICS) {
|
TrStat_gt_terms = 0;
|
||||||
TrStat_gt_terms = 0;
|
TrStat_gt_nodes = 1;
|
||||||
TrStat_gt_nodes = 1;
|
TrStat_gt_refs = 0;
|
||||||
TrStat_gt_refs = 0;
|
if (show_mode == SHOW_MODE_STATISTICS)
|
||||||
Sfprintf(TrStat_out, "Global trie statistics\n");
|
Sfprintf(TrStat_out, "Global trie statistics\n");
|
||||||
} else { /* SHOW_MODE_STRUCTURE */
|
else /* SHOW_MODE_STRUCTURE */
|
||||||
Sfprintf(TrStat_out, "Global trie structure\n");
|
Sfprintf(TrStat_out, "Global trie structure\n");
|
||||||
}
|
|
||||||
if (TrNode_child(GLOBAL_root_gt)) {
|
if (TrNode_child(GLOBAL_root_gt)) {
|
||||||
char *str = (char *) malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE);
|
char *str = (char *) malloc(sizeof(char) * SHOW_TABLE_STR_ARRAY_SIZE);
|
||||||
int *arity = (int *) malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
|
int *arity = (int *) malloc(sizeof(int) * SHOW_TABLE_ARITY_ARRAY_SIZE);
|
||||||
@ -1552,6 +1686,4 @@ void show_global_trie(int show_mode, IOSTREAM *out) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
@ -64,7 +64,9 @@ static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent
|
|||||||
#else
|
#else
|
||||||
static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
|
static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
|
||||||
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
CACHE_REGS
|
CACHE_REGS
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
sg_node_ptr child_node;
|
sg_node_ptr child_node;
|
||||||
|
|
||||||
LOCK_SUBGOAL_NODE(parent_node);
|
LOCK_SUBGOAL_NODE(parent_node);
|
||||||
@ -133,7 +135,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
|
|||||||
sg_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
sg_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
int num_buckets;
|
int num_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -150,7 +152,7 @@ static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, s
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_SUBGOAL_NODE(parent_node);
|
UNLOCK_SUBGOAL_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -162,6 +164,9 @@ static inline sg_node_ptr subgoal_trie_check_insert_gt_entry(tab_ent_ptr tab_ent
|
|||||||
#else
|
#else
|
||||||
static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
|
static inline sg_node_ptr subgoal_trie_check_insert_entry(tab_ent_ptr tab_ent, sg_node_ptr parent_node, Term t) {
|
||||||
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
||||||
|
#ifdef THREADS_NO_SHARING
|
||||||
|
CACHE_REGS
|
||||||
|
#endif /* THREADS_NO_SHARING */
|
||||||
sg_node_ptr child_node;
|
sg_node_ptr child_node;
|
||||||
sg_hash_ptr hash;
|
sg_hash_ptr hash;
|
||||||
|
|
||||||
@ -325,7 +330,7 @@ subgoal_trie_hash:
|
|||||||
/* expand current hash */
|
/* expand current hash */
|
||||||
sg_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
sg_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -342,7 +347,7 @@ subgoal_trie_hash:
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_SUBGOAL_NODE(parent_node);
|
UNLOCK_SUBGOAL_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -434,7 +439,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
|
|||||||
ans_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
ans_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
int num_buckets;
|
int num_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -451,7 +456,7 @@ static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_n
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_ANSWER_NODE(parent_node);
|
UNLOCK_ANSWER_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -463,6 +468,7 @@ static inline ans_node_ptr answer_trie_check_insert_gt_entry(sg_fr_ptr sg_fr, an
|
|||||||
#else
|
#else
|
||||||
static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) {
|
static inline ans_node_ptr answer_trie_check_insert_entry(sg_fr_ptr sg_fr, ans_node_ptr parent_node, Term t, int instr) {
|
||||||
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
#endif /* MODE_GLOBAL_TRIE_ENTRY */
|
||||||
|
CACHE_REGS
|
||||||
ans_node_ptr child_node;
|
ans_node_ptr child_node;
|
||||||
ans_hash_ptr hash;
|
ans_hash_ptr hash;
|
||||||
|
|
||||||
@ -627,7 +633,7 @@ answer_trie_hash:
|
|||||||
/* expand current hash */
|
/* expand current hash */
|
||||||
ans_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
ans_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -644,7 +650,7 @@ answer_trie_hash:
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_ANSWER_NODE(parent_node);
|
UNLOCK_ANSWER_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -734,7 +740,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
|
|||||||
gt_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
gt_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
int num_buckets;
|
int num_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -751,7 +757,7 @@ static inline gt_node_ptr global_trie_check_insert_entry(gt_node_ptr parent_node
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_GLOBAL_NODE(parent_node);
|
UNLOCK_GLOBAL_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -927,7 +933,7 @@ global_trie_hash:
|
|||||||
/* expand current hash */
|
/* expand current hash */
|
||||||
gt_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
gt_node_ptr chain_node, next_node, *old_bucket, *old_hash_buckets, *new_hash_buckets;
|
||||||
num_buckets = Hash_num_buckets(hash) * 2;
|
num_buckets = Hash_num_buckets(hash) * 2;
|
||||||
ALLOC_HASH_BUCKETS(new_hash_buckets, num_buckets);
|
ALLOC_BUCKETS(new_hash_buckets, num_buckets);
|
||||||
old_hash_buckets = Hash_buckets(hash);
|
old_hash_buckets = Hash_buckets(hash);
|
||||||
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
old_bucket = old_hash_buckets + Hash_num_buckets(hash);
|
||||||
do {
|
do {
|
||||||
@ -944,7 +950,7 @@ global_trie_hash:
|
|||||||
} while (old_bucket != old_hash_buckets);
|
} while (old_bucket != old_hash_buckets);
|
||||||
Hash_buckets(hash) = new_hash_buckets;
|
Hash_buckets(hash) = new_hash_buckets;
|
||||||
Hash_num_buckets(hash) = num_buckets;
|
Hash_num_buckets(hash) = num_buckets;
|
||||||
FREE_HASH_BUCKETS(old_hash_buckets);
|
FREE_BUCKETS(old_hash_buckets);
|
||||||
}
|
}
|
||||||
UNLOCK_GLOBAL_NODE(parent_node);
|
UNLOCK_GLOBAL_NODE(parent_node);
|
||||||
return child_node;
|
return child_node;
|
||||||
@ -1498,7 +1504,7 @@ static inline ans_node_ptr answer_search_min_max(sg_fr_ptr sg_fr, ans_node_ptr c
|
|||||||
FREE_ANSWER_TRIE_NODE(NODE)
|
FREE_ANSWER_TRIE_NODE(NODE)
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \
|
#define INVALIDATE_ANSWER_TRIE_LEAF_NODE(NODE, SG_FR) \
|
||||||
TAG_AS_INVALID_LEAF_NODE(NODE); \
|
TAG_AS_ANSWER_INVALID_NODE(NODE); \
|
||||||
TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \
|
TrNode_next(NODE) = SgFr_invalid_chain(SG_FR); \
|
||||||
SgFr_invalid_chain(SG_FR) = NODE
|
SgFr_invalid_chain(SG_FR) = NODE
|
||||||
|
|
||||||
@ -1534,7 +1540,7 @@ static void invalidate_answer_trie(ans_node_ptr current_node, sg_fr_ptr sg_fr, i
|
|||||||
Hash_next(Hash_previous(hash)) = Hash_next(hash);
|
Hash_next(Hash_previous(hash)) = Hash_next(hash);
|
||||||
else
|
else
|
||||||
SgFr_hash_chain(sg_fr) = Hash_next(hash);
|
SgFr_hash_chain(sg_fr) = Hash_next(hash);
|
||||||
FREE_HASH_BUCKETS(Hash_buckets(hash));
|
FREE_BUCKETS(Hash_buckets(hash));
|
||||||
FREE_ANSWER_TRIE_HASH(hash);
|
FREE_ANSWER_TRIE_HASH(hash);
|
||||||
} else {
|
} else {
|
||||||
if (position == TRAVERSE_POSITION_FIRST) {
|
if (position == TRAVERSE_POSITION_FIRST) {
|
||||||
@ -1619,7 +1625,7 @@ static inline CELL *load_answer_loop(ans_node_ptr current_node) {
|
|||||||
#ifdef MODE_GLOBAL_TRIE_LOOP
|
#ifdef MODE_GLOBAL_TRIE_LOOP
|
||||||
current_node = TrNode_parent(current_node);
|
current_node = TrNode_parent(current_node);
|
||||||
#else
|
#else
|
||||||
current_node = UNTAG_ANSWER_LEAF_NODE(TrNode_parent(current_node));
|
current_node = UNTAG_ANSWER_NODE(TrNode_parent(current_node));
|
||||||
#endif /* MODE_GLOBAL_TRIE_LOOP */
|
#endif /* MODE_GLOBAL_TRIE_LOOP */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -189,10 +189,13 @@ yamop getwork_seq_code[1] GETWORK_SEQ InitOtaplInst(GETWORK_SEQ,_getwork_seq,P
|
|||||||
yamop getwork_first_time[1] GETWORK_FIRST_TIME MkInstE _getwork_first_time
|
yamop getwork_first_time[1] GETWORK_FIRST_TIME MkInstE _getwork_first_time
|
||||||
#endif /* YAPOR */
|
#endif /* YAPOR */
|
||||||
#ifdef TABLING
|
#ifdef TABLING
|
||||||
yamop table_load_answer_code[1] LOAD_ANSWER InitOtaplInst(LOAD_ANSWER,_table_load_answer,PredFail) RestoreOtaplInst(LOAD_ANSWER,_table_load_answer,PredFail)
|
yamop table_load_answer_code[1] LOAD_ANSWER InitOtaplInst(LOAD_ANSWER,_table_load_answer,PredFail) RestoreOtaplInst(LOAD_ANSWER,_table_load_answer,PredFail)
|
||||||
yamop table_try_answer_code[1] TRY_ANSWER InitOtaplInst(TRY_ANSWER,_table_try_answer,PredFail) RestoreOtaplInst(TRY_ANSWER,_table_try_answer,PredFail)
|
yamop table_try_answer_code[1] TRY_ANSWER InitOtaplInst(TRY_ANSWER,_table_try_answer,PredFail) RestoreOtaplInst(TRY_ANSWER,_table_try_answer,PredFail)
|
||||||
yamop table_answer_resolution_code[1] ANSWER_RESOLUTION InitOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail) RestoreOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail)
|
yamop table_answer_resolution_code[1] ANSWER_RESOLUTION InitOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail) RestoreOtaplInst(ANSWER_RESOLUTION,_table_answer_resolution,PredFail)
|
||||||
yamop table_completion_code[1] COMPLETION InitOtaplInst(COMPLETION,_table_completion,PredFail) RestoreOtaplInst(COMPLETION,_table_completion,PredFail)
|
yamop table_completion_code[1] COMPLETION InitOtaplInst(COMPLETION,_table_completion,PredFail) RestoreOtaplInst(COMPLETION,_table_completion,PredFail)
|
||||||
|
#ifdef THREADS_CONSUMER_SHARING
|
||||||
|
yamop table_answer_resolution_completion_code[1] ANSWER_RESOLUTION_COMPLETION InitOtaplInst(ANSWER_RESOLUTION_COMPLETION,_table_answer_resolution_completion,PredFail) RestoreOtaplInst(ANSWER_RESOLUTION_COMPLETION,_table_answer_resolution_completion,PredFail)
|
||||||
|
#endif /* THREADS_CONSUMER_SHARING */
|
||||||
#endif /* TABLING */
|
#endif /* TABLING */
|
||||||
|
|
||||||
/* */
|
/* */
|
||||||
|
@ -164,6 +164,7 @@ end_special(Name, W) :-
|
|||||||
end_special(_, _).
|
end_special(_, _).
|
||||||
|
|
||||||
special_op("clause_with_cut","TABLING_INNER_CUTS").
|
special_op("clause_with_cut","TABLING_INNER_CUTS").
|
||||||
|
special_op("table_answer_resolution_completion","THREADS_CONSUMER_SHARING").
|
||||||
special_op("cut_c","CUT_C").
|
special_op("cut_c","CUT_C").
|
||||||
special_op("cut_userc","CUT_C").
|
special_op("cut_userc","CUT_C").
|
||||||
special_op("run_eam","BEAM").
|
special_op("run_eam","BEAM").
|
||||||
|
Reference in New Issue
Block a user