X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2Fquery%2FScheduling.java;fp=bundles%2Forg.simantics.db.impl%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fimpl%2Fquery%2FScheduling.java;h=061435f25f7d924731a8357dc2e76e7c7dd030a8;hb=a88c02c2d0f4250caf887a130b9f4314c6564722;hp=0000000000000000000000000000000000000000;hpb=785f638bab44e70ec6103c3891daea95bcda9a07;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Scheduling.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Scheduling.java new file mode 100644 index 000000000..061435f25 --- /dev/null +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Scheduling.java @@ -0,0 +1,102 @@ +package org.simantics.db.impl.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.concurrent.Semaphore; + +import org.simantics.db.impl.graph.BarrierTracing; +import org.simantics.db.impl.graph.ReadGraphImpl; +import org.simantics.db.impl.query.QueryProcessor.AsyncBarrier; +import org.simantics.db.impl.query.QueryProcessor.SessionTask; + +public class Scheduling { + + private final Semaphore requests; + + private Map> freeScheduling = new HashMap<>(); + + private LinkedList topLevelTasks = new LinkedList(); + + public Scheduling(Semaphore requests) { + this.requests = requests; + } + + public SessionTask getSubTask(ReadGraphImpl parent) { + synchronized(this) { + assert(parent.asyncBarrier.isBlocking()); + LinkedList tasks = freeScheduling.get(parent.asyncBarrier); + if(tasks == null) + return null; + SessionTask task = tasks.removeLast(); + if(tasks.isEmpty()) + freeScheduling.remove(parent.asyncBarrier); + return task; + } + } + + public boolean pumpTask(ArrayList tasks) { + + synchronized(this) { + + // First finish existing executions + if(!freeScheduling.isEmpty()) { + Map.Entry> ls = freeScheduling.entrySet().iterator().next(); + assert(ls.getKey().isBlocking()); + tasks.add(ls.getValue().removeLast()); + if(ls.getValue().isEmpty()) + freeScheduling.remove(ls.getKey()); + return true; + } + // Check for new tasks + if(!topLevelTasks.isEmpty()) { + tasks.add(topLevelTasks.removeLast()); + return true; + } + + return false; + + } + + } + + final public SessionTask scheduleOrReturnForExecution(SessionTask request) { + + assert(request != null); + + synchronized(this) { + + if(BarrierTracing.BOOKKEEPING) { + Exception current = new Exception(); + Exception previous = BarrierTracing.tasks.put(request, current); + if(previous != null) { + previous.printStackTrace(); + current.printStackTrace(); + } + } + + requests.release(); + + if(request.rootGraph != null) { + AsyncBarrier sb = request.rootGraph.asyncBarrier.getBlockingBarrier(); + if(sb != null) { + LinkedList ls = freeScheduling.get(sb); + if(ls == null) { + ls = new LinkedList(); + freeScheduling.put(sb, ls); + } + ls.addFirst(request); + return null; + } + } + + topLevelTasks.addFirst(request); + + } + + return null; + + } + +}