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 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 25 | func OkAmount(size, n uintptr) bool { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 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 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 41 | func AllocAndFree(size, count int) { |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame] | 42 | if *chatty { |
Rob Pike | 61f3302 | 2009-01-15 13:48:11 -0800 | [diff] [blame] | 43 | fmt.Printf("size=%d count=%d ...\n", size, count); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 44 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 45 | n1 := stats.Alloc; |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 46 | for i := 0; i < count; i++ { |
Russ Cox | b014be7 | 2009-06-05 10:59:37 -0700 | [diff] [blame] | 47 | b[i] = malloc.Alloc(uintptr(size)); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 48 | base, n := malloc.Lookup(b[i]); |
Ian Lance Taylor | 03c40f5 | 2009-01-16 15:03:22 -0800 | [diff] [blame] | 49 | if base != b[i] || !OkAmount(uintptr(size), n) { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 50 | panicln("lookup failed: got", base, n, "for", b[i]); |
| 51 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 52 | if malloc.GetStats().Sys > 1e9 { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 53 | panicln("too much memory allocated"); |
| 54 | } |
| 55 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 56 | n2 := stats.Alloc; |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame] | 57 | if *chatty { |
Rob Pike | 61f3302 | 2009-01-15 13:48:11 -0800 | [diff] [blame] | 58 | fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 59 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 60 | n3 := stats.Alloc; |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 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 | } |
Russ Cox | b014be7 | 2009-06-05 10:59:37 -0700 | [diff] [blame] | 66 | alloc := uintptr(stats.Alloc); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 67 | base, n := malloc.Lookup(b[i]); |
Ian Lance Taylor | 03c40f5 | 2009-01-16 15:03:22 -0800 | [diff] [blame] | 68 | if base != b[i] || !OkAmount(uintptr(size), n) { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 69 | panicln("lookup failed: got", base, n, "for", b[i]); |
| 70 | } |
| 71 | malloc.Free(b[i]); |
Russ Cox | b014be7 | 2009-06-05 10:59:37 -0700 | [diff] [blame] | 72 | if stats.Alloc != uint64(alloc - n) { |
| 73 | panicln("free alloc got", stats.Alloc, "expected", alloc - n, "after free of", n); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 74 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 75 | if malloc.GetStats().Sys > 1e9 { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 76 | panicln("too much memory allocated"); |
| 77 | } |
| 78 | } |
Russ Cox | f48cbfd | 2009-01-16 16:12:14 -0800 | [diff] [blame] | 79 | n4 := stats.Alloc; |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 80 | |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame] | 81 | if *chatty { |
Rob Pike | 61f3302 | 2009-01-15 13:48:11 -0800 | [diff] [blame] | 82 | fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 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 { |
Russ Cox | ae54cf7 | 2009-09-15 12:42:24 -0700 | [diff] [blame] | 90 | i, _ := strconv.Atoi(s); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 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 | } |
Russ Cox | ebd27d6 | 2009-10-09 11:18:32 -0700 | [diff] [blame^] | 101 | maxb := 1<<22; |
| 102 | if !*longtest { |
| 103 | maxb = 1<<19; |
| 104 | } |
| 105 | for j := 1; j <= maxb; j<<=1 { |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 106 | n := len(b); |
Russ Cox | b014be7 | 2009-06-05 10:59:37 -0700 | [diff] [blame] | 107 | max := uintptr(1<<28); |
Rob Pike | c45d2a7 | 2009-01-09 13:42:46 -0800 | [diff] [blame] | 108 | if !*longtest { |
Russ Cox | ebd27d6 | 2009-10-09 11:18:32 -0700 | [diff] [blame^] | 109 | max = uintptr(maxb); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 110 | } |
Russ Cox | b014be7 | 2009-06-05 10:59:37 -0700 | [diff] [blame] | 111 | if uintptr(j)*uintptr(n) > max { |
| 112 | n = int(max / uintptr(j)); |
Russ Cox | da0a7d7 | 2008-12-19 03:13:39 -0800 | [diff] [blame] | 113 | } |
| 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 | } |