Search in sources :

Example 1 with ResumeBThread

use of il.ac.bgu.cs.bp.bpjs.execution.tasks.ResumeBThread in project BPjs by bThink-BGU.

the class BProgramSyncSnapshot method triggerEvent.

/**
 * Runs the program from the snapshot, triggering the passed event.
 * @param exSvc the executor service that will advance the threads.
 * @param anEvent the event selected.
 * @param listeners
 * @return A set of b-thread snapshots that should participate in the next cycle.
 * @throws InterruptedException
 */
public BProgramSyncSnapshot triggerEvent(BEvent anEvent, ExecutorService exSvc, Iterable<BProgramRunnerListener> listeners) throws InterruptedException {
    if (anEvent == null)
        throw new IllegalArgumentException("Cannot trigger a null event.");
    if (triggered) {
        throw new IllegalStateException("A BProgramSyncSnapshot is not allowed to be triggered twice.");
    }
    triggered = true;
    Set<BThreadSyncSnapshot> resumingThisRound = new HashSet<>(threadSnapshots.size());
    Set<BThreadSyncSnapshot> sleepingThisRound = new HashSet<>(threadSnapshots.size());
    Set<BThreadSyncSnapshot> nextRound = new HashSet<>(threadSnapshots.size());
    List<BEvent> nextExternalEvents = new ArrayList<>(getExternalEvents());
    try {
        Context ctxt = Context.enter();
        handleInterrupts(anEvent, listeners, bprog, ctxt);
        nextExternalEvents.addAll(bprog.drainEnqueuedExternalEvents());
        // Split threads to those that advance this round and those that sleep.
        threadSnapshots.forEach(snapshot -> {
            (snapshot.getBSyncStatement().shouldWakeFor(anEvent) ? resumingThisRound : sleepingThisRound).add(snapshot);
        });
    } finally {
        Context.exit();
    }
    BPEngineTask.Listener halter = new HaltOnAssertion(exSvc);
    try {
        // add the run results of all those who advance this stage
        nextRound.addAll(exSvc.invokeAll(resumingThisRound.stream().map(bt -> new ResumeBThread(bt, anEvent, halter)).collect(toList())).stream().map(f -> safeGet(f)).filter(Objects::nonNull).collect(toList()));
        // inform listeners which b-threads completed
        Set<String> nextRoundIds = nextRound.stream().map(t -> t.getName()).collect(toSet());
        resumingThisRound.stream().filter(t -> !nextRoundIds.contains(t.getName())).forEach(t -> listeners.forEach(l -> l.bthreadDone(bprog, t)));
        executeAllAddedBThreads(nextRound, exSvc, halter);
        nextExternalEvents.addAll(bprog.drainEnqueuedExternalEvents());
        // carry over BThreads that did not advance this round to next round.
        nextRound.addAll(sleepingThisRound);
        return new BProgramSyncSnapshot(bprog, nextRound, nextExternalEvents, violationRecord.get());
    } catch (RejectedExecutionException ree) {
        // The executor thread pool must have been shut down, e.g. due to program violation.
        return new BProgramSyncSnapshot(bprog, Collections.emptySet(), nextExternalEvents, violationRecord.get());
    }
}
Also used : Context(org.mozilla.javascript.Context) ResumeBThread(il.ac.bgu.cs.bp.bpjs.execution.tasks.ResumeBThread) Context(org.mozilla.javascript.Context) BProgramException(il.ac.bgu.cs.bp.bpjs.exceptions.BProgramException) ContinuationPending(org.mozilla.javascript.ContinuationPending) Set(java.util.Set) Logger(java.util.logging.Logger) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) HashSet(java.util.HashSet) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) List(java.util.List) Future(java.util.concurrent.Future) Collectors.toList(java.util.stream.Collectors.toList) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) StartBThread(il.ac.bgu.cs.bp.bpjs.execution.tasks.StartBThread) Scriptable(org.mozilla.javascript.Scriptable) BProgramRunnerListener(il.ac.bgu.cs.bp.bpjs.execution.listeners.BProgramRunnerListener) Collections(java.util.Collections) Collectors.toSet(java.util.stream.Collectors.toSet) BPEngineTask(il.ac.bgu.cs.bp.bpjs.execution.tasks.BPEngineTask) ExecutorService(java.util.concurrent.ExecutorService) ArrayList(java.util.ArrayList) ResumeBThread(il.ac.bgu.cs.bp.bpjs.execution.tasks.ResumeBThread) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) Objects(java.util.Objects) BPEngineTask(il.ac.bgu.cs.bp.bpjs.execution.tasks.BPEngineTask) HashSet(java.util.HashSet)

Aggregations

BProgramException (il.ac.bgu.cs.bp.bpjs.exceptions.BProgramException)1 BProgramRunnerListener (il.ac.bgu.cs.bp.bpjs.execution.listeners.BProgramRunnerListener)1 BPEngineTask (il.ac.bgu.cs.bp.bpjs.execution.tasks.BPEngineTask)1 ResumeBThread (il.ac.bgu.cs.bp.bpjs.execution.tasks.ResumeBThread)1 StartBThread (il.ac.bgu.cs.bp.bpjs.execution.tasks.StartBThread)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Objects (java.util.Objects)1 Set (java.util.Set)1 ExecutionException (java.util.concurrent.ExecutionException)1 ExecutorService (java.util.concurrent.ExecutorService)1 Future (java.util.concurrent.Future)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 Level (java.util.logging.Level)1 Logger (java.util.logging.Logger)1 Collectors.toList (java.util.stream.Collectors.toList)1 Collectors.toSet (java.util.stream.Collectors.toSet)1