Index: benchmark/readyQ/churn.go
===================================================================
--- benchmark/readyQ/churn.go	(revision 62402e2cbc4f12fb140f25baed97fa9729396e77)
+++ benchmark/readyQ/churn.go	(revision 62402e2cbc4f12fb140f25baed97fa9729396e77)
@@ -0,0 +1,98 @@
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"math/rand"
+	"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()
+	s := rand.NewSource(time.Now().UnixNano())
+	rng := rand.New(s)
+
+	count := uint64(0)
+	start.Wait()
+	for true {
+
+		sem := spots[ rng.Intn(100) % len(spots) ];
+		if !skip { sem.Release(1); };
+		sem.Acquire(ctx,1);
+		skip = false;
+
+		count += 1
+		if  clock_mode && atomic.LoadInt32(&stop) == 1 { break }
+		if !clock_mode && count >= stop_count { break }
+	}
+
+	atomic.AddInt64(&threads_left, -1);
+	result <- count
+}
+
+func main() {
+	var spot_cnt int
+
+	spot_cntOpt := flag.Int("s", 1, "Number of spots in the system")
+
+	bench_init()
+
+	spot_cnt = *spot_cntOpt
+
+	threads_left = int64(nthreads)
+
+	result := make(chan uint64)
+	var wg sync.WaitGroup
+	wg.Add(1)
+
+	spots := make([] * semaphore.Weighted, spot_cnt)
+	for i := range spots {
+		ctx := context.TODO()
+		spots[i] = semaphore.NewWeighted(20000)
+		spots[i].Acquire(ctx, 20000)
+	}
+
+	for i := 0; i < nthreads; i++ {
+		go churner(result, &wg, i < len(spots), spots)
+	}
+	fmt.Printf("Starting\n");
+	atomic.StoreInt32(&stop, 0)
+	start := time.Now()
+	wg.Done();
+	wait(start, true);
+
+	atomic.StoreInt32(&stop, 1)
+	end := time.Now()
+	duration := end.Sub(start)
+
+	fmt.Printf("\nDone\n")
+
+	for i := range spots {
+		spots[i].Release(10000)
+	}
+
+	global_counter := uint64(0)
+	for i := 0; i < nthreads; i++ {
+		global_counter += <- result
+	}
+
+	p := message.NewPrinter(language.English)
+	p.Printf("Duration (ms)        : %d\n", duration.Milliseconds())
+	p.Printf("Number of processors : %d\n", nprocs);
+	p.Printf("Number of threads    : %d\n", nthreads);
+	p.Printf("Number of spots      : %d\n", spot_cnt);
+	p.Printf("Total Operations(ops): %15d\n", global_counter);
+	// p.Printf("Total blocks         : %15d\n", global_blocks);
+	p.Printf("Ops per second       : %18.2f\n", float64(global_counter) / duration.Seconds());
+	p.Printf("ns per ops           : %18.2f\n", float64(duration.Nanoseconds()) / float64(global_counter))
+	p.Printf("Ops per threads      : %15d\n", global_counter / uint64(nthreads))
+	p.Printf("Ops per procs        : %15d\n", global_counter / uint64(nprocs))
+	p.Printf("Ops/sec/procs        : %18.2f\n", (float64(global_counter) / float64(nprocs)) / duration.Seconds())
+	p.Printf("ns per ops/procs     : %18.2f\n", float64(duration.Nanoseconds()) / (float64(global_counter) / float64(nprocs)))
+}
