mirror of
https://github.com/golang/go
synced 2024-11-12 10:20:27 -07:00
ae54cf73ca
R=r DELTA=127 (38 added, 3 deleted, 86 changed) OCL=34640 CL=34650
128 lines
2.4 KiB
Go
128 lines
2.4 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";
|
|
"malloc";
|
|
"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 = malloc.GetStats();
|
|
|
|
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] = malloc.Alloc(uintptr(size));
|
|
base, n := malloc.Lookup(b[i]);
|
|
if base != b[i] || !OkAmount(uintptr(size), n) {
|
|
panicln("lookup failed: got", base, n, "for", b[i]);
|
|
}
|
|
if malloc.GetStats().Sys > 1e9 {
|
|
panicln("too much memory allocated");
|
|
}
|
|
}
|
|
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 := malloc.Lookup(b[i]);
|
|
if base != b[i] || !OkAmount(uintptr(size), n) {
|
|
panicln("lookup failed: got", base, n, "for", b[i]);
|
|
}
|
|
malloc.Free(b[i]);
|
|
if stats.Alloc != uint64(alloc - n) {
|
|
panicln("free alloc got", stats.Alloc, "expected", alloc - n, "after free of", n);
|
|
}
|
|
if malloc.GetStats().Sys > 1e9 {
|
|
panicln("too much memory allocated");
|
|
}
|
|
}
|
|
n4 := stats.Alloc;
|
|
|
|
if *chatty {
|
|
fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats);
|
|
}
|
|
if n2-n1 != n3-n4 {
|
|
panicln("wrong alloc count: ", n2-n1, n3-n4);
|
|
}
|
|
}
|
|
|
|
func atoi(s string) int {
|
|
i, _ := strconv.Atoi(s);
|
|
return i
|
|
}
|
|
|
|
func main() {
|
|
flag.Parse();
|
|
b = make([]*byte, 10000);
|
|
if flag.NArg() > 0 {
|
|
AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)));
|
|
return;
|
|
}
|
|
for j := 1; j <= 1<<22; j<<=1 {
|
|
n := len(b);
|
|
max := uintptr(1<<28);
|
|
if !*longtest {
|
|
max = 1<<22;
|
|
}
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|