static void cndfs_handle_nonseed_accepting (wctx_t *ctx) { alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; size_t nonred, accs; nonred = accs = dfs_stack_size(cloc->out_stack); if (nonred) { loc->counters.waits++; cloc->counters.rec += accs; RTstartTimer (cloc->timer); while ( nonred && !run_is_stopped(ctx->run) ) { nonred = 0; for (size_t i = 0; i < accs; i++) { raw_data_t state_data = dfs_stack_peek (cloc->out_stack, i); state_info_deserialize (ctx->state, state_data); if (state_store_get_colors (ctx->state->ref) != CRED) nonred++; } } RTstopTimer (cloc->timer); } for (size_t i = 0; i < accs; i++) dfs_stack_pop (cloc->out_stack); while ( dfs_stack_size(cloc->in_stack) ) { raw_data_t state_data = dfs_stack_pop (cloc->in_stack); state_info_deserialize (ctx->state, state_data); if (update_color(ctx, ctx->state->ref, CRED, 1)) loc->red_work.explored++; } }
void ta_dfs (wctx_t *ctx) { alg_shared_t *shared = ctx->run->shared; alg_global_t *sm = ctx->global; while (lb_balance(shared->lb, ctx->id, dfs_stack_size(sm->stack), split_dfs)) { raw_data_t state_data = dfs_stack_top (sm->stack); if (NULL != state_data) { if (grab_waiting(ctx, state_data)) { dfs_stack_enter (sm->stack); increase_level (ctx->counters); ta_explore_state (ctx); } else { dfs_stack_pop (sm->stack); } } else { if (0 == dfs_stack_size (sm->stack)) continue; dfs_stack_leave (sm->stack); ctx->counters->level_cur--; dfs_stack_pop (sm->stack); } } }
static void endfs_handle_dangerous (wctx_t *ctx) { alg_local_t *loc = ctx->local; cndfs_alg_local_t *cloc = (cndfs_alg_local_t *) ctx->local; while ( dfs_stack_size(cloc->in_stack) ) { raw_data_t state_data = dfs_stack_pop (cloc->in_stack); state_info_deserialize (ctx->state, state_data); if ( !state_store_has_color(ctx->state->ref, GDANGEROUS, loc->rec_bits) && ctx->state->ref != loc->seed->ref ) if (update_color(ctx, ctx->state->ref, CRED, 1)) loc->red_work.explored++; } if (update_color(ctx, ctx->state->ref, CRED, 1)) { loc->red_work.explored++; loc->counters.accepting++; } if ( state_store_has_color(loc->seed->ref, GDANGEROUS, loc->rec_bits) ) { rec_ndfs_call (ctx, loc->seed->ref); } }
void tarjan_run (run_t *run, wctx_t *ctx) { alg_local_t *loc = ctx->local; raw_data_t *addr; raw_data_t state_data; bool on_stack; hash32_t hash; #ifdef HAVE_PROFILER Warning (info, "Using the profiler"); ProfilerStart ("tarjan.perf"); #endif #ifdef SEARCH_COMPLETE_GRAPH int init_state = dlopen_get_worker_initial_state (ctx->id, W); int inits = 0; // loop until every state of the graph has been visited while ( 1 ) { inits ++; // use loc->target as a dummy for the initial state loc->target->ref = init_state; #endif tarjan_init (ctx); // continue until we are done exploring the graph while ( !run_is_stopped (run) ) { state_data = dfs_stack_top (loc->search_stack); if (state_data != NULL) { // there is a state on the current stackframe ==> explore it state_info_deserialize (ctx->state, state_data); // pop the state and continue if it is part of a completed SCC if (state_store_has_color (ctx->state->ref, SCC_STATE, 0)) { dfs_stack_pop (loc->search_stack); continue; } hash = ref_hash (ctx->state->ref); on_stack = fset_find (loc->visited_states, &hash, &ctx->state->ref, (void **) &addr, true); if (!on_stack) { // unseen state ==> initialize and explore HREassert (loc->cnt.tarjan_counter != UINT32_MAX); loc->cnt.tarjan_counter ++; loc->state_tarjan.index = loc->cnt.tarjan_counter; loc->state_tarjan.lowlink = loc->cnt.tarjan_counter; // point visited_states data to stack *addr = state_data; explore_state (ctx); state_info_serialize (ctx->state, state_data); } else { // previously visited state ==> update parent // NB: state is on tarjan_stack state_info_deserialize (ctx->state, *addr); update_parent (ctx, loc->state_tarjan.lowlink); dfs_stack_pop (loc->search_stack); } } else { // there is no state on the current stackframe ==> backtrack // we are done if we backtrack from the initial state if (0 == dfs_stack_nframes (loc->search_stack)) break; // leave the stackframe dfs_stack_leave (loc->search_stack); ctx->counters->level_cur--; // retrieve the parent state from search_stack (to be removed) state_data = dfs_stack_top (loc->search_stack); state_info_deserialize (ctx->state, state_data); Debug ("Backtracking %zu (%d, %d)", ctx->state->ref, loc->state_tarjan.index, loc->state_tarjan.lowlink); if (loc->state_tarjan.index == loc->state_tarjan.lowlink) { // index == lowlink ==> root of the SCC ==> report the SCC pop_scc (ctx, ctx->state->ref, loc->state_tarjan.lowlink); } else { // lowlink < index ==> LIVE SCC ==> move to tarjan_stack move_tarjan (ctx, ctx->state, state_data); update_parent (ctx, loc->state_tarjan.lowlink); } dfs_stack_pop (loc->search_stack); } } #ifdef SEARCH_COMPLETE_GRAPH init_state = dlopen_get_new_initial_state (init_state); if (init_state == -1) { Warning(info, "Number of inits : %d", inits); break; } } #endif #ifdef HAVE_PROFILER Warning(info, "Done profiling"); ProfilerStop(); #endif if (!run_is_stopped(run) && dfs_stack_size(loc->tarjan_stack) != 0) Warning (info, "Tarjan stack not empty: %zu (stack %zu)", dfs_stack_size(loc->tarjan_stack), dfs_stack_size(loc->search_stack)); if (!run_is_stopped(run) && fset_count(loc->visited_states) != 0) Warning (info, "Stack-set not empty: %zu", fset_count(loc->visited_states)); }