thread-ring Go #6 program
source code
/* The Computer Language Benchmarks Game
http://benchmarksgame.alioth.debian.org/
contributed by KP
modified by fwip
*/
package main
import (
"fmt"
"os"
"runtime"
"strconv"
"sync"
)
type Token int
type T struct {
next *T
label int
value int
mux sync.Mutex
}
func (w *T) put(v int) {
w.value = v
if v == 0 {
res <- w.label
} else {
w.mux.Unlock()
}
}
func (w *T) run() {
for {
w.mux.Lock()
w.next.put(w.value - 1)
runtime.Gosched()
}
}
func (w *T) Start(label int, next *T) {
w.label = label
w.next = next
w.mux.Lock()
go w.run()
}
const NThreads = 503
var res = make(chan int)
func main() {
n := 1000
if len(os.Args) > 1 {
n, _ = strconv.Atoi(os.Args[1])
}
runtime.GOMAXPROCS(1)
var channels [NThreads]T
for i := range channels {
channels[i].Start(i+1, &channels[(i+1)%NThreads])
}
channels[0].put(n)
fmt.Println(<-res)
}
notes, command-line, and program output
NOTES:
64-bit Ubuntu quad core
go version go1.10 linux/amd64
Sat, 17 Feb 2018 19:19:11 GMT
MAKE:
/opt/src/go1.10.linux-amd64/go/bin/go build -o threadring.go-6.go_run
0.38s to complete and log all make actions
COMMAND LINE:
./threadring.go-6.go_run 50000000
PROGRAM OUTPUT:
292