1 // Copyright (c) 2003, Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 // Author: Sanjay Ghemawat
33 // Test speed of handling fragmented heap
35 #include "config_for_unittests.h"
38 #ifdef HAVE_SYS_RESOURCE_H
39 #include <sys/time.h> // for struct timeval
40 #include <sys/resource.h> // for getrusage
43 #include <windows.h> // for GetTickCount()
46 #include "base/logging.h"
48 #include <gperftools/malloc_extension.h>
52 int main(int argc
, char** argv
) {
53 // Make kAllocSize one page larger than the maximum small object size.
54 static const int kAllocSize
= kMaxSize
+ kPageSize
;
55 // Allocate 400MB in total.
56 static const int kTotalAlloc
= 400 << 20;
57 static const int kAllocIterations
= kTotalAlloc
/ kAllocSize
;
59 // Allocate lots of objects
60 vector
<char*> saved(kAllocIterations
);
61 for (int i
= 0; i
< kAllocIterations
; i
++) {
62 saved
[i
] = new char[kAllocSize
];
65 // Check the current "slack".
67 MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
70 // Free alternating ones to fragment heap
71 size_t free_bytes
= 0;
72 for (int i
= 0; i
< saved
.size(); i
+= 2) {
74 free_bytes
+= kAllocSize
;
77 // Check that slack delta is within 10% of expected.
79 MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
81 CHECK_GE(slack_after
, slack_before
);
82 size_t slack
= slack_after
- slack_before
;
84 CHECK_GT(double(slack
), 0.9*free_bytes
);
85 CHECK_LT(double(slack
), 1.1*free_bytes
);
88 static const int kBufSize
= 1<<20;
89 char* buffer
= new char[kBufSize
];
90 MallocExtension::instance()->GetStats(buffer
, kBufSize
);
91 VLOG(1, "%s", buffer
);
94 // Now do timing tests
95 for (int i
= 0; i
< 5; i
++) {
96 static const int kIterations
= 100000;
97 #ifdef HAVE_SYS_RESOURCE_H
99 getrusage(RUSAGE_SELF
, &r
); // figure out user-time spent on this
100 struct timeval tv_start
= r
.ru_utime
;
101 #elif defined(_WIN32)
102 long long int tv_start
= GetTickCount();
104 # error No way to calculate time on your system
107 for (int i
= 0; i
< kIterations
; i
++) {
109 MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
113 #ifdef HAVE_SYS_RESOURCE_H
114 getrusage(RUSAGE_SELF
, &r
);
115 struct timeval tv_end
= r
.ru_utime
;
116 int64 sumsec
= static_cast<int64
>(tv_end
.tv_sec
) - tv_start
.tv_sec
;
117 int64 sumusec
= static_cast<int64
>(tv_end
.tv_usec
) - tv_start
.tv_usec
;
118 #elif defined(_WIN32)
119 long long int tv_end
= GetTickCount();
120 int64 sumsec
= (tv_end
- tv_start
) / 1000;
121 // Resolution in windows is only to the millisecond, alas
122 int64 sumusec
= ((tv_end
- tv_start
) % 1000) * 1000;
124 # error No way to calculate time on your system
126 fprintf(stderr
, "getproperty: %6.1f ns/call\n",
127 (sumsec
* 1e9
+ sumusec
* 1e3
) / kIterations
);