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
;
35 int next_discardable_shared_memory_id
= 0;
37 for (size_t i
= 0; i
< kSegments
; ++i
) {
38 scoped_ptr
<base::DiscardableSharedMemory
> memory(
39 new base::DiscardableSharedMemory
);
40 ASSERT_TRUE(memory
->CreateAndMap(segment_size
));
41 heap
.MergeIntoFreeLists(heap
.Grow(memory
.Pass(), segment_size
,
42 next_discardable_shared_memory_id
++,
43 base::Bind(NullTask
)).Pass());
47 // Use kSeed as seed for random number generator.
50 // Pre-compute random values.
51 int random_span
[kTimeCheckInterval
];
52 size_t random_blocks
[kTimeCheckInterval
];
53 for (int i
= 0; i
< kTimeCheckInterval
; ++i
) {
54 random_span
[i
] = std::rand();
55 // Exponentially distributed block size.
56 const double kLambda
= 2.0;
57 double v
= static_cast<double>(std::rand()) / RAND_MAX
;
58 random_blocks
[i
] = 1 + log(1.0 - v
) / -kLambda
* kBlocks
;
61 ScopedVector
<base::ScopedClosureRunner
> spans
;
63 base::TimeTicks start
= base::TimeTicks::Now();
64 base::TimeTicks end
= start
+ base::TimeDelta::FromMilliseconds(kTimeLimitMs
);
65 base::TimeDelta accumulator
;
68 for (int i
= 0; i
< kTimeCheckInterval
; ++i
) {
69 // Search for a perfect fit if greater than kBlocks.
71 random_blocks
[i
] < kBlocks
? kBlocks
- random_blocks
[i
] : 0;
72 scoped_ptr
<DiscardableSharedMemoryHeap::Span
> span
=
73 heap
.SearchFreeLists(random_blocks
[i
], slack
);
75 spans
.push_back(new base::ScopedClosureRunner(
76 base::Bind(&DiscardableSharedMemoryHeap::MergeIntoFreeLists
,
77 base::Unretained(&heap
), base::Passed(&span
))));
78 } else if (!spans
.empty()) {
79 // Merge a random span back into the free list.
80 std::swap(spans
[random_span
[i
] % spans
.size()], spans
.back());
87 base::TimeTicks now
= base::TimeTicks::Now();
88 accumulator
+= now
- start
;
94 perf_test::PrintResult("search_free_list", "", "",
95 count
/ accumulator
.InSecondsF(), "runs/s", true);
99 } // namespace content