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"
21#include "roc_core/stddefs.h"
22
23namespace roc {
24namespace core {
25
26//! Memory pool flags.
28 //! Enable guards for buffer overflow, invalid ownership, etc.
30};
31
32//! Default memory pool flags.
33enum { 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.
64template <class T, size_t EmbeddedCapacity = 0>
65class SlabPool : public IPool, public NonCopyable<> {
66public:
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
117private:
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
void * allocate()
Allocate memory for an object.
Definition: slab_pool.h:103
ROC_ATTR_NODISCARD bool reserve(size_t n_objects)
Reserve memory for given number of objects.
Definition: slab_pool.h:98
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