sclass ThreadPool { int max = numberOfCores(); new Set used; new Set free; synchronized int total() { ret l(used)+l(free); } synchronized bool nonFree() { ret empty(free) && max < total(); } event customerMustWaitAlert; void fireCustomerMustWaitAlert { vmBus_send customerMustWaitAlert(this, currentThread()); customerMustWaitAlert(); } synchronized Thread acquireThread(Runnable action) ctex { while (nonFree()) { if (total() < max) { free.add(newThread()); break; } fireCustomerMustWaitAlert(); wait(); } PooledThread t = first(free); t.addWork(action); // will move it from free to used ret t; } class PooledThread extends Thread { *(S name) { super(name); } AppendableChain q; synchronized Runnable _grabWork() { Runnable r = first(q); q = popFirst(q); if (r == null) threadIdling(this); ret r; } run { while ping (true) { Runnable r = _grabWork(); if (r != null) pcall { r.run(); } else { synchronized { wait(); } } } } // append to q (do later) void addWork(Runnable r) { if (r == null) ret; synchronized { if (isEmpty(q)) markUsed(this); q = chainPlus(q, r); ifdef CompactQ_Stats biggestSize = max(size(), biggestSize); endifdef } notify(); } } PooledThread newThread() { ret new PooledThread("Thread Pool Inhabitant " + n2(total()+1)); } synchronized void threadIdling(PooledThread t) { used.remove(t); free.add(t); notifyAll(); } synchronized void markUsed(PooledThread t) { free.remove(t); used.add(t); } }