]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/tests/unit/slab_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / tests / unit / slab_test.cc
1 /*
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.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2015 Cloudius Systems, Ltd.
20 *
21 * To compile: g++ -std=c++14 slab_test.cc
22 */
23
24 #include <iostream>
25 #include <assert.h>
26 #include <seastar/core/slab.hh>
27
28 using namespace seastar;
29
30 namespace bi = boost::intrusive;
31
32 static constexpr size_t max_object_size = 1024*1024;
33
34 class item : public slab_item_base {
35 public:
36 bi::list_member_hook<> _cache_link;
37 uint32_t _slab_page_index;
38
39 item(uint32_t slab_page_index) : _slab_page_index(slab_page_index) {}
40
41 const uint32_t get_slab_page_index() {
42 return _slab_page_index;
43 }
44 const bool is_unlocked() {
45 return true;
46 }
47 };
48
49 template<typename Item>
50 static void free_vector(slab_allocator<Item>& slab, std::vector<item *>& items) {
51 for (auto item : items) {
52 slab.free(item);
53 }
54 }
55
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;
59
60 slab.print_slab_classes();
61
62 std::vector<item *> items;
63
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);
68 }
69 assert(slab.create(size) == nullptr);
70
71 free_vector<item>(slab, items);
72 std::cout << __FUNCTION__ << " done!\n";
73 }
74
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);
77 size_t size = 1024;
78
79 std::vector<item *> items;
80
81 auto allocations = 0u;
82 for (;;) {
83 auto item = slab.create(size);
84 if (!item) {
85 break;
86 }
87 items.push_back(item);
88 allocations++;
89 }
90
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));
95
96 free_vector<item>(slab, items);
97 std::cout << __FUNCTION__ << " done!\n";
98 }
99
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;
103
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;
107
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);
113 }
114 assert(evictions == max * 999);
115
116 _cache.clear();
117
118 std::cout << __FUNCTION__ << " done!\n";
119 }
120
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);
125
126 return 0;
127 }