Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
heap_arena.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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/heap_arena.h
10 //! @brief Heap arena implementation.
11 
12 #ifndef ROC_CORE_HEAP_ARENA_H_
13 #define ROC_CORE_HEAP_ARENA_H_
14 
15 #include "roc_core/align_ops.h"
16 #include "roc_core/atomic.h"
17 #include "roc_core/iarena.h"
18 #include "roc_core/noncopyable.h"
19 
20 namespace roc {
21 namespace core {
22 
23 //! Heap arena guards.
25  //! Panic if leaks detected in arena destructor.
26  HeapArena_LeakGuard = (1 << 0),
27  //! Panic if detected buffer overflow when deallocating chunk.
29  //! Panic if detected ownership mismatch when deallocating chunk.
31 };
32 
33 //! Default heap arena guards.
34 //! Leak guard is disabled by default, because in C API leaks may be caused by user
35 //! (e.g. if context wasn't closed before program exit). We don't want to turn bugs
36 //! in user code into panics, only bugs in our own code should cause panics.
37 enum { HeapArena_DefaultGuards = (HeapArena_OverflowGuard | HeapArena_OwnershipGuard) };
38 
39 //! Heap arena implementation.
40 //!
41 //! Uses malloc() and free().
42 //!
43 //! The memory is always maximum aligned.
44 //!
45 //! Implements three safety measures:
46 //! - to catch double-free and other logical bugs, inserts link to owning arena before
47 //! user data, and panics if it differs when memory is returned to arena
48 //! - to catch buffer overflow bugs, inserts "canary guards" before and after user
49 //! data, and panics if they are overwritten when memory is returned to arena
50 //! - to catch uninitialized-access and use-after-free bugs, "poisons" memory when it
51 //! returned to user, and when it returned back to the arena
52 //!
53 //! Allocated chunks have the following format:
54 //! @code
55 //! +-------------+-------------+-----------+-------------+
56 //! | ChunkHeader | ChunkCanary | user data | ChunkCanary |
57 //! +-------------+-------------+-----------+-------------+
58 //! @endcode
59 //!
60 //! ChunkHeader contains pointer to the owning arena, checked when returning memory to
61 //! arena. ChunkCanary contains magic bytes filled when returning memory to user, and
62 //! checked when returning memory to arena.
63 //!
64 //! Thread-safe.
65 class HeapArena : public IArena, public NonCopyable<> {
66 public:
67  //! Initialize.
69  ~HeapArena();
70 
71  //! Set enabled guards, for all instances.
72  //! @b Parameters
73  //! - @p guards defines options to modify behaviour as indicated in HeapArenaGuard
74  static void set_guards(size_t guards);
75 
76  //! Get number of allocated blocks.
77  size_t num_allocations() const;
78 
79  //! Get number of guard failures.
80  size_t num_guard_failures() const;
81 
82  //! Allocate memory.
83  virtual void* allocate(size_t size);
84 
85  //! Deallocate previously allocated memory.
86  virtual void deallocate(void* ptr);
87 
88  //! Computes how many bytes will be actually allocated if allocate() is called with
89  //! given size. Covers all internal overhead, if any.
90  virtual size_t compute_allocated_size(size_t size) const;
91 
92  //! Returns how many bytes was allocated for given pointer returned by allocate().
93  //! Covers all internal overhead, if any.
94  //! Returns same value as computed by compute_allocated_size(size).
95  virtual size_t allocated_size(void* ptr) const;
96 
97 private:
98  struct ChunkHeader {
99  // The heap arena that the chunk belongs to.
100  HeapArena* owner;
101  // Data size, excluding canary guards.
102  size_t size;
103  // Data surrounded with canary guards.
104  AlignMax data[];
105  };
106 
107  typedef AlignMax ChunkCanary;
108 
109  bool report_guard_(HeapArenaGuard guard) const;
110 
111  Atomic<int> num_allocations_;
112  mutable Atomic<size_t> num_guard_failures_;
113 
114  static size_t guards_;
115 };
116 
117 } // namespace core
118 } // namespace roc
119 
120 #endif // ROC_CORE_HEAP_ARENA_H_
Alignment operations.
Atomic.
Heap arena implementation.
Definition: heap_arena.h:65
virtual void deallocate(void *ptr)
Deallocate previously allocated memory.
size_t num_guard_failures() const
Get number of guard failures.
virtual void * allocate(size_t size)
Allocate memory.
size_t num_allocations() const
Get number of allocated blocks.
static void set_guards(size_t guards)
Set enabled guards, for all instances. Parameters.
HeapArena()
Initialize.
virtual size_t compute_allocated_size(size_t size) const
Computes how many bytes will be actually allocated if allocate() is called with given size....
virtual size_t allocated_size(void *ptr) const
Returns how many bytes was allocated for given pointer returned by allocate(). Covers all internal ov...
Memory arena interface.
Definition: iarena.h:23
Base class for non-copyable objects.
Definition: noncopyable.h:23
Memory arena interface.
HeapArenaGuard
Heap arena guards.
Definition: heap_arena.h:24
@ HeapArena_LeakGuard
Panic if leaks detected in arena destructor.
Definition: heap_arena.h:26
@ HeapArena_OverflowGuard
Panic if detected buffer overflow when deallocating chunk.
Definition: heap_arena.h:28
@ HeapArena_OwnershipGuard
Panic if detected ownership mismatch when deallocating chunk.
Definition: heap_arena.h:30
Root namespace.
Non-copyable object.
Maximum aligned data unit.
Definition: align_ops.h:21