github.com/aclements/go-misc@v0.0.0-20240129233631-2f6ede80790c/go-weave/models/cl20858.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 // cl20858 is a model for checking the proposed scheduler change in CL 8 // 20858. 9 package main 10 11 import ( 12 "github.com/aclements/go-misc/go-weave/amb" 13 "github.com/aclements/go-misc/go-weave/weave" 14 ) 15 16 var sched = weave.Scheduler{Strategy: &amb.StrategyDFS{}} 17 18 func mainOld() { 19 sched.Run(func() { 20 runnext, runqhead, runqtail = 0, 0, 0 21 22 runqput(1) 23 sched.Go(func() { 24 runqput(2) 25 runqget() 26 }) 27 if runqempty() { 28 panic("runqempty") 29 } 30 }) 31 } 32 33 func main() { 34 states := 0 35 sched.Run(func() { 36 states++ 37 runnext, runqhead, runqtail = 0, 0, 0 38 39 sched.Go(func() { 40 for i := 0; i < 5; i++ { 41 if sched.Amb(2) == 0 { 42 runqget() 43 } else { 44 runqput(1) 45 } 46 } 47 }) 48 var empty, nonempty, checks int 49 v := runqempty() 50 if empty == 0 && v == true { 51 panic("spurious runqempty()") 52 } 53 if nonempty == checks && v == false { 54 panic("spurious !runqempty()") 55 } 56 }) 57 println(states, "states") 58 } 59 60 var runnext int 61 var runqhead, runqtail int 62 var runq [256]int 63 64 func runqput(g int) { 65 old := runnext 66 runnext = g 67 sched.Sched() 68 if old == 0 { 69 return 70 } 71 72 h := runqhead 73 sched.Sched() 74 t := runqtail 75 sched.Sched() 76 if t-h < len(runq) { 77 runq[t%len(runq)] = g 78 sched.Sched() 79 runqtail = t + 1 80 sched.Sched() 81 return 82 } 83 panic("runq full") 84 } 85 86 func runqget() int { 87 next := runnext 88 if next != 0 { 89 runnext = 0 90 sched.Sched() 91 return next 92 } 93 94 for { 95 h := runqhead 96 sched.Sched() 97 t := runqtail 98 sched.Sched() 99 if t == h { 100 return 0 101 } 102 g := runq[h%len(runq)] 103 sched.Sched() 104 if runqhead == h { 105 runqhead = h + 1 106 sched.Sched() 107 return g 108 } 109 } 110 } 111 112 func runqemptyOld() bool { 113 h := runqhead 114 sched.Sched() 115 t := runqtail 116 sched.Sched() 117 n := runnext 118 sched.Sched() 119 return h == t && n == 0 120 } 121 122 func runqempty() bool { 123 for { 124 h := runqhead 125 sched.Sched() 126 t := runqtail 127 sched.Sched() 128 n := runnext 129 sched.Sched() 130 t2 := runqtail 131 sched.Sched() 132 if t == t2 { 133 return h == t && n == 0 134 } 135 } 136 } 137 138 func runqemptyTest() bool { 139 for { 140 h := runqhead 141 sched.Sched() 142 n := runnext 143 sched.Sched() 144 t := runqtail 145 sched.Sched() 146 return h == t && n == 0 147 } 148 }