blob: eb67bed86babd26ed32a3eafb011cab54353bcf5 [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 (
Russ Cox33e396a2010-02-03 16:31:34 -080012 "flag"
13 "fmt"
14 "runtime"
Russ Coxda0a7d72008-12-19 03:13:39 -080015 "strconv"
16)
17
Russ Cox33e396a2010-02-03 16:31:34 -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 Cox33e396a2010-02-03 16:31:34 -080022var b []*byte
23var stats = &runtime.MemStats
Russ Coxda0a7d72008-12-19 03:13:39 -080024
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 {
Russ Cox33e396a2010-02-03 16:31:34 -080043 fmt.Printf("size=%d count=%d ...\n", size, count)
Russ Coxda0a7d72008-12-19 03:13:39 -080044 }
Russ Cox33e396a2010-02-03 16:31:34 -080045 n1 := stats.Alloc
Russ Coxda0a7d72008-12-19 03:13:39 -080046 for i := 0; i < count; i++ {
Russ Cox33e396a2010-02-03 16:31:34 -080047 b[i] = runtime.Alloc(uintptr(size))
48 base, n := runtime.Lookup(b[i])
Ian Lance Taylor03c40f52009-01-16 15:03:22 -080049 if base != b[i] || !OkAmount(uintptr(size), n) {
Rob Pike325cf8e2010-03-24 16:46:53 -070050 println("lookup failed: got", base, n, "for", b[i])
51 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080052 }
Russ Cox33e396a2010-02-03 16:31:34 -080053 if runtime.MemStats.Sys > 1e9 {
Rob Pike325cf8e2010-03-24 16:46:53 -070054 println("too much memory allocated")
55 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080056 }
57 }
Russ Cox33e396a2010-02-03 16:31:34 -080058 n2 := stats.Alloc
Rob Pikec45d2a72009-01-09 13:42:46 -080059 if *chatty {
Russ Cox33e396a2010-02-03 16:31:34 -080060 fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
Russ Coxda0a7d72008-12-19 03:13:39 -080061 }
Russ Cox33e396a2010-02-03 16:31:34 -080062 n3 := stats.Alloc
Russ Coxda0a7d72008-12-19 03:13:39 -080063 for j := 0; j < count; j++ {
Russ Cox33e396a2010-02-03 16:31:34 -080064 i := j
Rob Pikec45d2a72009-01-09 13:42:46 -080065 if *reverse {
Russ Cox33e396a2010-02-03 16:31:34 -080066 i = count - 1 - j
Russ Coxda0a7d72008-12-19 03:13:39 -080067 }
Russ Cox33e396a2010-02-03 16:31:34 -080068 alloc := uintptr(stats.Alloc)
69 base, n := runtime.Lookup(b[i])
Ian Lance Taylor03c40f52009-01-16 15:03:22 -080070 if base != b[i] || !OkAmount(uintptr(size), n) {
Rob Pike325cf8e2010-03-24 16:46:53 -070071 println("lookup failed: got", base, n, "for", b[i])
72 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080073 }
Russ Cox33e396a2010-02-03 16:31:34 -080074 runtime.Free(b[i])
75 if stats.Alloc != uint64(alloc-n) {
Rob Pike325cf8e2010-03-24 16:46:53 -070076 println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
77 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080078 }
Russ Cox33e396a2010-02-03 16:31:34 -080079 if runtime.MemStats.Sys > 1e9 {
Rob Pike325cf8e2010-03-24 16:46:53 -070080 println("too much memory allocated")
81 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080082 }
83 }
Russ Cox33e396a2010-02-03 16:31:34 -080084 n4 := stats.Alloc
Russ Coxda0a7d72008-12-19 03:13:39 -080085
Rob Pikec45d2a72009-01-09 13:42:46 -080086 if *chatty {
Russ Cox33e396a2010-02-03 16:31:34 -080087 fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
Russ Coxda0a7d72008-12-19 03:13:39 -080088 }
89 if n2-n1 != n3-n4 {
Rob Pike325cf8e2010-03-24 16:46:53 -070090 println("wrong alloc count: ", n2-n1, n3-n4)
91 panic("fail")
Russ Coxda0a7d72008-12-19 03:13:39 -080092 }
93}
94
95func atoi(s string) int {
Russ Cox33e396a2010-02-03 16:31:34 -080096 i, _ := strconv.Atoi(s)
Russ Coxda0a7d72008-12-19 03:13:39 -080097 return i
98}
99
100func main() {
Russ Cox6eb251f2010-03-24 09:40:09 -0700101 runtime.MemProfileRate = 0 // disable profiler
Russ Cox33e396a2010-02-03 16:31:34 -0800102 flag.Parse()
103 b = make([]*byte, 10000)
Russ Coxda0a7d72008-12-19 03:13:39 -0800104 if flag.NArg() > 0 {
Russ Cox33e396a2010-02-03 16:31:34 -0800105 AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)))
106 return
Russ Coxda0a7d72008-12-19 03:13:39 -0800107 }
Russ Cox33e396a2010-02-03 16:31:34 -0800108 maxb := 1 << 22
Russ Coxebd27d62009-10-09 11:18:32 -0700109 if !*longtest {
Russ Cox33e396a2010-02-03 16:31:34 -0800110 maxb = 1 << 19
Russ Coxebd27d62009-10-09 11:18:32 -0700111 }
Russ Cox33e396a2010-02-03 16:31:34 -0800112 for j := 1; j <= maxb; j <<= 1 {
113 n := len(b)
114 max := uintptr(1 << 28)
Rob Pikec45d2a72009-01-09 13:42:46 -0800115 if !*longtest {
Russ Cox33e396a2010-02-03 16:31:34 -0800116 max = uintptr(maxb)
Russ Coxda0a7d72008-12-19 03:13:39 -0800117 }
Russ Coxb014be72009-06-05 10:59:37 -0700118 if uintptr(j)*uintptr(n) > max {
Russ Cox33e396a2010-02-03 16:31:34 -0800119 n = int(max / uintptr(j))
Russ Coxda0a7d72008-12-19 03:13:39 -0800120 }
121 if n < 10 {
Russ Cox33e396a2010-02-03 16:31:34 -0800122 n = 10
Russ Coxda0a7d72008-12-19 03:13:39 -0800123 }
124 for m := 1; m <= n; {
Russ Cox33e396a2010-02-03 16:31:34 -0800125 AllocAndFree(j, m)
Russ Coxda0a7d72008-12-19 03:13:39 -0800126 if m == n {
127 break
128 }
Russ Cox33e396a2010-02-03 16:31:34 -0800129 m = 5 * m / 4
Russ Coxda0a7d72008-12-19 03:13:39 -0800130 if m < 4 {
131 m++
132 }
133 if m > n {
134 m = n
135 }
136 }
137 }
138}