mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	 325cf8ef21
			
		
	
	
		325cf8ef21
		
	
	
	
	
		
			
			in the tests, println+panic. gofmt some tests too. R=rsc CC=golang-dev https://golang.org/cl/741041
		
			
				
	
	
		
			138 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // $G $D/$F.go && $L $F.$A && ./$A.out
 | |
| 
 | |
| // 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.
 | |
| 
 | |
| // Repeated malloc test.
 | |
| 
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"flag"
 | |
| 	"fmt"
 | |
| 	"runtime"
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| var chatty = flag.Bool("v", false, "chatty")
 | |
| var reverse = flag.Bool("r", false, "reverse")
 | |
| var longtest = flag.Bool("l", false, "long test")
 | |
| 
 | |
| var b []*byte
 | |
| var stats = &runtime.MemStats
 | |
| 
 | |
| func OkAmount(size, n uintptr) bool {
 | |
| 	if n < size {
 | |
| 		return false
 | |
| 	}
 | |
| 	if size < 16*8 {
 | |
| 		if n > size+16 {
 | |
| 			return false
 | |
| 		}
 | |
| 	} else {
 | |
| 		if n > size*9/8 {
 | |
| 			return false
 | |
| 		}
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| func AllocAndFree(size, count int) {
 | |
| 	if *chatty {
 | |
| 		fmt.Printf("size=%d count=%d ...\n", size, count)
 | |
| 	}
 | |
| 	n1 := stats.Alloc
 | |
| 	for i := 0; i < count; i++ {
 | |
| 		b[i] = runtime.Alloc(uintptr(size))
 | |
| 		base, n := runtime.Lookup(b[i])
 | |
| 		if base != b[i] || !OkAmount(uintptr(size), n) {
 | |
| 			println("lookup failed: got", base, n, "for", b[i])
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 		if runtime.MemStats.Sys > 1e9 {
 | |
| 			println("too much memory allocated")
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 	}
 | |
| 	n2 := stats.Alloc
 | |
| 	if *chatty {
 | |
| 		fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
 | |
| 	}
 | |
| 	n3 := stats.Alloc
 | |
| 	for j := 0; j < count; j++ {
 | |
| 		i := j
 | |
| 		if *reverse {
 | |
| 			i = count - 1 - j
 | |
| 		}
 | |
| 		alloc := uintptr(stats.Alloc)
 | |
| 		base, n := runtime.Lookup(b[i])
 | |
| 		if base != b[i] || !OkAmount(uintptr(size), n) {
 | |
| 			println("lookup failed: got", base, n, "for", b[i])
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 		runtime.Free(b[i])
 | |
| 		if stats.Alloc != uint64(alloc-n) {
 | |
| 			println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 		if runtime.MemStats.Sys > 1e9 {
 | |
| 			println("too much memory allocated")
 | |
| 			panic("fail")
 | |
| 		}
 | |
| 	}
 | |
| 	n4 := stats.Alloc
 | |
| 
 | |
| 	if *chatty {
 | |
| 		fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
 | |
| 	}
 | |
| 	if n2-n1 != n3-n4 {
 | |
| 		println("wrong alloc count: ", n2-n1, n3-n4)
 | |
| 		panic("fail")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func atoi(s string) int {
 | |
| 	i, _ := strconv.Atoi(s)
 | |
| 	return i
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	runtime.MemProfileRate = 0 // disable profiler
 | |
| 	flag.Parse()
 | |
| 	b = make([]*byte, 10000)
 | |
| 	if flag.NArg() > 0 {
 | |
| 		AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)))
 | |
| 		return
 | |
| 	}
 | |
| 	maxb := 1 << 22
 | |
| 	if !*longtest {
 | |
| 		maxb = 1 << 19
 | |
| 	}
 | |
| 	for j := 1; j <= maxb; j <<= 1 {
 | |
| 		n := len(b)
 | |
| 		max := uintptr(1 << 28)
 | |
| 		if !*longtest {
 | |
| 			max = uintptr(maxb)
 | |
| 		}
 | |
| 		if uintptr(j)*uintptr(n) > max {
 | |
| 			n = int(max / uintptr(j))
 | |
| 		}
 | |
| 		if n < 10 {
 | |
| 			n = 10
 | |
| 		}
 | |
| 		for m := 1; m <= n; {
 | |
| 			AllocAndFree(j, m)
 | |
| 			if m == n {
 | |
| 				break
 | |
| 			}
 | |
| 			m = 5 * m / 4
 | |
| 			if m < 4 {
 | |
| 				m++
 | |
| 			}
 | |
| 			if m > n {
 | |
| 				m = n
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |