func aGoroutine(a int) { if a == 4 { //panic("test panic in goroutine 4") } for i := 0; i < a; i++ { tardisgolib.Gosched() } (&aGrCtrMux).Lock() atomic.AddInt32(&aGrCtr, -1) (&aGrCtrMux).Unlock() aGrWG.Done() }
func pushBooks(x, y *float64, state *int, cartLoad int) { *state = Full for *x = 0.0; *x < 150.0; (*x) += 10.0 / float64(cartLoad) { if *y > 0.0 { // create bumps in the road *y = 0.0 } else { *y = float64(tardisgolib.HAXE("Std.random(3);")) // random small bumps } tardisgolib.Gosched() // without this, the animation would not show each state } if *x > 150.0 { // constrain large x offsets *x = 150.0 } *y = 0.0 }
func moreBooks(x, y *float64, state *int) { *state = Empty for *x > 0.0 { *x -= 10.0 if *x < 0.0 { // no -ve x offsets please *x = 0.0 } if *y > 0.0 { // create bumps in the road *y = 0.0 } else { *y = float64(tardisgolib.HAXE("Std.random(5);")) // random bigger bumps } tardisgolib.Gosched() // would not show state without this, the animation would jump. } *y = 0.0 }
func main() { // As before we'll count how many operations we perform. var ops int64 // The `reads` and `writes` channels will be used by // other goroutines to issue read and write requests, // respectively. reads := make(chan *readOp) writes := make(chan *writeOp) // Here is the goroutine that owns the `state`, which // is a map as in the previous example but now private // to the stateful goroutine. This goroutine repeatedly // selects on the `reads` and `writes` channels, // responding to requests as they arrive. A response // is executed by first performing the requested // operation and then sending a value on the response // channel `resp` to indicate success (and the desired // value in the case of `reads`). go func() { state := make(map[int]int) for { select { case read := <-reads: read.resp <- state[read.key] case write := <-writes: state[write.key] = write.val write.resp <- true } } }() // This starts 100 goroutines to issue reads to the // state-owning goroutine via the `reads` channel. // Each read requires constructing a `readOp`, sending // it over the `reads` channel, and the receiving the // result over the provided `resp` channel. for r := 0; r < 100; r++ { go func() { for { read := &readOp{ key: int(tardisgolib.HAXE("Std.random(5);")), // rand.Intn(5), resp: make(chan int)} reads <- read <-read.resp atomic.AddInt64(&ops, 1) } }() } // We start 10 writes as well, using a similar // approach. for w := 0; w < 10; w++ { go func() { for { write := &writeOp{ key: int(tardisgolib.HAXE("Std.random(5);")), // rand.Intn(5), val: int(tardisgolib.HAXE("Std.random(100);")), // rand.Intn(100), resp: make(chan bool)} writes <- write <-write.resp atomic.AddInt64(&ops, 1) } }() } // Let the goroutines work for a second. //time.Sleep(time.Second) for i := 0; i < 1000; i++ { tardisgolib.Gosched() } // Finally, capture and report the `ops` count. opsFinal := atomic.LoadInt64(&ops) //fmt.Println("ops:", opsFinal) println("ops:", int(opsFinal)) // TODO println of a 64-bit int does not show the actual value on all platforms, only the type name see issue #18 }
func loop(n int) { // add some delay when required for n > 0 { n-- tardisgolib.Gosched() // give up control in order to show the gopher waiting } }
// Gosched implements runtime.Goshed func Gosched() { tardisgolib.Gosched() }