diff --git a/src/main/java/uk/co/edstow/cain/ReverseSearch.java b/src/main/java/uk/co/edstow/cain/ReverseSearch.java index 8a055b8..802fea4 100644 --- a/src/main/java/uk/co/edstow/cain/ReverseSearch.java +++ b/src/main/java/uk/co/edstow/cain/ReverseSearch.java @@ -228,6 +228,7 @@ public RunConfig setCostFunction(Function, Integer> costFunct private final int goalReductionsPerStep; private final int goalReductionsTolerance; + private final Object workMonitor = new Object(); public ReverseSearch(List initialGoals, List finalGoals, Generator generator, RunConfig runConfig, RegisterAllocator registerAllocator) { this.liveCounter = runConfig.liveCounter; @@ -409,7 +410,9 @@ public void run() { } endTime(); } - if(workersFinished.tryAcquire()){ + + boolean allSleeping = workersThreads.stream().noneMatch(w -> w.active); + if(workersFinished.tryAcquire() || allSleeping){ workersFinished.release(); if(!quiet) { System.out.println("\nWorkers Are finished"); @@ -488,12 +491,25 @@ public void run() { } private WorkState stealWork() throws InterruptedException { - Worker c = next; WorkState s = null; - while (s==null){ - s = localTraversalSystem.steal(c.localTraversalSystem); - c = c.next; - } + while (true) { + + for (Worker c = next; c.id != id && s == null; c = c.next) { + s = localTraversalSystem.steal(c.localTraversalSystem); + } + + if (s != null) + break; + + synchronized (workMonitor) { + try { + active = false; + workMonitor.wait(); + active = true; + } catch (InterruptedException ignored) {} + } + } + steals++; return s; } @@ -604,7 +620,9 @@ private void iSearch(WorkState s){ } WorkState next = new WorkState<>(depth, goals, currentPlan, goalPairs); localTraversalSystem.add(child, next); - + synchronized (workMonitor) { + workMonitor.notifyAll(); + } } private boolean tryDirectSolve(int depth, GoalBag goals, Plan currentPlan) {