Search in sources :

Example 41 with Thread

use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.

the class ExecutionModel method extractEventsFromModel.

// ========================== Internal methods  =========================
private void extractEventsFromModel() {
    // TODO(TH): We might also want to extract events such as inline assertions
    // and whether they were violated or not.
    int id = 0;
    eventList.clear();
    threadList.clear();
    threadEventsMap.clear();
    atomicBlocksMap.clear();
    // This one can probably be constant and need not be rebuilt!
    addressInitMap.clear();
    addressWritesMap.clear();
    addressReadsMap.clear();
    writeReadsMap.clear();
    fenceMap.clear();
    eventMap.clear();
    addrDepMap.clear();
    dataDepMap.clear();
    ctrlDepMap.clear();
    List<Thread> threadList = new ArrayList<>(getProgram().getThreads());
    List<Integer> threadEndIndexList = new ArrayList<>(threadList.size());
    Map<Thread, List<List<Integer>>> atomicBlockRangesMap = new HashMap<>();
    for (Thread thread : threadList) {
        initDepTracking();
        List<List<Integer>> atomicBlockRanges = atomicBlockRangesMap.computeIfAbsent(thread, key -> new ArrayList<>());
        Event e = thread.getEntry();
        int atomicBegin = -1;
        int localId = 0;
        do {
            if (!e.wasExecuted(model)) {
                e = e.getSuccessor();
                continue;
            }
            if (eventFilter.filter(e)) {
                addEvent(e, id++, localId++);
            }
            trackDependencies(e);
            // ===== Atomic blocks =====
            if (e instanceof BeginAtomic) {
                atomicBegin = id;
            } else if (e instanceof EndAtomic) {
                Preconditions.checkState(atomicBegin != -1, "EndAtomic without matching BeginAtomic in model");
                atomicBlockRanges.add(ImmutableList.of(atomicBegin, id));
                atomicBegin = -1;
            }
            if (e instanceof CondJump) {
                CondJump jump = (CondJump) e;
                if (jump.didJump(model, context)) {
                    e = jump.getLabel();
                    continue;
                }
            }
            e = e.getSuccessor();
        } while (e != null);
        // We have a BeginAtomic without EndAtomic since the program terminated within the block
        if (atomicBegin != -1) {
            atomicBlockRanges.add(ImmutableList.of(atomicBegin, id));
        }
        // -----------
        threadEndIndexList.add(id);
    }
    // Get sublists for all threads
    int start = 0;
    for (int i = 0; i < threadList.size(); i++) {
        Thread thread = threadList.get(i);
        int end = threadEndIndexList.get(i);
        if (start != end) {
            this.threadList.add(thread);
            threadEventsMap.put(thread, Collections.unmodifiableList(eventList.subList(start, end)));
            atomicBlocksMap.put(thread, new ArrayList<>());
            for (List<Integer> aRange : atomicBlockRangesMap.get(thread)) {
                atomicBlocksMap.get(thread).add(eventList.subList(aRange.get(0), aRange.get(1)));
            }
        }
        start = end;
    }
}
Also used : EndAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.EndAtomic) Thread(com.dat3m.dartagnan.program.Thread) BigInteger(java.math.BigInteger) BeginAtomic(com.dat3m.dartagnan.program.event.lang.svcomp.BeginAtomic) ImmutableList(com.google.common.collect.ImmutableList)

Example 42 with Thread

use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.

the class RelCtrlDirect method getMaxTupleSet.

@Override
public TupleSet getMaxTupleSet() {
    if (maxTupleSet == null) {
        maxTupleSet = new TupleSet();
        // NOTE: If's (under Linux) have different notion of ctrl dependency than conditional jumps!
        for (Thread thread : task.getProgram().getThreads()) {
            for (Event e1 : thread.getCache().getEvents(FilterBasic.get(Tag.CMP))) {
                for (Event e2 : ((IfAsJump) e1).getBranchesEvents()) {
                    maxTupleSet.add(new Tuple(e1, e2));
                }
            }
            // Relates jumps (except those implementing Ifs and their internal jump to end) with all later events
            List<Event> condJumps = thread.getCache().getEvents(FilterMinus.get(FilterBasic.get(Tag.JUMP), FilterUnion.get(FilterBasic.get(Tag.CMP), FilterBasic.get(Tag.IFI))));
            if (!condJumps.isEmpty()) {
                for (Event e2 : thread.getCache().getEvents(FilterBasic.get(Tag.ANY))) {
                    for (Event e1 : condJumps) {
                        if (e1.getCId() < e2.getCId()) {
                            maxTupleSet.add(new Tuple(e1, e2));
                        }
                    }
                }
            }
        }
        removeMutuallyExclusiveTuples(maxTupleSet);
    }
    return maxTupleSet;
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) Event(com.dat3m.dartagnan.program.event.core.Event) IfAsJump(com.dat3m.dartagnan.program.event.core.IfAsJump) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Thread(com.dat3m.dartagnan.program.Thread)

Example 43 with Thread

use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.

the class RelCrit method getMaxTupleSet.

@Override
public TupleSet getMaxTupleSet() {
    if (maxTupleSet == null) {
        maxTupleSet = new TupleSet();
        for (Thread thread : task.getProgram().getThreads()) {
            for (Event lock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_LOCK))) {
                for (Event unlock : thread.getCache().getEvents(FilterBasic.get(Tag.Linux.RCU_UNLOCK))) {
                    if (lock.getCId() < unlock.getCId()) {
                        maxTupleSet.add(new Tuple(lock, unlock));
                    }
                }
            }
        }
        removeMutuallyExclusiveTuples(maxTupleSet);
    }
    return maxTupleSet;
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Thread(com.dat3m.dartagnan.program.Thread)

Example 44 with Thread

use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.

the class RelRMW method encodeApprox.

@Override
protected BooleanFormula encodeApprox(SolverContext ctx) {
    FormulaManager fmgr = ctx.getFormulaManager();
    BooleanFormulaManager bmgr = fmgr.getBooleanFormulaManager();
    // Encode base (not exclusive pairs) RMW
    TupleSet origEncodeTupleSet = encodeTupleSet;
    encodeTupleSet = new TupleSet(Sets.intersection(encodeTupleSet, baseMaxTupleSet));
    BooleanFormula enc = super.encodeApprox(ctx);
    encodeTupleSet = origEncodeTupleSet;
    // Encode RMW for exclusive pairs
    BooleanFormula unpredictable = bmgr.makeFalse();
    for (Thread thread : task.getProgram().getThreads()) {
        for (Event store : thread.getCache().getEvents(storeExclFilter)) {
            BooleanFormula storeExec = bmgr.makeFalse();
            for (Event load : thread.getCache().getEvents(loadExclFilter)) {
                if (load.getCId() < store.getCId()) {
                    // Encode if load and store form an exclusive pair
                    BooleanFormula isPair = exclPair(load, store, ctx);
                    BooleanFormula isExecPair = bmgr.and(isPair, store.exec());
                    enc = bmgr.and(enc, bmgr.equivalence(isPair, pairingCond(thread, load, store, ctx)));
                    // If load and store have the same address
                    BooleanFormula sameAddress = generalEqual(((MemEvent) load).getMemAddressExpr(), ((MemEvent) store).getMemAddressExpr(), ctx);
                    unpredictable = bmgr.or(unpredictable, bmgr.and(isExecPair, bmgr.not(sameAddress)));
                    // Relation between exclusive load and store
                    enc = bmgr.and(enc, bmgr.equivalence(this.getSMTVar(load, store, ctx), bmgr.and(isExecPair, sameAddress)));
                    // Can be executed if addresses mismatch, but behaviour is "constrained unpredictable"
                    // The implementation does not include all possible unpredictable cases: in case of address
                    // mismatch, addresses of read and write are unknown, i.e. read and write can use any address
                    storeExec = bmgr.or(storeExec, isPair);
                }
            }
            enc = bmgr.and(enc, bmgr.implication(store.exec(), storeExec));
        }
    }
    return bmgr.and(enc, bmgr.equivalence(Flag.ARM_UNPREDICTABLE_BEHAVIOUR.repr(ctx), unpredictable));
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) FormulaManager(org.sosy_lab.java_smt.api.FormulaManager) BooleanFormulaManager(org.sosy_lab.java_smt.api.BooleanFormulaManager) MemEvent(com.dat3m.dartagnan.program.event.core.MemEvent) Event(com.dat3m.dartagnan.program.event.core.Event) BooleanFormula(org.sosy_lab.java_smt.api.BooleanFormula) Thread(com.dat3m.dartagnan.program.Thread)

Example 45 with Thread

use of com.dat3m.dartagnan.program.Thread in project Dat3M by hernanponcedeleon.

the class RelFencerel method getMinTupleSet.

@Override
public TupleSet getMinTupleSet() {
    if (minTupleSet == null) {
        ExecutionAnalysis exec = analysisContext.get(ExecutionAnalysis.class);
        minTupleSet = new TupleSet();
        for (Thread t : task.getProgram().getThreads()) {
            List<Event> fences = t.getCache().getEvents(FilterBasic.get(fenceName));
            List<Event> memEvents = t.getCache().getEvents(FilterBasic.get(Tag.MEMORY));
            for (Event fence : fences) {
                int numEventsBeforeFence = (int) memEvents.stream().mapToInt(Event::getCId).filter(id -> id < fence.getCId()).count();
                List<Event> eventsBefore = memEvents.subList(0, numEventsBeforeFence);
                List<Event> eventsAfter = memEvents.subList(numEventsBeforeFence, memEvents.size());
                for (Event e1 : eventsBefore) {
                    boolean isImpliedByE1 = exec.isImplied(e1, fence);
                    for (Event e2 : eventsAfter) {
                        if (isImpliedByE1 || exec.isImplied(e2, fence)) {
                            minTupleSet.add(new Tuple(e1, e2));
                        }
                    }
                }
            }
        }
        removeMutuallyExclusiveTuples(minTupleSet);
    }
    return minTupleSet;
}
Also used : TupleSet(com.dat3m.dartagnan.wmm.utils.TupleSet) ExecutionAnalysis(com.dat3m.dartagnan.program.analysis.ExecutionAnalysis) Event(com.dat3m.dartagnan.program.event.core.Event) Tuple(com.dat3m.dartagnan.wmm.utils.Tuple) Thread(com.dat3m.dartagnan.program.Thread)

Aggregations

Thread (com.dat3m.dartagnan.program.Thread)48 Event (com.dat3m.dartagnan.program.event.core.Event)27 Tuple (com.dat3m.dartagnan.wmm.utils.Tuple)13 TupleSet (com.dat3m.dartagnan.wmm.utils.TupleSet)11 LogManager (org.apache.logging.log4j.LogManager)10 Logger (org.apache.logging.log4j.Logger)10 BooleanFormula (org.sosy_lab.java_smt.api.BooleanFormula)9 BooleanFormulaManager (org.sosy_lab.java_smt.api.BooleanFormulaManager)9 Program (com.dat3m.dartagnan.program.Program)8 Tag (com.dat3m.dartagnan.program.event.Tag)8 Configuration (org.sosy_lab.common.configuration.Configuration)8 InvalidConfigurationException (org.sosy_lab.common.configuration.InvalidConfigurationException)8 MemEvent (com.dat3m.dartagnan.program.event.core.MemEvent)7 Collectors (java.util.stream.Collectors)7 Context (com.dat3m.dartagnan.verification.Context)6 Preconditions (com.google.common.base.Preconditions)6 FilterBasic (com.dat3m.dartagnan.program.filter.FilterBasic)5 Options (org.sosy_lab.common.configuration.Options)5 Utils.generalEqual (com.dat3m.dartagnan.expression.utils.Utils.generalEqual)4 RegWriter (com.dat3m.dartagnan.program.event.core.utils.RegWriter)4