/src/brpc/src/butil/object_pool.h
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. 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 | | // bthread - An M:N threading library to make applications more concurrent. |
19 | | |
20 | | // Date: Sun Jul 13 15:04:18 CST 2014 |
21 | | |
22 | | #ifndef BUTIL_OBJECT_POOL_H |
23 | | #define BUTIL_OBJECT_POOL_H |
24 | | |
25 | | #include <cstddef> // size_t |
26 | | #include "butil/type_traits.h" |
27 | | |
28 | | // ObjectPool is a derivative class of ResourcePool to allocate and |
29 | | // reuse fixed-size objects without identifiers. |
30 | | |
31 | | namespace butil { |
32 | | |
33 | | // Specialize following classes to override default parameters for type T. |
34 | | // namespace butil { |
35 | | // template <> struct ObjectPoolBlockMaxSize<Foo> { |
36 | | // static const size_t value = 1024; |
37 | | // }; |
38 | | // } |
39 | | |
40 | | // Memory is allocated in blocks, memory size of a block will not exceed: |
41 | | // min(ObjectPoolBlockMaxSize<T>::value, |
42 | | // ObjectPoolBlockMaxItem<T>::value * sizeof(T)) |
43 | | template <typename T> struct ObjectPoolBlockMaxSize { |
44 | | static const size_t value = 64 * 1024; // bytes |
45 | | }; |
46 | | template <typename T> struct ObjectPoolBlockMaxItem { |
47 | | static const size_t value = 256; |
48 | | }; |
49 | | |
50 | | // Free objects of each thread are grouped into a chunk before they are merged |
51 | | // to the global list. Memory size of objects in one free chunk will not exceed: |
52 | | // min(ObjectPoolFreeChunkMaxItem<T>::value() * sizeof(T), |
53 | | // ObjectPoolBlockMaxSize<T>::value, |
54 | | // ObjectPoolBlockMaxItem<T>::value * sizeof(T)) |
55 | | template <typename T> struct ObjectPoolFreeChunkMaxItem { |
56 | 0 | static size_t value() { return 256; } Unexecuted instantiation: butil::ObjectPoolFreeChunkMaxItem<bthread::SampledContention>::value() Unexecuted instantiation: butil::ObjectPoolFreeChunkMaxItem<logging::LogRequest>::value() Unexecuted instantiation: butil::ObjectPoolFreeChunkMaxItem<butil::IOBufSample>::value() Unexecuted instantiation: butil::ObjectPoolFreeChunkMaxItem<bthread::Butex>::value() |
57 | | }; |
58 | | |
59 | | // ObjectPool calls this function on newly constructed objects. If this |
60 | | // function returns false, the object is destructed immediately and |
61 | | // get_object() shall return NULL. This is useful when the constructor |
62 | | // failed internally(namely ENOMEM). |
63 | | template <typename T> struct ObjectPoolValidator { |
64 | 0 | static bool validate(const T*) { return true; } Unexecuted instantiation: butil::ObjectPoolValidator<bthread::SampledContention>::validate(bthread::SampledContention const*) Unexecuted instantiation: butil::ObjectPoolValidator<logging::LogRequest>::validate(logging::LogRequest const*) Unexecuted instantiation: butil::ObjectPoolValidator<butil::IOBufSample>::validate(butil::IOBufSample const*) Unexecuted instantiation: butil::ObjectPoolValidator<bthread::Butex>::validate(bthread::Butex const*) |
65 | | }; |
66 | | |
67 | | // |
68 | | template <typename T> |
69 | | struct ObjectPoolWithASanPoison : true_type {}; |
70 | | |
71 | | } // namespace butil |
72 | | |
73 | | #include "butil/object_pool_inl.h" |
74 | | |
75 | | namespace butil { |
76 | | |
77 | | // Whether if FreeChunk of LocalPool is empty. |
78 | 0 | template <typename T> inline bool local_pool_free_empty() { |
79 | 0 | return ObjectPool<T>::singleton()->local_free_empty(); |
80 | 0 | } |
81 | | |
82 | | // Get an object typed |T|. The object should be cleared before usage. |
83 | | // NOTE: If there are no arguments, T must be default-constructible. |
84 | | template <typename T, typename... Args> |
85 | 0 | inline T* get_object(Args&&... args) { |
86 | 0 | return ObjectPool<T>::singleton()->get_object(std::forward<Args>(args)...); |
87 | 0 | } Unexecuted instantiation: bthread::SampledContention* butil::get_object<bthread::SampledContention>() Unexecuted instantiation: bthread::StackFactory<bthread::SmallStackClass>::Wrapper* butil::get_object<bthread::StackFactory<bthread::SmallStackClass>::Wrapper, void (*&)(long)>(void (*&)(long)) Unexecuted instantiation: bthread::StackFactory<bthread::NormalStackClass>::Wrapper* butil::get_object<bthread::StackFactory<bthread::NormalStackClass>::Wrapper, void (*&)(long)>(void (*&)(long)) Unexecuted instantiation: bthread::StackFactory<bthread::LargeStackClass>::Wrapper* butil::get_object<bthread::StackFactory<bthread::LargeStackClass>::Wrapper, void (*&)(long)>(void (*&)(long)) Unexecuted instantiation: logging::LogRequest* butil::get_object<logging::LogRequest>() Unexecuted instantiation: butil::IOBufSample* butil::get_object<butil::IOBufSample>() Unexecuted instantiation: bthread::Butex* butil::get_object<bthread::Butex>() |
88 | | |
89 | | // Return the object |ptr| back. The object is NOT destructed and will be |
90 | | // returned by later get_object<T>. Similar with free/delete, validity of |
91 | | // the object is not checked, user shall not return a not-yet-allocated or |
92 | | // already-returned object otherwise behavior is undefined. |
93 | | // Returns 0 when successful, -1 otherwise. |
94 | 0 | template <typename T> inline int return_object(T* ptr) { |
95 | 0 | return ObjectPool<T>::singleton()->return_object(ptr); |
96 | 0 | } Unexecuted instantiation: int butil::return_object<bthread::SampledContention>(bthread::SampledContention*) Unexecuted instantiation: int butil::return_object<bthread::StackFactory<bthread::SmallStackClass>::Wrapper>(bthread::StackFactory<bthread::SmallStackClass>::Wrapper*) Unexecuted instantiation: int butil::return_object<bthread::StackFactory<bthread::NormalStackClass>::Wrapper>(bthread::StackFactory<bthread::NormalStackClass>::Wrapper*) Unexecuted instantiation: int butil::return_object<bthread::StackFactory<bthread::LargeStackClass>::Wrapper>(bthread::StackFactory<bthread::LargeStackClass>::Wrapper*) Unexecuted instantiation: int butil::return_object<logging::LogRequest>(logging::LogRequest*) Unexecuted instantiation: int butil::return_object<butil::IOBufSample>(butil::IOBufSample*) Unexecuted instantiation: int butil::return_object<bthread::Butex>(bthread::Butex*) |
97 | | |
98 | | // Reclaim all allocated objects typed T if caller is the last thread called |
99 | | // this function, otherwise do nothing. You rarely need to call this function |
100 | | // manually because it's called automatically when each thread quits. |
101 | | template <typename T> inline void clear_objects() { |
102 | | ObjectPool<T>::singleton()->clear_objects(); |
103 | | } |
104 | | |
105 | | // Get description of objects typed T. |
106 | | // This function is possibly slow because it iterates internal structures. |
107 | | // Don't use it frequently like a "getter" function. |
108 | | template <typename T> ObjectPoolInfo describe_objects() { |
109 | | return ObjectPool<T>::singleton()->describe_objects(); |
110 | | } |
111 | | |
112 | | } // namespace butil |
113 | | |
114 | | #endif // BUTIL_OBJECT_POOL_H |