Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
Loading...
Searching...
No Matches
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 Slab pool.
11
12#ifndef ROC_CORE_SLAB_POOL_H_
13#define ROC_CORE_SLAB_POOL_H_
14
15#include "roc_core/iallocator.h"
16#include "roc_core/list.h"
17#include "roc_core/mutex.h"
19#include "roc_core/stddefs.h"
20
21namespace roc {
22namespace core {
23
24//! Slab pool.
25//!
26//! Allocates large chunks of memory ("slabs") from given allocator suitable to hold
27//! multiple fixed-size objects ("slots").
28//!
29//! Keeps track of free slots and use them when possible. Automatically allocates new
30//! slabs when there are no free slots.
31//!
32//! Automatically grows size of new slabs exponentially. The user can also specify the
33//! minimum and maximum limits for the slab.
34//!
35//! The return memory is always maximum aligned. Thread-safe.
36class SlabPool : public NonCopyable<> {
37public:
38 //! Initialize.
39 //!
40 //! @b Parameters
41 //! - @p allocator is used to allocate slabs
42 //! - @p object_size defines size of single object in bytes
43 //! - @p min_alloc_bytes defines minimum size in bytes per request to allocator
44 //! - @p max_alloc_bytes defines maximum size in bytes per request to allocator
45 //! - @p poison enables memory poisoning for debugging
46 SlabPool(IAllocator& allocator,
47 size_t object_size,
48 bool poison,
49 size_t min_alloc_bytes = 0,
50 size_t max_alloc_bytes = 0);
51
52 //! Deinitialize.
54
55 //! Get size of objects in pool.
56 size_t object_size() const;
57
58 //! Reserve memory for given number of objects.
59 //! @returns
60 //! false if allocation failed.
61 bool reserve(size_t n_objects);
62
63 //! Allocate memory for an object.
64 //! @returns
65 //! pointer to a maximum aligned uninitialized memory for a new object
66 //! or NULL if memory can't be allocated.
67 void* allocate();
68
69 //! Return memory to pool.
70 void deallocate(void* memory);
71
72 //! Destroy object and deallocate its memory.
73 template <class T> void destroy_object(T& object) {
74 object.~T();
75 deallocate(&object);
76 }
77
78private:
79 // Some good fillers for unused memory.
80 // If we fill memory with these values and interpret it as 16-bit or 32-bit
81 // integers, or as floats, the values will be rather high and will sound
82 // loudly when trying to play them on sound card.
83 enum { PoisonAllocated = 0x7a, PoisonDeallocated = 0x7d };
84
85 struct Slab : ListNode {};
86 struct Slot : ListNode {};
87
88 void* give_slot_to_user_(Slot* slot);
89 Slot* take_slot_from_user_(void* memory);
90
91 Slot* acquire_slot_();
92 void release_slot_(Slot* slot);
93 bool reserve_slots_(size_t desired_slots);
94
95 void increase_slab_size_(size_t desired_n_slots);
96 bool allocate_new_slab_();
97 void deallocate_everything_();
98
99 size_t slots_per_slab_(size_t slab_size, bool round_up) const;
100 size_t slot_offset_(size_t slot_index) const;
101
102 Mutex mutex_;
103
104 IAllocator& allocator_;
105
106 List<Slab, NoOwnership> slabs_;
107 List<Slot, NoOwnership> free_slots_;
108 size_t n_used_slots_;
109
110 const size_t slab_min_bytes_;
111 const size_t slab_max_bytes_;
112
113 const size_t slot_size_;
114 const size_t slab_hdr_size_;
115
116 size_t slab_cur_slots_;
117 const size_t slab_max_slots_;
118
119 const size_t object_size_;
120 const bool poison_;
121};
122
123} // namespace core
124} // namespace roc
125
126//! Placement new for core::SlabPool.
127//! @note
128//! nothrow forces compiler to check for NULL return value before calling ctor.
129inline void* operator new(size_t size, roc::core::SlabPool& pool) throw() {
130 roc_panic_if_not(size <= pool.object_size());
131 return pool.allocate();
132}
133
134//! Placement delete for core::SlabPool.
135//! @note
136//! Compiler calls this if ctor throws in a placement new expression.
137inline void operator delete(void* ptr, roc::core::SlabPool& pool) throw() {
138 pool.deallocate(ptr);
139}
140
141#endif // ROC_CORE_SLAB_POOL_H_
Memory allocator interface.
Definition: iallocator.h:23
Base class for non-copyable objects.
Definition: noncopyable.h:23
Slab pool.
Definition: slab_pool.h:36
SlabPool(IAllocator &allocator, size_t object_size, bool poison, size_t min_alloc_bytes=0, size_t max_alloc_bytes=0)
Initialize.
void deallocate(void *memory)
Return memory to pool.
void * allocate()
Allocate memory for an object.
bool reserve(size_t n_objects)
Reserve memory for given number of objects.
~SlabPool()
Deinitialize.
void destroy_object(T &object)
Destroy object and deallocate its memory.
Definition: slab_pool.h:73
size_t object_size() const
Get size of objects in pool.
Memory allocator interface.
Intrusive doubly-linked list.
Mutex.
Root namespace.
Non-copyable object.
#define roc_panic_if_not(x)
Panic if condition is false.
Definition: panic.h:37
Commonly used types and functions.