Exemplo n.º 1
0
/**
 * move a stack state to the completed SCC set
 */
static void
move_scc (wctx_t *ctx, ref_t state)
{
    alg_local_t        *loc     = ctx->local;
    hash32_t            hash;
    int                 success;

    Debug ("Marking %zu as SCC", state);

    // remove reference to stack state
    hash    = ref_hash (state);
    success = fset_delete (loc->visited_states, &hash, &state);
    HREassert (success, "Could not remove SCC state from set");

    // set SCC globally
    state_store_try_color (state, SCC_STATE, 0);
}
Exemplo n.º 2
0
static void
ta_handle (void *arg, state_info_t *successor, transition_info_t *ti, int seen)
{
    wctx_t             *ctx = (wctx_t*) arg;
    ta_alg_shared_t    *shared = (ta_alg_shared_t *) ctx->run->shared;
    alg_local_t        *loc = ctx->local;
    ta_alg_local_t     *ta_loc = (ta_alg_local_t *) ctx->local;
    ta_alg_global_t    *sm = (ta_alg_global_t *) ctx->global;
    ta_loc->done = 0;
    ta_loc->subsumes = 0; // if a successor subsumes one in the set, it cannot be subsumed itself (see invariant paper)
    ta_loc->work = 0;
    ta_loc->added_at = LM_NULL_LOC;
    ta_loc->last = LM_NULL_LOC;
    ta_loc->successor = successor;
    lm_lock (shared->lmap, successor->ref);
    lm_loc_t last = lm_iterate (shared->lmap, successor->ref, ta_covered, ctx);
    if (!ta_loc->done) {
        last = (LM_NULL_LOC == ta_loc->last ? last : ta_loc->last);
        sm->lloc = lm_insert_from (shared->lmap, successor->ref,
                                   successor->lattice, TA_WAITING, &last);
        lm_unlock (shared->lmap, successor->ref);
        ta_loc->counters.inserts++;
        if (0) { // quite costly: flops
            if (ta_loc->work > 0)
                statistics_unrecord (&ta_loc->counters.lattice_ratio, ta_loc->work);
            statistics_record (&ta_loc->counters.lattice_ratio, ta_loc->work+1);
        }
        ta_queue_state (ctx, successor);
        ta_loc->counters.updates += LM_NULL_LOC != ta_loc->last;
        loc->counters.level_size++;
    } else {
        lm_unlock (shared->lmap, successor->ref);
    }
    action_detect (ctx, ti, successor);
    if (EXPECT_FALSE(loc->lts != NULL)) {
        int             src = ctx->counters->explored;
        int            *tgt = state_info_state (successor);
        int             tgt_owner = ref_hash (successor->ref) % W;
        lts_write_edge (loc->lts, ctx->id, &src, tgt_owner, tgt, ti->labels);
    }
    ctx->counters->trans++;
    (void) seen;
}
Exemplo n.º 3
0
static void
tarjan_handle (void *arg, state_info_t *successor, transition_info_t *ti,
               int seen)
{
    // parent state is ctx->state

    wctx_t             *ctx   = (wctx_t *) arg;
    alg_local_t        *loc   = ctx->local;
    raw_data_t         *addr;
    hash32_t            hash;
    int                 found;

    ctx->counters->trans++;

    // self-loop
    if (ctx->state->ref == successor->ref)
        return;

    // completed SCC
    if (state_store_has_color (successor->ref, SCC_STATE, 0))
        return;

    hash  = ref_hash (successor->ref);
    found = fset_find (loc->visited_states, &hash, &successor->ref,
                       (void **)&addr, false);

    if (found) {
        // previously visited state ==> update lowlink

        state_info_deserialize (loc->target, *addr);
        if (loc->state_tarjan.lowlink > loc->target_tarjan.lowlink)
            loc->state_tarjan.lowlink = loc->target_tarjan.lowlink;

    } else {
        // unseen state ==> push to search_stack

        raw_data_t stack_loc = dfs_stack_push (loc->search_stack, NULL);
        state_info_serialize (successor, stack_loc);
    }

    (void) ti; (void) seen;
}
Exemplo n.º 4
0
/**
 * move a search_stack state to the tarjan_stack
 */
static void
move_tarjan (wctx_t *ctx, state_info_t *state, raw_data_t state_data)
{
    alg_local_t        *loc   = ctx->local;
    raw_data_t         *addr;
    hash32_t            hash;
    int                 found;

    // add state to tarjan_stack
    raw_data_t tarjan_loc = dfs_stack_push (loc->tarjan_stack, NULL);
    state_info_serialize (state, tarjan_loc);

    // Update reference to the new stack
    hash  = ref_hash (state->ref);
    found = fset_find (loc->visited_states, &hash, &state->ref,
                       (void**) &addr, false);
    HREassert (*addr == state_data, "Wrong addr?");
    HREassert (found, "Could not find key in set");
    *addr = tarjan_loc;
}
Exemplo n.º 5
0
void
timed_run (run_t *run, wctx_t *ctx)
{
    transition_info_t       ti = GB_NO_TRANSITION;

    if ( Strat_PBFS & strategy[0] ) {
        ta_queue_state = pbfs_queue_state;
    }

    if (0 == ctx->id) { // only w1 receives load, as it is propagated later
        if ( Strat_PBFS & strategy[0] ) {
            if (ctx->local->lts != NULL) {
                state_data_t    initial = state_info_state(ctx->initial);
                int             src_owner = ref_hash(ctx->initial->ref) % W;
                lts_write_init (ctx->local->lts, src_owner, initial);
            }
        }
        ta_handle (ctx, ctx->initial, &ti, 0);
        ctx->counters->trans = 0; //reset trans count
    }

    HREbarrier (HREglobal());

    switch (get_strategy(run->alg)) {
        case Strat_TA_PBFS:
            ta_pbfs (ctx);
            break;
        case Strat_TA_SBFS:
            ta_sbfs (ctx);
            break;
        case Strat_TA_BFS:
            ta_bfs (ctx);
            break;
        case Strat_TA_DFS:
            ta_dfs (ctx);
            break;
        default: Abort ("Missing case in timed_run");
    }
}
Exemplo n.º 6
0
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));
}