[Session restore] Rename group name Enabled to Restore.
[chromium-blink-merge.git] / third_party / tcmalloc / chromium / src / tests / sampler_test.cc
blobc55d5dceafaa6a9ed699ceb68da8be2f11ad14a9
1 // Copyright (c) 2008, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
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
13 // distribution.
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.
17 //
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.
30 // ---
31 // All Rights Reserved.
33 // Author: Daniel Ford
35 // Checks basic properties of the sampler
37 #include "config_for_unittests.h"
38 #include <stdlib.h> // defines posix_memalign
39 #include <stdio.h> // for the printf at the end
40 #if defined HAVE_STDINT_H
41 #include <stdint.h> // to get uintptr_t
42 #elif defined HAVE_INTTYPES_H
43 #include <inttypes.h> // another place uintptr_t might be defined
44 #endif
45 #include <sys/types.h>
46 #include <iostream>
47 #include <algorithm>
48 #include <vector>
49 #include <string>
50 #include <cmath>
51 #include "base/logging.h"
52 #include "base/commandlineflags.h"
53 #include "sampler.h" // The Sampler class being tested
55 using std::sort;
56 using std::min;
57 using std::max;
58 using std::vector;
59 using std::abs;
61 vector<void (*)()> g_testlist; // the tests to run
63 #define TEST(a, b) \
64 struct Test_##a##_##b { \
65 Test_##a##_##b() { g_testlist.push_back(&Run); } \
66 static void Run(); \
67 }; \
68 static Test_##a##_##b g_test_##a##_##b; \
69 void Test_##a##_##b::Run()
72 static int RUN_ALL_TESTS() {
73 vector<void (*)()>::const_iterator it;
74 for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
75 (*it)(); // The test will error-exit if there's a problem.
77 fprintf(stderr, "\nPassed %d tests\n\nPASS\n", (int)g_testlist.size());
78 return 0;
81 #undef LOG // defined in base/logging.h
82 // Ideally, we'd put the newline at the end, but this hack puts the
83 // newline at the end of the previous log message, which is good enough :-)
84 #define LOG(level) std::cerr << "\n"
86 static std::string StringPrintf(const char* format, ...) {
87 char buf[256]; // should be big enough for all logging
88 va_list ap;
89 va_start(ap, format);
90 perftools_vsnprintf(buf, sizeof(buf), format, ap);
91 va_end(ap);
92 return buf;
95 namespace {
96 template<typename T> class scoped_array {
97 public:
98 scoped_array(T* p) : p_(p) { }
99 ~scoped_array() { delete[] p_; }
100 const T* get() const { return p_; }
101 T* get() { return p_; }
102 T& operator[](int i) { return p_[i]; }
103 private:
104 T* p_;
108 // Note that these tests are stochastic.
109 // This mean that the chance of correct code passing the test is,
110 // in the case of 5 standard deviations:
111 // kSigmas=5: ~99.99994267%
112 // in the case of 4 standard deviations:
113 // kSigmas=4: ~99.993666%
114 static const double kSigmas = 4;
115 static const size_t kSamplingInterval = 512*1024;
117 // Tests that GetSamplePeriod returns the expected value
118 // which is 1<<19
119 TEST(Sampler, TestGetSamplePeriod) {
120 tcmalloc::Sampler sampler;
121 sampler.Init(1);
122 uint64_t sample_period;
123 sample_period = sampler.GetSamplePeriod();
124 CHECK_GT(sample_period, 0);
127 // Tests of the quality of the random numbers generated
128 // This uses the Anderson Darling test for uniformity.
129 // See "Evaluating the Anderson-Darling Distribution" by Marsaglia
130 // for details.
132 // Short cut version of ADinf(z), z>0 (from Marsaglia)
133 // This returns the p-value for Anderson Darling statistic in
134 // the limit as n-> infinity. For finite n, apply the error fix below.
135 double AndersonDarlingInf(double z) {
136 if (z < 2) {
137 return exp(-1.2337141 / z) / sqrt(z) * (2.00012 + (0.247105 -
138 (0.0649821 - (0.0347962 - (0.011672 - 0.00168691
139 * z) * z) * z) * z) * z);
141 return exp( - exp(1.0776 - (2.30695 - (0.43424 - (0.082433 -
142 (0.008056 - 0.0003146 * z) * z) * z) * z) * z));
145 // Corrects the approximation error in AndersonDarlingInf for small values of n
146 // Add this to AndersonDarlingInf to get a better approximation
147 // (from Marsaglia)
148 double AndersonDarlingErrFix(int n, double x) {
149 if (x > 0.8) {
150 return (-130.2137 + (745.2337 - (1705.091 - (1950.646 -
151 (1116.360 - 255.7844 * x) * x) * x) * x) * x) / n;
153 double cutoff = 0.01265 + 0.1757 / n;
154 double t;
155 if (x < cutoff) {
156 t = x / cutoff;
157 t = sqrt(t) * (1 - t) * (49 * t - 102);
158 return t * (0.0037 / (n * n) + 0.00078 / n + 0.00006) / n;
159 } else {
160 t = (x - cutoff) / (0.8 - cutoff);
161 t = -0.00022633 + (6.54034 - (14.6538 - (14.458 - (8.259 - 1.91864
162 * t) * t) * t) * t) * t;
163 return t * (0.04213 + 0.01365 / n) / n;
167 // Returns the AndersonDarling p-value given n and the value of the statistic
168 double AndersonDarlingPValue(int n, double z) {
169 double ad = AndersonDarlingInf(z);
170 double errfix = AndersonDarlingErrFix(n, ad);
171 return ad + errfix;
174 double AndersonDarlingStatistic(int n, double* random_sample) {
175 double ad_sum = 0;
176 for (int i = 0; i < n; i++) {
177 ad_sum += (2*i + 1) * log(random_sample[i] * (1 - random_sample[n-1-i]));
179 double ad_statistic = - n - 1/static_cast<double>(n) * ad_sum;
180 return ad_statistic;
183 // Tests if the array of doubles is uniformly distributed.
184 // Returns the p-value of the Anderson Darling Statistic
185 // for the given set of sorted random doubles
186 // See "Evaluating the Anderson-Darling Distribution" by
187 // Marsaglia and Marsaglia for details.
188 double AndersonDarlingTest(int n, double* random_sample) {
189 double ad_statistic = AndersonDarlingStatistic(n, random_sample);
190 LOG(INFO) << StringPrintf("AD stat = %f, n=%d\n", ad_statistic, n);
191 double p = AndersonDarlingPValue(n, ad_statistic);
192 return p;
195 // Test the AD Test. The value of the statistic should go to zero as n->infty
196 // Not run as part of regular tests
197 void ADTestTest(int n) {
198 scoped_array<double> random_sample(new double[n]);
199 for (int i = 0; i < n; i++) {
200 random_sample[i] = (i+0.01)/n;
202 sort(random_sample.get(), random_sample.get() + n);
203 double ad_stat = AndersonDarlingStatistic(n, random_sample.get());
204 LOG(INFO) << StringPrintf("Testing the AD test. n=%d, ad_stat = %f",
205 n, ad_stat);
208 // Print the CDF of the distribution of the Anderson-Darling Statistic
209 // Used for checking the Anderson-Darling Test
210 // Not run as part of regular tests
211 void ADCDF() {
212 for (int i = 1; i < 40; i++) {
213 double x = i/10.0;
214 LOG(INFO) << "x= " << x << " adpv= "
215 << AndersonDarlingPValue(100, x) << ", "
216 << AndersonDarlingPValue(1000, x);
220 // Testing that NextRandom generates uniform
221 // random numbers.
222 // Applies the Anderson-Darling test for uniformity
223 void TestNextRandom(int n) {
224 tcmalloc::Sampler sampler;
225 sampler.Init(1);
226 uint64_t x = 1;
227 // This assumes that the prng returns 48 bit numbers
228 uint64_t max_prng_value = static_cast<uint64_t>(1)<<48;
229 // Initialize
230 for (int i = 1; i <= 20; i++) { // 20 mimics sampler.Init()
231 x = sampler.NextRandom(x);
233 scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
234 // Collect samples
235 for (int i = 0; i < n; i++) {
236 int_random_sample[i] = x;
237 x = sampler.NextRandom(x);
239 // First sort them...
240 sort(int_random_sample.get(), int_random_sample.get() + n);
241 scoped_array<double> random_sample(new double[n]);
242 // Convert them to uniform randoms (in the range [0,1])
243 for (int i = 0; i < n; i++) {
244 random_sample[i] = static_cast<double>(int_random_sample[i])/max_prng_value;
246 // Now compute the Anderson-Darling statistic
247 double ad_pvalue = AndersonDarlingTest(n, random_sample.get());
248 LOG(INFO) << StringPrintf("pvalue for AndersonDarlingTest "
249 "with n= %d is p= %f\n", n, ad_pvalue);
250 CHECK_GT(min(ad_pvalue, 1 - ad_pvalue), 0.0001);
251 // << StringPrintf("prng is not uniform, %d\n", n);
255 TEST(Sampler, TestNextRandom_MultipleValues) {
256 TestNextRandom(10); // Check short-range correlation
257 TestNextRandom(100);
258 TestNextRandom(1000);
259 TestNextRandom(10000); // Make sure there's no systematic error
262 // Tests that PickNextSamplePeriod generates
263 // geometrically distributed random numbers.
264 // First converts to uniforms then applied the
265 // Anderson-Darling test for uniformity.
266 void TestPickNextSample(int n) {
267 tcmalloc::Sampler sampler;
268 sampler.Init(1);
269 scoped_array<uint64_t> int_random_sample(new uint64_t[n]);
270 int sample_period = sampler.GetSamplePeriod();
271 int ones_count = 0;
272 for (int i = 0; i < n; i++) {
273 int_random_sample[i] = sampler.PickNextSamplingPoint();
274 CHECK_GE(int_random_sample[i], 1);
275 if (int_random_sample[i] == 1) {
276 ones_count += 1;
278 CHECK_LT(ones_count, 4); // << " out of " << i << " samples.";
280 // First sort them...
281 sort(int_random_sample.get(), int_random_sample.get() + n);
282 scoped_array<double> random_sample(new double[n]);
283 // Convert them to uniform random numbers
284 // by applying the geometric CDF
285 for (int i = 0; i < n; i++) {
286 random_sample[i] = 1 - exp(-static_cast<double>(int_random_sample[i])
287 / sample_period);
289 // Now compute the Anderson-Darling statistic
290 double geom_ad_pvalue = AndersonDarlingTest(n, random_sample.get());
291 LOG(INFO) << StringPrintf("pvalue for geometric AndersonDarlingTest "
292 "with n= %d is p= %f\n", n, geom_ad_pvalue);
293 CHECK_GT(min(geom_ad_pvalue, 1 - geom_ad_pvalue), 0.0001);
294 // << "PickNextSamplingPoint does not produce good "
295 // "geometric/exponential random numbers\n";
298 TEST(Sampler, TestPickNextSample_MultipleValues) {
299 TestPickNextSample(10); // Make sure the first few are good (enough)
300 TestPickNextSample(100);
301 TestPickNextSample(1000);
302 TestPickNextSample(10000); // Make sure there's no systematic error
306 // This is superceeded by the Anderson-Darling Test
307 // and it not run now.
308 // Tests how fast nearby values are spread out with LRand64
309 // The purpose of this code is to determine how many
310 // steps to apply to the seed during initialization
311 void TestLRand64Spread() {
312 tcmalloc::Sampler sampler;
313 sampler.Init(1);
314 uint64_t current_value;
315 printf("Testing LRand64 Spread\n");
316 for (int i = 1; i < 10; i++) {
317 printf("%d ", i);
318 current_value = i;
319 for (int j = 1; j < 100; j++) {
320 current_value = sampler.NextRandom(current_value);
322 LOG(INFO) << current_value;
327 // Test for Fastlog2 code
328 // We care about the percentage error because we're using this
329 // for choosing step sizes, so "close" is relative to the size of
330 // the step we would get if we used the built-in log function
331 TEST(Sampler, FastLog2) {
332 tcmalloc::Sampler sampler;
333 sampler.Init(1);
334 double max_ratio_error = 0;
335 for (double d = -1021.9; d < 1; d+= 0.13124235) {
336 double e = pow(2.0, d);
337 double truelog = log(e) / log(2.0); // log_2(e)
338 double fastlog = sampler.FastLog2(e);
339 max_ratio_error = max(max_ratio_error,
340 max(truelog/fastlog-1, fastlog/truelog-1));
341 CHECK_LE(max_ratio_error, 0.01);
342 // << StringPrintf("d = %f, e=%f, truelog = %f, fastlog= %f\n",
343 // d, e, truelog, fastlog);
345 LOG(INFO) << StringPrintf("Fastlog2: max_ratio_error = %f\n",
346 max_ratio_error);
349 // Futher tests
351 bool CheckMean(size_t mean, int num_samples) {
352 tcmalloc::Sampler sampler;
353 sampler.Init(1);
354 size_t total = 0;
355 for (int i = 0; i < num_samples; i++) {
356 total += sampler.PickNextSamplingPoint();
358 double empirical_mean = total / static_cast<double>(num_samples);
359 double expected_sd = mean / pow(num_samples * 1.0, 0.5);
360 return(fabs(mean-empirical_mean) < expected_sd * kSigmas);
363 // Prints a sequence so you can look at the distribution
364 void OutputSequence(int sequence_length) {
365 tcmalloc::Sampler sampler;
366 sampler.Init(1);
367 size_t next_step;
368 for (int i = 0; i< sequence_length; i++) {
369 next_step = sampler.PickNextSamplingPoint();
370 LOG(INFO) << next_step;
375 double StandardDeviationsErrorInSample(
376 int total_samples, int picked_samples,
377 int alloc_size, int sampling_interval) {
378 double p = 1 - exp(-(static_cast<double>(alloc_size) / sampling_interval));
379 double expected_samples = total_samples * p;
380 double sd = pow(p*(1-p)*total_samples, 0.5);
381 return((picked_samples - expected_samples) / sd);
384 TEST(Sampler, LargeAndSmallAllocs_CombinedTest) {
385 tcmalloc::Sampler sampler;
386 sampler.Init(1);
387 int counter_big = 0;
388 int counter_small = 0;
389 int size_big = 129*8*1024+1;
390 int size_small = 1024*8;
391 int num_iters = 128*4*8;
392 // Allocate in mixed chunks
393 for (int i = 0; i < num_iters; i++) {
394 if (sampler.SampleAllocation(size_big)) {
395 counter_big += 1;
397 for (int i = 0; i < 129; i++) {
398 if (sampler.SampleAllocation(size_small)) {
399 counter_small += 1;
403 // Now test that there are the right number of each
404 double large_allocs_sds =
405 StandardDeviationsErrorInSample(num_iters, counter_big,
406 size_big, kSamplingInterval);
407 double small_allocs_sds =
408 StandardDeviationsErrorInSample(num_iters*129, counter_small,
409 size_small, kSamplingInterval);
410 LOG(INFO) << StringPrintf("large_allocs_sds = %f\n", large_allocs_sds);
411 LOG(INFO) << StringPrintf("small_allocs_sds = %f\n", small_allocs_sds);
412 CHECK_LE(fabs(large_allocs_sds), kSigmas);
413 CHECK_LE(fabs(small_allocs_sds), kSigmas);
416 // Tests whether the mean is about right over 1000 samples
417 TEST(Sampler, IsMeanRight) {
418 CHECK(CheckMean(kSamplingInterval, 1000));
421 // This flag is for the OldSampler class to use
422 const int64 FLAGS_mock_tcmalloc_sample_parameter = 1<<19;
424 // A cut down and slightly refactored version of the old Sampler
425 class OldSampler {
426 public:
427 void Init(uint32_t seed);
428 void Cleanup() {}
430 // Record allocation of "k" bytes. Return true iff allocation
431 // should be sampled
432 bool SampleAllocation(size_t k);
434 // Generate a geometric with mean 1M (or FLAG value)
435 void PickNextSample(size_t k);
437 // Initialize the statics for the Sample class
438 static void InitStatics() {
439 sample_period = 1048583;
441 size_t bytes_until_sample_;
443 private:
444 uint32_t rnd_; // Cheap random number generator
445 static uint64_t sample_period;
446 // Should be a prime just above a power of 2:
447 // 2, 5, 11, 17, 37, 67, 131, 257,
448 // 521, 1031, 2053, 4099, 8209, 16411,
449 // 32771, 65537, 131101, 262147, 524309, 1048583,
450 // 2097169, 4194319, 8388617, 16777259, 33554467
453 // Statics for OldSampler
454 uint64_t OldSampler::sample_period;
456 void OldSampler::Init(uint32_t seed) {
457 // Initialize PRNG -- run it for a bit to get to good values
458 if (seed != 0) {
459 rnd_ = seed;
460 } else {
461 rnd_ = 12345;
463 bytes_until_sample_ = 0;
464 for (int i = 0; i < 100; i++) {
465 PickNextSample(sample_period * 2);
469 // A cut-down version of the old PickNextSampleRoutine
470 void OldSampler::PickNextSample(size_t k) {
471 // Make next "random" number
472 // x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers
473 static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0);
474 uint32_t r = rnd_;
475 rnd_ = (r << 1) ^ ((static_cast<int32_t>(r) >> 31) & kPoly);
477 // Next point is "rnd_ % (sample_period)". I.e., average
478 // increment is "sample_period/2".
479 const int flag_value = FLAGS_mock_tcmalloc_sample_parameter;
480 static int last_flag_value = -1;
482 if (flag_value != last_flag_value) {
483 // There should be a spinlock here, but this code is
484 // for benchmarking only.
485 sample_period = 1048583;
486 last_flag_value = flag_value;
489 bytes_until_sample_ += rnd_ % sample_period;
491 if (k > (static_cast<size_t>(-1) >> 2)) {
492 // If the user has asked for a huge allocation then it is possible
493 // for the code below to loop infinitely. Just return (note that
494 // this throws off the sampling accuracy somewhat, but a user who
495 // is allocating more than 1G of memory at a time can live with a
496 // minor inaccuracy in profiling of small allocations, and also
497 // would rather not wait for the loop below to terminate).
498 return;
501 while (bytes_until_sample_ < k) {
502 // Increase bytes_until_sample_ by enough average sampling periods
503 // (sample_period >> 1) to allow us to sample past the current
504 // allocation.
505 bytes_until_sample_ += (sample_period >> 1);
508 bytes_until_sample_ -= k;
511 inline bool OldSampler::SampleAllocation(size_t k) {
512 if (bytes_until_sample_ < k) {
513 PickNextSample(k);
514 return true;
515 } else {
516 bytes_until_sample_ -= k;
517 return false;
521 // This checks that the stated maximum value for the
522 // tcmalloc_sample_parameter flag never overflows bytes_until_sample_
523 TEST(Sampler, bytes_until_sample_Overflow_Underflow) {
524 tcmalloc::Sampler sampler;
525 sampler.Init(1);
526 uint64_t one = 1;
527 // sample_parameter = 0; // To test the edge case
528 uint64_t sample_parameter_array[4] = {0, 1, one<<19, one<<58};
529 for (int i = 0; i < 4; i++) {
530 uint64_t sample_parameter = sample_parameter_array[i];
531 LOG(INFO) << "sample_parameter = " << sample_parameter;
532 double sample_scaling = - log(2.0) * sample_parameter;
533 // Take the top 26 bits as the random number
534 // (This plus the 1<<26 sampling bound give a max step possible of
535 // 1209424308 bytes.)
536 const uint64_t prng_mod_power = 48; // Number of bits in prng
538 // First, check the largest_prng value
539 uint64_t largest_prng_value = (static_cast<uint64_t>(1)<<48) - 1;
540 double q = (largest_prng_value >> (prng_mod_power - 26)) + 1.0;
541 LOG(INFO) << StringPrintf("q = %f\n", q);
542 LOG(INFO) << StringPrintf("FastLog2(q) = %f\n", sampler.FastLog2(q));
543 LOG(INFO) << StringPrintf("log2(q) = %f\n", log(q)/log(2.0));
544 // Replace min(sampler.FastLog2(q) - 26, 0.0) with
545 // (sampler.FastLog2(q) - 26.000705) when using that optimization
546 uint64_t smallest_sample_step
547 = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)
548 * sample_scaling + 1);
549 LOG(INFO) << "Smallest sample step is " << smallest_sample_step;
550 uint64_t cutoff = static_cast<uint64_t>(10)
551 * (sample_parameter/(one<<24) + 1);
552 LOG(INFO) << "Acceptable value is < " << cutoff;
553 // This checks that the answer is "small" and positive
554 CHECK_LE(smallest_sample_step, cutoff);
556 // Next, check with the smallest prng value
557 uint64_t smallest_prng_value = 0;
558 q = (smallest_prng_value >> (prng_mod_power - 26)) + 1.0;
559 LOG(INFO) << StringPrintf("q = %f\n", q);
560 // Replace min(sampler.FastLog2(q) - 26, 0.0) with
561 // (sampler.FastLog2(q) - 26.000705) when using that optimization
562 uint64_t largest_sample_step
563 = static_cast<uint64_t>(min(sampler.FastLog2(q) - 26, 0.0)
564 * sample_scaling + 1);
565 LOG(INFO) << "Largest sample step is " << largest_sample_step;
566 CHECK_LE(largest_sample_step, one<<63);
567 CHECK_GE(largest_sample_step, smallest_sample_step);
572 // Test that NextRand is in the right range. Unfortunately, this is a
573 // stochastic test which could miss problems.
574 TEST(Sampler, NextRand_range) {
575 tcmalloc::Sampler sampler;
576 sampler.Init(1);
577 uint64_t one = 1;
578 // The next number should be (one << 48) - 1
579 uint64_t max_value = (one << 48) - 1;
580 uint64_t x = (one << 55);
581 int n = 22; // 27;
582 LOG(INFO) << "Running sampler.NextRandom 1<<" << n << " times";
583 for (int i = 1; i <= (1<<n); i++) { // 20 mimics sampler.Init()
584 x = sampler.NextRandom(x);
585 CHECK_LE(x, max_value);
589 // Tests certain arithmetic operations to make sure they compute what we
590 // expect them too (for testing across different platforms)
591 TEST(Sampler, arithmetic_1) {
592 tcmalloc::Sampler sampler;
593 sampler.Init(1);
594 uint64_t rnd; // our 48 bit random number, which we don't trust
595 const uint64_t prng_mod_power = 48;
596 uint64_t one = 1;
597 rnd = one;
598 uint64_t max_value = (one << 48) - 1;
599 for (int i = 1; i <= (1>>27); i++) { // 20 mimics sampler.Init()
600 rnd = sampler.NextRandom(rnd);
601 CHECK_LE(rnd, max_value);
602 double q = (rnd >> (prng_mod_power - 26)) + 1.0;
603 CHECK_GE(q, 0); // << rnd << " " << prng_mod_power;
605 // Test some potentially out of bounds value for rnd
606 for (int i = 1; i <= 66; i++) {
607 rnd = one << i;
608 double q = (rnd >> (prng_mod_power - 26)) + 1.0;
609 LOG(INFO) << "rnd = " << rnd << " i=" << i << " q=" << q;
610 CHECK_GE(q, 0);
611 // << " rnd=" << rnd << " i=" << i << " prng_mod_power" << prng_mod_power;
615 void test_arithmetic(uint64_t rnd) {
616 const uint64_t prng_mod_power = 48; // Number of bits in prng
617 uint64_t shifted_rnd = rnd >> (prng_mod_power - 26);
618 CHECK_GE(shifted_rnd, 0);
619 CHECK_LT(shifted_rnd, (1<<26));
620 LOG(INFO) << shifted_rnd;
621 LOG(INFO) << static_cast<double>(shifted_rnd);
622 CHECK_GE(static_cast<double>(static_cast<uint32_t>(shifted_rnd)), 0);
623 // << " rnd=" << rnd << " srnd=" << shifted_rnd;
624 CHECK_GE(static_cast<double>(shifted_rnd), 0);
625 // << " rnd=" << rnd << " srnd=" << shifted_rnd;
626 double q = static_cast<double>(shifted_rnd) + 1.0;
627 CHECK_GT(q, 0);
630 // Tests certain arithmetic operations to make sure they compute what we
631 // expect them too (for testing across different platforms)
632 // know bad values under with -c dbg --cpu piii for _some_ binaries:
633 // rnd=227453640600554
634 // shifted_rnd=54229173
635 // (hard to reproduce)
636 TEST(Sampler, arithmetic_2) {
637 uint64_t rnd = 227453640600554LL;
638 test_arithmetic(rnd);
642 // It's not really a test, but it's good to know
643 TEST(Sample, size_of_class) {
644 tcmalloc::Sampler sampler;
645 sampler.Init(1);
646 LOG(INFO) << "Size of Sampler class is: " << sizeof(tcmalloc::Sampler);
647 LOG(INFO) << "Size of Sampler object is: " << sizeof(sampler);
650 // Make sure sampling is enabled, or the tests won't work right.
651 DECLARE_int64(tcmalloc_sample_parameter);
653 int main(int argc, char **argv) {
654 if (FLAGS_tcmalloc_sample_parameter == 0)
655 FLAGS_tcmalloc_sample_parameter = 524288;
656 return RUN_ALL_TESTS();