Search in sources :

Example 1 with BProgramRunnerListener

use of il.ac.bgu.cs.bp.bpjs.execution.listeners.BProgramRunnerListener 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)

Example 2 with BProgramRunnerListener

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

the class BProgramSyncSnapshot method handleInterrupts.

private void handleInterrupts(BEvent anEvent, Iterable<BProgramRunnerListener> listeners, BProgram bprog, Context ctxt) {
    Set<BThreadSyncSnapshot> interrupted = threadSnapshots.stream().filter(bt -> bt.getBSyncStatement().getInterrupt().contains(anEvent)).collect(toSet());
    if (!interrupted.isEmpty()) {
        threadSnapshots.removeAll(interrupted);
        interrupted.forEach(bt -> {
            listeners.forEach(l -> l.bthreadRemoved(bprog, bt));
            bt.getInterrupt().ifPresent(func -> {
                final Scriptable scope = bt.getScope();
                // can't call bsync from a break handler.
                scope.delete("bsync");
                try {
                    ctxt.callFunctionWithContinuations(func, scope, new Object[] { anEvent });
                } catch (ContinuationPending ise) {
                    throw new BProgramException("Cannot call bsync from a break-upon handler. Please consider pushing an external event.");
                }
            });
        });
    }
}
Also used : 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) ContinuationPending(org.mozilla.javascript.ContinuationPending) Scriptable(org.mozilla.javascript.Scriptable) BProgramException(il.ac.bgu.cs.bp.bpjs.exceptions.BProgramException)

Aggregations

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