2008-12-19 04:13:39 -07:00
|
|
|
// $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 (
|
2010-02-03 17:31:34 -07:00
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"runtime"
|
2008-12-19 04:13:39 -07:00
|
|
|
"strconv"
|
|
|
|
)
|
|
|
|
|
2010-02-03 17:31:34 -07:00
|
|
|
var chatty = flag.Bool("v", false, "chatty")
|
|
|
|
var reverse = flag.Bool("r", false, "reverse")
|
|
|
|
var longtest = flag.Bool("l", false, "long test")
|
2008-12-19 04:13:39 -07:00
|
|
|
|
2010-02-03 17:31:34 -07:00
|
|
|
var b []*byte
|
|
|
|
var stats = &runtime.MemStats
|
2008-12-19 04:13:39 -07:00
|
|
|
|
2009-01-20 15:40:40 -07:00
|
|
|
func OkAmount(size, n uintptr) bool {
|
2008-12-19 04:13:39 -07:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2009-01-20 15:40:40 -07:00
|
|
|
func AllocAndFree(size, count int) {
|
2009-01-09 14:42:46 -07:00
|
|
|
if *chatty {
|
2010-02-03 17:31:34 -07:00
|
|
|
fmt.Printf("size=%d count=%d ...\n", size, count)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
n1 := stats.Alloc
|
2008-12-19 04:13:39 -07:00
|
|
|
for i := 0; i < count; i++ {
|
2010-02-03 17:31:34 -07:00
|
|
|
b[i] = runtime.Alloc(uintptr(size))
|
|
|
|
base, n := runtime.Lookup(b[i])
|
2009-01-16 16:03:22 -07:00
|
|
|
if base != b[i] || !OkAmount(uintptr(size), n) {
|
2010-02-03 17:31:34 -07:00
|
|
|
panicln("lookup failed: got", base, n, "for", b[i])
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
if runtime.MemStats.Sys > 1e9 {
|
|
|
|
panicln("too much memory allocated")
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
n2 := stats.Alloc
|
2009-01-09 14:42:46 -07:00
|
|
|
if *chatty {
|
2010-02-03 17:31:34 -07:00
|
|
|
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
n3 := stats.Alloc
|
2008-12-19 04:13:39 -07:00
|
|
|
for j := 0; j < count; j++ {
|
2010-02-03 17:31:34 -07:00
|
|
|
i := j
|
2009-01-09 14:42:46 -07:00
|
|
|
if *reverse {
|
2010-02-03 17:31:34 -07:00
|
|
|
i = count - 1 - j
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
alloc := uintptr(stats.Alloc)
|
|
|
|
base, n := runtime.Lookup(b[i])
|
2009-01-16 16:03:22 -07:00
|
|
|
if base != b[i] || !OkAmount(uintptr(size), n) {
|
2010-02-03 17:31:34 -07:00
|
|
|
panicln("lookup failed: got", base, n, "for", b[i])
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
runtime.Free(b[i])
|
|
|
|
if stats.Alloc != uint64(alloc-n) {
|
|
|
|
panicln("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
if runtime.MemStats.Sys > 1e9 {
|
|
|
|
panicln("too much memory allocated")
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
n4 := stats.Alloc
|
2008-12-19 04:13:39 -07:00
|
|
|
|
2009-01-09 14:42:46 -07:00
|
|
|
if *chatty {
|
2010-02-03 17:31:34 -07:00
|
|
|
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
if n2-n1 != n3-n4 {
|
2010-02-03 17:31:34 -07:00
|
|
|
panicln("wrong alloc count: ", n2-n1, n3-n4)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func atoi(s string) int {
|
2010-02-03 17:31:34 -07:00
|
|
|
i, _ := strconv.Atoi(s)
|
2008-12-19 04:13:39 -07:00
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
2010-03-24 10:40:09 -06:00
|
|
|
runtime.MemProfileRate = 0 // disable profiler
|
2010-02-03 17:31:34 -07:00
|
|
|
flag.Parse()
|
|
|
|
b = make([]*byte, 10000)
|
2008-12-19 04:13:39 -07:00
|
|
|
if flag.NArg() > 0 {
|
2010-02-03 17:31:34 -07:00
|
|
|
AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)))
|
|
|
|
return
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
maxb := 1 << 22
|
2009-10-09 12:18:32 -06:00
|
|
|
if !*longtest {
|
2010-02-03 17:31:34 -07:00
|
|
|
maxb = 1 << 19
|
2009-10-09 12:18:32 -06:00
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
for j := 1; j <= maxb; j <<= 1 {
|
|
|
|
n := len(b)
|
|
|
|
max := uintptr(1 << 28)
|
2009-01-09 14:42:46 -07:00
|
|
|
if !*longtest {
|
2010-02-03 17:31:34 -07:00
|
|
|
max = uintptr(maxb)
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
2009-06-05 11:59:37 -06:00
|
|
|
if uintptr(j)*uintptr(n) > max {
|
2010-02-03 17:31:34 -07:00
|
|
|
n = int(max / uintptr(j))
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
if n < 10 {
|
2010-02-03 17:31:34 -07:00
|
|
|
n = 10
|
2008-12-19 04:13:39 -07:00
|
|
|
}
|
|
|
|
for m := 1; m <= n; {
|
2010-02-03 17:31:34 -07:00
|
|
|
AllocAndFree(j, m)
|
2008-12-19 04:13:39 -07:00
|
|
|
if m == n {
|
|
|
|
break
|
|
|
|
}
|
2010-02-03 17:31:34 -07:00
|
|
|
m = 5 * m / 4
|
2008-12-19 04:13:39 -07:00
|
|
|
if m < 4 {
|
|
|
|
m++
|
|
|
|
}
|
|
|
|
if m > n {
|
|
|
|
m = n
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|