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 flags.
28  //! Enable guards for buffer overflow, invalid ownership, etc.
30 };
31 
32 //! Default memory pool flags.
33 enum { DefaultSlabPoolFlags = (SlabPoolFlag_EnableGuards) };
34 
35 //! Memory pool.
36 //!
37 //! Implements slab allocator algorithm. Allocates large chunks of memory ("slabs") from
38 //! given arena, and uses them for multiple smaller fixed-sized objects ("slots").
39 //!
40 //! Keeps track of free slots and uses them when possible. Automatically allocates new
41 //! slabs when there are no free slots available.
42 //!
43 //! Automatically grows size of new slabs exponentially. The user can also specify the
44 //! minimum and maximum limits for the slabs.
45 //!
46 //! The returned memory is always maximum-aligned.
47 //!
48 //! Implements three safety measures:
49 //! - to catch double-free and other logical bugs, inserts link to owning pool before
50 //! user data, and panics if it differs when memory is returned to pool
51 //! - to catch buffer overflow bugs, inserts "canary guards" before and after user
52 //! data, and panics if they are overwritten when memory is returned to pool
53 //! - to catch uninitialized-access and use-after-free bugs, "poisons" memory when it
54 //! returned to user, and when it returned back to the pool
55 //!
56 //! @tparam T defines pool object type. It is used to determine allocation size. If
57 //! runtime size is different from static size of T, it can be provided via constructor.
58 //!
59 //! @tparam EmbeddedCapacity defines number of slots embedded directly into SlabPool
60 //! instance. If non-zero, this memory will be used for first allocations, before
61 //! using memory arena.
62 //!
63 //! Thread-safe.
64 template <class T, size_t EmbeddedCapacity = 0>
65 class SlabPool : public IPool, public NonCopyable<> {
66 public:
67  //! Initialize.
68  //!
69  //! @b Parameters
70  //! - @p name defines pool name, used for logging
71  //! - @p arena is used to allocate slabs
72  //! - @p object_size defines size of single object in bytes
73  //! - @p min_alloc_bytes defines minimum size in bytes per request to arena
74  //! - @p max_alloc_bytes defines maximum size in bytes per request to arena
75  //! - @p flags defines options to modify behaviour as indicated in SlabPoolFlags
76  explicit SlabPool(const char* name,
77  IArena& arena,
78  size_t object_size = sizeof(T),
79  size_t min_alloc_bytes = 0,
80  size_t max_alloc_bytes = 0,
81  size_t flags = DefaultSlabPoolFlags)
82  : impl_(name,
83  arena,
85  min_alloc_bytes,
86  max_alloc_bytes,
87  embedded_data_.memory(),
88  embedded_data_.size(),
89  flags) {
90  }
91 
92  //! Get size of objects in pool.
93  size_t object_size() const {
94  return impl_.object_size();
95  }
96 
97  //! Reserve memory for given number of objects.
98  ROC_ATTR_NODISCARD bool reserve(size_t n_objects) {
99  return impl_.reserve(n_objects);
100  }
101 
102  //! Allocate memory for an object.
103  void* allocate() {
104  return impl_.allocate();
105  }
106 
107  //! Return memory to pool.
108  void deallocate(void* memory) {
109  impl_.deallocate(memory);
110  }
111 
112  //! Get number of guard failures detected.
113  size_t num_guard_failures() const {
114  return impl_.num_guard_failures();
115  }
116 
117 private:
118  enum {
119  SlotSize = (sizeof(SlabPoolImpl::SlotHeader) + sizeof(SlabPoolImpl::SlotCanary)
120  + sizeof(T) + sizeof(SlabPoolImpl::SlotCanary) + sizeof(AlignMax) - 1)
121  / sizeof(AlignMax) * sizeof(AlignMax)
122  };
123  AlignedStorage<EmbeddedCapacity * SlotSize> embedded_data_;
124  SlabPoolImpl impl_;
125 };
126 
127 } // namespace core
128 } // namespace roc
129 
130 #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 objects in pool.
size_t num_guard_failures() const
Get number of guard failures.
void * allocate()
Allocate memory for an object.
Memory pool.
Definition: slab_pool.h:65
ROC_ATTR_NODISCARD bool reserve(size_t n_objects)
Reserve memory for given number of objects.
Definition: slab_pool.h:98
void * allocate()
Allocate memory for an object.
Definition: slab_pool.h:103
void deallocate(void *memory)
Return memory to pool.
Definition: slab_pool.h:108
size_t num_guard_failures() const
Get number of guard failures detected.
Definition: slab_pool.h:113
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 flags=DefaultSlabPoolFlags)
Initialize.
Definition: slab_pool.h:76
size_t object_size() const
Get size of objects in pool.
Definition: slab_pool.h:93
Memory arena interface.
Memory pool interface.
SlabPoolFlags
Memory pool flags.
Definition: slab_pool.h:27
@ SlabPoolFlag_EnableGuards
Enable guards for buffer overflow, invalid ownership, etc.
Definition: slab_pool.h:29
Root namespace.
Non-copyable object.
Memory pool implementation class.
Commonly used types and functions.
Maximum aligned data unit.
Definition: align_ops.h:21