blob: 7552e99b469e1f89621f1b6148b82a168e3b614c [file] [log] [blame]
Russ Coxda0a7d72008-12-19 03:13:39 -08001// $G $D/$F.go && $L $F.$A && ./$A.out
2
3// Copyright 2009 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Repeated malloc test.
8
9package main
10
11import (
12 "flag";
13 "fmt";
14 "malloc";
15 "strconv"
16)
17
Rob Pikec45d2a72009-01-09 13:42:46 -080018var chatty = flag.Bool("v", false, "chatty");
19var reverse = flag.Bool("r", false, "reverse");
20var longtest = flag.Bool("l", false, "long test");
Russ Coxda0a7d72008-12-19 03:13:39 -080021
Russ Coxc3077f72008-12-19 17:11:54 -080022var b []*byte;
Russ Coxda0a7d72008-12-19 03:13:39 -080023var stats = malloc.GetStats();
24
Russ Cox839a6842009-01-20 14:40:40 -080025func OkAmount(size, n uintptr) bool {
Russ Coxda0a7d72008-12-19 03:13:39 -080026 if n < size {
27 return false
28 }
29 if size < 16*8 {
30 if n > size+16 {
31 return false
32 }
33 } else {
34 if n > size*9/8 {
35 return false
36 }
37 }
38 return true
39}
40
Russ Cox839a6842009-01-20 14:40:40 -080041func AllocAndFree(size, count int) {
Rob Pikec45d2a72009-01-09 13:42:46 -080042 if *chatty {
Rob Pike61f33022009-01-15 13:48:11 -080043 fmt.Printf("size=%d count=%d ...\n", size, count);
Russ Coxda0a7d72008-12-19 03:13:39 -080044 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080045 n1 := stats.Alloc;
Russ Coxda0a7d72008-12-19 03:13:39 -080046 for i := 0; i < count; i++ {
Russ Coxb014be72009-06-05 10:59:37 -070047 b[i] = malloc.Alloc(uintptr(size));
Russ Coxda0a7d72008-12-19 03:13:39 -080048 base, n := malloc.Lookup(b[i]);
Ian Lance Taylor03c40f52009-01-16 15:03:22 -080049 if base != b[i] || !OkAmount(uintptr(size), n) {
Russ Coxda0a7d72008-12-19 03:13:39 -080050 panicln("lookup failed: got", base, n, "for", b[i]);
51 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080052 if malloc.GetStats().Sys > 1e9 {
Russ Coxda0a7d72008-12-19 03:13:39 -080053 panicln("too much memory allocated");
54 }
55 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080056 n2 := stats.Alloc;
Rob Pikec45d2a72009-01-09 13:42:46 -080057 if *chatty {
Rob Pike61f33022009-01-15 13:48:11 -080058 fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats);
Russ Coxda0a7d72008-12-19 03:13:39 -080059 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080060 n3 := stats.Alloc;
Russ Coxda0a7d72008-12-19 03:13:39 -080061 for j := 0; j < count; j++ {
62 i := j;
Rob Pikec45d2a72009-01-09 13:42:46 -080063 if *reverse {
Russ Coxda0a7d72008-12-19 03:13:39 -080064 i = count - 1 - j;
65 }
Russ Coxb014be72009-06-05 10:59:37 -070066 alloc := uintptr(stats.Alloc);
Russ Coxda0a7d72008-12-19 03:13:39 -080067 base, n := malloc.Lookup(b[i]);
Ian Lance Taylor03c40f52009-01-16 15:03:22 -080068 if base != b[i] || !OkAmount(uintptr(size), n) {
Russ Coxda0a7d72008-12-19 03:13:39 -080069 panicln("lookup failed: got", base, n, "for", b[i]);
70 }
71 malloc.Free(b[i]);
Russ Coxb014be72009-06-05 10:59:37 -070072 if stats.Alloc != uint64(alloc - n) {
73 panicln("free alloc got", stats.Alloc, "expected", alloc - n, "after free of", n);
Russ Coxda0a7d72008-12-19 03:13:39 -080074 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080075 if malloc.GetStats().Sys > 1e9 {
Russ Coxda0a7d72008-12-19 03:13:39 -080076 panicln("too much memory allocated");
77 }
78 }
Russ Coxf48cbfd2009-01-16 16:12:14 -080079 n4 := stats.Alloc;
Russ Coxda0a7d72008-12-19 03:13:39 -080080
Rob Pikec45d2a72009-01-09 13:42:46 -080081 if *chatty {
Rob Pike61f33022009-01-15 13:48:11 -080082 fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats);
Russ Coxda0a7d72008-12-19 03:13:39 -080083 }
84 if n2-n1 != n3-n4 {
85 panicln("wrong alloc count: ", n2-n1, n3-n4);
86 }
87}
88
89func atoi(s string) int {
Russ Coxae54cf72009-09-15 12:42:24 -070090 i, _ := strconv.Atoi(s);
Russ Coxda0a7d72008-12-19 03:13:39 -080091 return i
92}
93
94func main() {
95 flag.Parse();
Russ Cox55645042009-01-06 15:19:02 -080096 b = make([]*byte, 10000);
Russ Coxda0a7d72008-12-19 03:13:39 -080097 if flag.NArg() > 0 {
98 AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)));
99 return;
100 }
Russ Coxebd27d62009-10-09 11:18:32 -0700101 maxb := 1<<22;
102 if !*longtest {
103 maxb = 1<<19;
104 }
105 for j := 1; j <= maxb; j<<=1 {
Russ Coxda0a7d72008-12-19 03:13:39 -0800106 n := len(b);
Russ Coxb014be72009-06-05 10:59:37 -0700107 max := uintptr(1<<28);
Rob Pikec45d2a72009-01-09 13:42:46 -0800108 if !*longtest {
Russ Coxebd27d62009-10-09 11:18:32 -0700109 max = uintptr(maxb);
Russ Coxda0a7d72008-12-19 03:13:39 -0800110 }
Russ Coxb014be72009-06-05 10:59:37 -0700111 if uintptr(j)*uintptr(n) > max {
112 n = int(max / uintptr(j));
Russ Coxda0a7d72008-12-19 03:13:39 -0800113 }
114 if n < 10 {
115 n = 10;
116 }
117 for m := 1; m <= n; {
118 AllocAndFree(j, m);
119 if m == n {
120 break
121 }
122 m = 5*m/4;
123 if m < 4 {
124 m++
125 }
126 if m > n {
127 m = n
128 }
129 }
130 }
131}