Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 1 | // $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 | |
| 9 | package main |
| 10 | |
| 11 | import ( |
| 12 | "flag"; |
| 13 | "fmt"; |
| 14 | "malloc"; |
| 15 | "strconv" |
| 16 | ) |
| 17 | |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 18 | var chatty = flag.Bool("v", false, "chatty"); |
| 19 | var reverse = flag.Bool("r", false, "reverse"); |
| 20 | var longtest = flag.Bool("l", false, "long test"); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 21 | |
Russ Cox | c3077f7 | 2008-12-19 17:11:54 -0800 | [diff] [blame] | 22 | var b []*byte; |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 23 | var stats = malloc.GetStats(); |
| 24 | |
| 25 | func 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 | |
| 41 | func AllocAndFree(size, count int) { |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 42 | if *chatty { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 43 | 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 Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 57 | if *chatty { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 58 | 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 Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 63 | if *reverse { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 64 | 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 Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 81 | if *chatty { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 82 | 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 | |
| 89 | func atoi(s string) int { |
| 90 | i, xx1 := strconv.atoi(s); |
| 91 | return i |
| 92 | } |
| 93 | |
| 94 | func main() { |
| 95 | flag.Parse(); |
Russ Cox | 5564504 | 2009-01-06 15:19:02 -0800 | [diff] [blame] | 96 | b = make([]*byte, 10000); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 97 | 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 Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame^] | 104 | if !*longtest { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 105 | 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 | } |