Index: benchmark/readyQ/churn.go
===================================================================
--- benchmark/readyQ/churn.go	(revision f56101f1a10d47718fe1bda947aa0608f6d95ec2)
+++ benchmark/readyQ/churn.go	(revision 160ee4c993ad3541f0715f8ddef04bfc84888981)
@@ -2,18 +2,16 @@
 
 import (
-	"context"
 	"flag"
 	"fmt"
 	"math/rand"
+	"runtime"
 	"sync"
 	"sync/atomic"
 	"time"
-	"golang.org/x/sync/semaphore"
 	"golang.org/x/text/language"
 	"golang.org/x/text/message"
 )
 
-func churner(result chan uint64, start *sync.WaitGroup, skip bool, spots [] * semaphore.Weighted) {
-	ctx := context.TODO()
+func churner(result chan uint64, start *sync.WaitGroup, spots [] chan struct {}) {
 	s := rand.NewSource(time.Now().UnixNano())
 	rng := rand.New(s)
@@ -24,7 +22,6 @@
 
 		sem := spots[ rng.Intn(100) % len(spots) ];
-		if !skip { sem.Release(1); };
-		sem.Acquire(ctx,1);
-		skip = false;
+		sem <- (struct {}{})
+		<- sem;
 
 		count += 1
@@ -52,13 +49,11 @@
 	wg.Add(1)
 
-	spots := make([] * semaphore.Weighted, spot_cnt)
+	spots := make([] chan struct {}, spot_cnt)
 	for i := range spots {
-		ctx := context.TODO()
-		spots[i] = semaphore.NewWeighted(20000)
-		spots[i].Acquire(ctx, 20000)
+		spots[i] = make(chan struct {}, 1)
 	}
 
 	for i := 0; i < nthreads; i++ {
-		go churner(result, &wg, i < len(spots), spots)
+		go churner(result, &wg, spots)
 	}
 	fmt.Printf("Starting\n");
@@ -74,6 +69,12 @@
 	fmt.Printf("\nDone\n")
 
-	for i := range spots {
-		spots[i].Release(10000)
+	for atomic.LoadInt64(&threads_left) != 0 {
+		for i := range spots {
+			select {
+			case spots[i] <- (struct {}{}):
+			default:
+			}
+			runtime.Gosched()
+		}
 	}
 
