1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/discardable_shared_memory_heap.h"
11 #include "base/bind.h"
12 #include "base/callback_helpers.h"
13 #include "base/memory/discardable_shared_memory.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/process/process_metrics.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/perf/perf_test.h"
22 const int kTimeLimitMs
= 2000;
23 const int kTimeCheckInterval
= 8192;
28 TEST(DiscardableSharedMemoryHeapTest
, SearchFreeLists
) {
29 size_t block_size
= base::GetPageSize();
30 DiscardableSharedMemoryHeap
heap(block_size
);
32 const size_t kBlocks
= 4096;
33 const size_t kSegments
= 16;
34 size_t segment_size
= block_size
* kBlocks
;
36 for (size_t i
= 0; i
< kSegments
; ++i
) {
37 scoped_ptr
<base::DiscardableSharedMemory
> memory(
38 new base::DiscardableSharedMemory
);
39 ASSERT_TRUE(memory
->CreateAndMap(segment_size
));
40 heap
.MergeIntoFreeLists(
41 heap
.Grow(memory
.Pass(), segment_size
, base::Bind(NullTask
)).Pass());
45 // Use kSeed as seed for random number generator.
48 // Pre-compute random values.
49 int random_span
[kTimeCheckInterval
];
50 size_t random_blocks
[kTimeCheckInterval
];
51 for (int i
= 0; i
< kTimeCheckInterval
; ++i
) {
52 random_span
[i
] = std::rand();
53 // Exponentially distributed block size.
54 const double kLambda
= 2.0;
55 double v
= static_cast<double>(std::rand()) / RAND_MAX
;
56 random_blocks
[i
] = 1 + log(1.0 - v
) / -kLambda
* kBlocks
;
59 ScopedVector
<base::ScopedClosureRunner
> spans
;
61 base::TimeTicks start
= base::TimeTicks::Now();
62 base::TimeTicks end
= start
+ base::TimeDelta::FromMilliseconds(kTimeLimitMs
);
63 base::TimeDelta accumulator
;
66 for (int i
= 0; i
< kTimeCheckInterval
; ++i
) {
67 // Search for a perfect fit if greater than kBlocks.
69 random_blocks
[i
] < kBlocks
? kBlocks
- random_blocks
[i
] : 0;
70 scoped_ptr
<DiscardableSharedMemoryHeap::Span
> span
=
71 heap
.SearchFreeLists(random_blocks
[i
], slack
);
73 spans
.push_back(new base::ScopedClosureRunner(
74 base::Bind(&DiscardableSharedMemoryHeap::MergeIntoFreeLists
,
75 base::Unretained(&heap
), base::Passed(&span
))));
76 } else if (!spans
.empty()) {
77 // Merge a random span back into the free list.
78 std::swap(spans
[random_span
[i
] % spans
.size()], spans
.back());
85 base::TimeTicks now
= base::TimeTicks::Now();
86 accumulator
+= now
- start
;
92 perf_test::PrintResult("search_free_list", "", "",
93 count
/ accumulator
.InSecondsF(), "runs/s", true);
97 } // namespace content