Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
slab_pool.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_core/slab_pool.h
10 //! @brief Memory pool.
11 
12 #ifndef ROC_CORE_SLAB_POOL_H_
13 #define ROC_CORE_SLAB_POOL_H_
14 
16 #include "roc_core/attributes.h"
17 #include "roc_core/iarena.h"
18 #include "roc_core/ipool.h"
19 #include "roc_core/noncopyable.h"
21 #include "roc_core/stddefs.h"
22 
23 namespace roc {
24 namespace core {
25 
26 //! Memory pool guards.
28  //! Panic if leaks detected in pool destructor.
29  SlabPool_LeakGuard = (1 << 0),
30  //! Panic if detected buffer overflow when deallocating object.
32  //! Panic if detected ownership mismatch when deallocating object.
34 };
35 
36 //! Default memory pool guards.
37 enum {
38  SlabPool_DefaultGuards =
40 };
41 
42 //! Memory pool.
43 //!
44 //! Implements slab allocator algorithm. Allocates large chunks of memory ("slabs") from
45 //! given arena, and uses them for multiple smaller fixed-sized objects ("slots").
46 //!
47 //! Keeps track of free slots and uses them when possible. Automatically allocates new
48 //! slabs when there are no free slots available.
49 //!
50 //! Automatically grows size of new slabs exponentially. The user can also specify the
51 //! minimum and maximum limits for the slabs.
52 //!
53 //! The returned memory is always maximum-aligned.
54 //!
55 //! Implements three safety measures:
56 //! - to catch double-free and other logical bugs, inserts link to owning pool before
57 //! user data, and panics if it differs when memory is returned to pool
58 //! - to catch buffer overflow bugs, inserts "canary guards" before and after user
59 //! data, and panics if they are overwritten when memory is returned to pool
60 //! - to catch uninitialized-access and use-after-free bugs, "poisons" memory when it
61 //! returned to user, and when it returned back to the pool
62 //!
63 //! @tparam T defines pool object type. It is used to determine allocation size. If
64 //! runtime size is different from static size of T, it can be provided via constructor.
65 //!
66 //! @tparam EmbeddedCapacity defines number of slots embedded directly into SlabPool
67 //! instance. If non-zero, this memory will be used for first allocations, before
68 //! using memory arena.
69 //!
70 //! Thread-safe.
71 template <class T, size_t EmbeddedCapacity = 0>
72 class SlabPool : public IPool, public NonCopyable<> {
73 public:
74  //! Initialize.
75  //!
76  //! @b Parameters
77  //! - @p name defines pool name, used for logging
78  //! - @p arena is used to allocate slabs
79  //! - @p object_size defines size of single object in bytes
80  //! - @p min_alloc_bytes defines minimum size in bytes per request to arena
81  //! - @p max_alloc_bytes defines maximum size in bytes per request to arena
82  //! - @p guards defines options to modify behaviour as indicated in SlabPoolGuard
83  SlabPool(const char* name,
84  IArena& arena,
85  size_t object_size = sizeof(T),
86  size_t min_alloc_bytes = 0,
87  size_t max_alloc_bytes = 0,
88  size_t guards = SlabPool_DefaultGuards)
89  : impl_(name,
90  arena,
92  min_alloc_bytes,
93  max_alloc_bytes,
94  embedded_data_.memory(),
95  embedded_data_.size(),
96  guards) {
97  }
98 
99  //! Get size of the allocation per object.
100  virtual size_t allocation_size() const {
101  return impl_.allocation_size();
102  }
103 
104  //! Get size of the object.
105  virtual size_t object_size() const {
106  return impl_.object_size();
107  }
108 
109  //! Reserve memory for given number of objects.
110  virtual ROC_ATTR_NODISCARD bool reserve(size_t n_objects) {
111  return impl_.reserve(n_objects);
112  }
113 
114  //! Allocate memory for an object.
115  virtual void* allocate() {
116  return impl_.allocate();
117  }
118 
119  //! Return memory to pool.
120  virtual void deallocate(void* memory) {
121  impl_.deallocate(memory);
122  }
123 
124  //! Get number of guard failures detected.
125  size_t num_guard_failures() const {
126  return impl_.num_guard_failures();
127  }
128 
129 private:
130  enum {
131  SlotSize = (sizeof(SlabPoolImpl::SlotHeader) + sizeof(SlabPoolImpl::SlotCanary)
132  + sizeof(T) + sizeof(SlabPoolImpl::SlotCanary) + sizeof(AlignMax) - 1)
133  / sizeof(AlignMax) * sizeof(AlignMax)
134  };
135  AlignedStorage<EmbeddedCapacity * SlotSize> embedded_data_;
136  SlabPoolImpl impl_;
137 };
138 
139 } // namespace core
140 } // namespace roc
141 
142 #endif // ROC_CORE_SLAB_POOL_H_
Aligned storage.
Compiler attributes.
#define ROC_ATTR_NODISCARD
Emit warning if function result is not checked.
Definition: attributes.h:31
Memory arena interface.
Definition: iarena.h:23
Memory pool interface.
Definition: ipool.h:23
Base class for non-copyable objects.
Definition: noncopyable.h:23
ROC_ATTR_NODISCARD bool reserve(size_t n_objects)
Reserve memory for given number of objects.
void deallocate(void *memory)
Return memory to pool.
size_t object_size() const
Get size of the object.
size_t num_guard_failures() const
Get number of guard failures.
void * allocate()
Allocate memory for an object.
size_t allocation_size() const
Get size of the allocation per object.
Memory pool.
Definition: slab_pool.h:72
virtual size_t object_size() const
Get size of the object.
Definition: slab_pool.h:105
virtual void * allocate()
Allocate memory for an object.
Definition: slab_pool.h:115
size_t num_guard_failures() const
Get number of guard failures detected.
Definition: slab_pool.h:125
virtual ROC_ATTR_NODISCARD bool reserve(size_t n_objects)
Reserve memory for given number of objects.
Definition: slab_pool.h:110
virtual void deallocate(void *memory)
Return memory to pool.
Definition: slab_pool.h:120
SlabPool(const char *name, IArena &arena, size_t object_size=sizeof(T), size_t min_alloc_bytes=0, size_t max_alloc_bytes=0, size_t guards=SlabPool_DefaultGuards)
Initialize.
Definition: slab_pool.h:83
virtual size_t allocation_size() const
Get size of the allocation per object.
Definition: slab_pool.h:100
Memory arena interface.
Memory pool interface.
SlabPoolGuard
Memory pool guards.
Definition: slab_pool.h:27
@ SlabPool_LeakGuard
Panic if leaks detected in pool destructor.
Definition: slab_pool.h:29
@ SlabPool_OverflowGuard
Panic if detected buffer overflow when deallocating object.
Definition: slab_pool.h:31
@ SlabPool_OwnershipGuard
Panic if detected ownership mismatch when deallocating object.
Definition: slab_pool.h:33
Root namespace.
Non-copyable object.
Memory pool implementation class.
Commonly used types and functions.
Maximum aligned data unit.
Definition: align_ops.h:21