]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
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 | } |