]>
git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/slab_test.cc
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2015 Cloudius Systems, Ltd.
21 * To compile: g++ -std=c++14 slab_test.cc
26 #include <seastar/core/slab.hh>
28 using namespace seastar
;
30 namespace bi
= boost::intrusive
;
32 static constexpr size_t max_object_size
= 1024*1024;
34 class item
: public slab_item_base
{
36 bi::list_member_hook
<> _cache_link
;
37 uint32_t _slab_page_index
;
39 item(uint32_t slab_page_index
) : _slab_page_index(slab_page_index
) {}
41 const uint32_t get_slab_page_index() {
42 return _slab_page_index
;
44 const bool is_unlocked() {
49 template<typename Item
>
50 static void free_vector(slab_allocator
<Item
>& slab
, std::vector
<item
*>& items
) {
51 for (auto item
: items
) {
56 static void test_allocation_1(const double growth_factor
, const unsigned slab_limit_size
) {
57 slab_allocator
<item
> slab(growth_factor
, slab_limit_size
, max_object_size
);
58 size_t size
= max_object_size
;
60 slab
.print_slab_classes();
62 std::vector
<item
*> items
;
64 assert(slab_limit_size
% size
== 0);
65 for (auto i
= 0u; i
< (slab_limit_size
/ size
); i
++) {
66 auto item
= slab
.create(size
);
67 items
.push_back(item
);
69 assert(slab
.create(size
) == nullptr);
71 free_vector
<item
>(slab
, items
);
72 std::cout
<< __FUNCTION__
<< " done!\n";
75 static void test_allocation_2(const double growth_factor
, const unsigned slab_limit_size
) {
76 slab_allocator
<item
> slab(growth_factor
, slab_limit_size
, max_object_size
);
79 std::vector
<item
*> items
;
81 auto allocations
= 0u;
83 auto item
= slab
.create(size
);
87 items
.push_back(item
);
91 auto class_size
= slab
.class_size(size
);
92 auto per_slab_page
= max_object_size
/ class_size
;
93 auto available_slab_pages
= slab_limit_size
/ max_object_size
;
94 assert(allocations
== (per_slab_page
* available_slab_pages
));
96 free_vector
<item
>(slab
, items
);
97 std::cout
<< __FUNCTION__
<< " done!\n";
100 static void test_allocation_with_lru(const double growth_factor
, const unsigned slab_limit_size
) {
101 bi::list
<item
, bi::member_hook
<item
, bi::list_member_hook
<>, &item::_cache_link
>> _cache
;
102 unsigned evictions
= 0;
104 slab_allocator
<item
> slab(growth_factor
, slab_limit_size
, max_object_size
,
105 [&](item
& item_ref
) { _cache
.erase(_cache
.iterator_to(item_ref
)); evictions
++; });
106 size_t size
= max_object_size
;
108 auto max
= slab_limit_size
/ max_object_size
;
109 for (auto i
= 0u; i
< max
* 1000; i
++) {
110 auto item
= slab
.create(size
);
111 assert(item
!= nullptr);
112 _cache
.push_front(*item
);
114 assert(evictions
== max
* 999);
118 std::cout
<< __FUNCTION__
<< " done!\n";
121 int main(int ac
, char** av
) {
122 test_allocation_1(1.25, 5*1024*1024);
123 test_allocation_2(1.07, 5*1024*1024); // 1.07 is the growth factor used by facebook.
124 test_allocation_with_lru(1.25, 5*1024*1024);