!7 sinterface Steppable { public bool step(); // return false if done } sclass MultiThreadStepper { Lock lock = lock(); L threads = synchroList(); L steppables = synchroList(); L stepping = synchroList(); int coresToUse = coresToUse(); volatile bool cancelled; *() {} *(Steppable... steppables) { addAll(this.steppables, steppables); } void start { print("Using " + n2(coresToUse, "core")); repeat coresToUse { threads.add(startThread(r { int i = 0; while licensed { Steppable s; { lock lock; if (done()) ret; s = get(steppables, mod(i++, l(steppables))); if (s == null) continue with sleep(100); steppables.remove(s); stepping.add(s); } bool done = false; try { done = !s.step(); } catch e { _handleException(e); done = true; } finally { lock lock; stepping.remove(s); if (!done) steppable.add(s); } } })); } } bool done() { ret empty(steppables) || cancelled; } void stop { cancelled = true; cancelThreads(getAndClearList(threads)); } void cleanMeUp { stop(); } } p-exp { new MultiThreadStepper().start(); }