blob: 26d28715b55063207de047739a5d66ed0c5ac305 [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
25func OkAmount(size, n uint64) bool {
26 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
41func AllocAndFree(size, count int) {
Rob Pikec45d2a72009-01-09 13:42:46 -080042 if *chatty {
Russ Coxda0a7d72008-12-19 03:13:39 -080043 fmt.printf("size=%d count=%d ...\n", size, count);
44 }
45 n1 := stats.alloc;
46 for i := 0; i < count; i++ {
47 b[i] = malloc.Alloc(uint64(size));
48 base, n := malloc.Lookup(b[i]);
49 if base != b[i] || !OkAmount(uint64(size), n) {
50 panicln("lookup failed: got", base, n, "for", b[i]);
51 }
52 if malloc.GetStats().sys > 1e9 {
53 panicln("too much memory allocated");
54 }
55 }
56 n2 := stats.alloc;
Rob Pikec45d2a72009-01-09 13:42:46 -080057 if *chatty {
Russ Coxda0a7d72008-12-19 03:13:39 -080058 fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
59 }
60 n3 := stats.alloc;
61 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 }
66 alloc := stats.alloc;
67 base, n := malloc.Lookup(b[i]);
68 if base != b[i] || !OkAmount(uint64(size), n) {
69 panicln("lookup failed: got", base, n, "for", b[i]);
70 }
71 malloc.Free(b[i]);
72 if stats.alloc != alloc - n {
73 panicln("free alloc got", stats.alloc, "expected", alloc - n, "after free of", n);
74 }
75 if malloc.GetStats().sys > 1e9 {
76 panicln("too much memory allocated");
77 }
78 }
79 n4 := stats.alloc;
80
Rob Pikec45d2a72009-01-09 13:42:46 -080081 if *chatty {
Russ Coxda0a7d72008-12-19 03:13:39 -080082 fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
83 }
84 if n2-n1 != n3-n4 {
85 panicln("wrong alloc count: ", n2-n1, n3-n4);
86 }
87}
88
89func atoi(s string) int {
90 i, xx1 := strconv.atoi(s);
91 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 }
101 for j := 1; j <= 1<<22; j<<=1 {
102 n := len(b);
103 max := uint64(1<<28);
Rob Pikec45d2a72009-01-09 13:42:46 -0800104 if !*longtest {
Russ Coxda0a7d72008-12-19 03:13:39 -0800105 max = 1<<22;
106 }
107 if uint64(j)*uint64(n) > max {
108 n = int(max / uint64(j));
109 }
110 if n < 10 {
111 n = 10;
112 }
113 for m := 1; m <= n; {
114 AllocAndFree(j, m);
115 if m == n {
116 break
117 }
118 m = 5*m/4;
119 if m < 4 {
120 m++
121 }
122 if m > n {
123 m = n
124 }
125 }
126 }
127}