mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	 91e56e6486
			
		
	
	
		91e56e6486
		
	
	
	
	
		
			
			otherwise it fails spuriously with "newfunc allocated unexpectedly" message when run with GOMAXPROCS>1 (other goroutine allocates). R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/6347056
		
			
				
	
	
		
			128 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // run
 | |
| 
 | |
| // Copyright 2009 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| // Test the behavior of closures.
 | |
| 
 | |
| package main
 | |
| 
 | |
| import "runtime"
 | |
| 
 | |
| var c = make(chan int)
 | |
| 
 | |
| func check(a []int) {
 | |
| 	for i := 0; i < len(a); i++ {
 | |
| 		n := <-c
 | |
| 		if n != a[i] {
 | |
| 			println("want", a[i], "got", n, "at", i)
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func f() {
 | |
| 	var i, j int
 | |
| 
 | |
| 	i = 1
 | |
| 	j = 2
 | |
| 	f := func() {
 | |
| 		c <- i
 | |
| 		i = 4
 | |
| 		g := func() {
 | |
| 			c <- i
 | |
| 			c <- j
 | |
| 		}
 | |
| 		g()
 | |
| 		c <- i
 | |
| 	}
 | |
| 	j = 5
 | |
| 	f()
 | |
| }
 | |
| 
 | |
| // Accumulator generator
 | |
| func accum(n int) func(int) int {
 | |
| 	return func(i int) int {
 | |
| 		n += i
 | |
| 		return n
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func g(a, b func(int) int) {
 | |
| 	c <- a(2)
 | |
| 	c <- b(3)
 | |
| 	c <- a(4)
 | |
| 	c <- b(5)
 | |
| }
 | |
| 
 | |
| func h() {
 | |
| 	var x8 byte = 100
 | |
| 	var x64 int64 = 200
 | |
| 
 | |
| 	c <- int(x8)
 | |
| 	c <- int(x64)
 | |
| 	f := func(z int) {
 | |
| 		g := func() {
 | |
| 			c <- int(x8)
 | |
| 			c <- int(x64)
 | |
| 			c <- z
 | |
| 		}
 | |
| 		g()
 | |
| 		c <- int(x8)
 | |
| 		c <- int(x64)
 | |
| 		c <- int(z)
 | |
| 	}
 | |
| 	x8 = 101
 | |
| 	x64 = 201
 | |
| 	f(500)
 | |
| }
 | |
| 
 | |
| func newfunc() func(int) int { return func(x int) int { return x } }
 | |
| 
 | |
| func main() {
 | |
| 	runtime.GOMAXPROCS(1)
 | |
| 	var fail bool
 | |
| 
 | |
| 	go f()
 | |
| 	check([]int{1, 4, 5, 4})
 | |
| 
 | |
| 	a := accum(0)
 | |
| 	b := accum(1)
 | |
| 	go g(a, b)
 | |
| 	check([]int{2, 4, 6, 9})
 | |
| 
 | |
| 	go h()
 | |
| 	check([]int{100, 200, 101, 201, 500, 101, 201, 500})
 | |
| 
 | |
| 	memstats := new(runtime.MemStats)
 | |
| 	runtime.ReadMemStats(memstats)
 | |
| 	n0 := memstats.Mallocs
 | |
| 
 | |
| 	x, y := newfunc(), newfunc()
 | |
| 	if x(1) != 1 || y(2) != 2 {
 | |
| 		println("newfunc returned broken funcs")
 | |
| 		fail = true
 | |
| 	}
 | |
| 
 | |
| 	runtime.ReadMemStats(memstats)
 | |
| 	if n0 != memstats.Mallocs {
 | |
| 		println("newfunc allocated unexpectedly")
 | |
| 		fail = true
 | |
| 	}
 | |
| 
 | |
| 	ff(1)
 | |
| 
 | |
| 	if fail {
 | |
| 		panic("fail")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func ff(x int) {
 | |
| 	call(func() {
 | |
| 		_ = x
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func call(func()) {
 | |
| }
 |