vsg: include/vsg/core/Allocator.h Source File

vsg 1.1.3 VulkanSceneGraph library

Loading...
Searching...
No Matches
Allocator.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2022 Robert Osfield
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
13</editor-fold> */
14
15#include <vsg/core/MemorySlots.h>
16
17#include <memory>
18#include <mutex>
19#include <vector>
20
21namespace vsg
22{
23 enum AllocatorType : uint8_t
24 {
25 ALLOCATOR_TYPE_NO_DELETE = 0,
26 ALLOCATOR_TYPE_NEW_DELETE,
27 ALLOCATOR_TYPE_MALLOC_FREE,
28 ALLOCATOR_TYPE_VSG_ALLOCATOR
29 };
30
31 enum AllocatorAffinity : uint32_t
32 {
33 ALLOCATOR_AFFINITY_OBJECTS,
34 ALLOCATOR_AFFINITY_DATA,
35 ALLOCATOR_AFFINITY_NODES,
36 ALLOCATOR_AFFINITY_LAST = ALLOCATOR_AFFINITY_NODES + 1
37 };
38
40 class VSG_DECLSPEC Allocator
41 {
42 public:
43 Allocator(std::unique_ptr<Allocator> in_nestedAllocator = {});
44
45 virtual ~Allocator();
46
48 static std::unique_ptr<Allocator>& instance();
49
51 virtual void* allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS);
52
54 virtual bool deallocate(void* ptr, std::size_t size);
55
57 virtual size_t deleteEmptyMemoryBlocks();
58
60 virtual size_t totalAvailableSize() const;
61
63 virtual size_t totalReservedSize() const;
64
66 virtual size_t totalMemorySize() const;
67
69 virtual void report(std::ostream& out) const;
70
71 AllocatorType allocatorType = ALLOCATOR_TYPE_VSG_ALLOCATOR; // use MemoryBlocks by default
72 AllocatorType memoryBlocksAllocatorType = ALLOCATOR_TYPE_NEW_DELETE; // Use new/delete within MemoryBlocks by default
73 int memoryTracking = MEMORY_TRACKING_DEFAULT;
74
76 void setMemoryTracking(int mt);
77
78 struct MemoryBlock
79 {
80 MemoryBlock(size_t blockSize, int memoryTracking, AllocatorType in_allocatorType);
81 virtual ~MemoryBlock();
82
83 void* allocate(std::size_t size);
84 bool deallocate(void* ptr, std::size_t size);
85
86 vsg::MemorySlots memorySlots;
87 const AllocatorType allocatorType;
88 uint8_t* memory = nullptr;
89 };
90
91 struct MemoryBlocks
92 {
93 Allocator* parent = nullptr;
94 std::string name;
95 size_t blockSize = 0;
96 std::map<void*, std::shared_ptr<MemoryBlock>> memoryBlocks;
97 std::shared_ptr<MemoryBlock> latestMemoryBlock;
98
99 MemoryBlocks(Allocator* in_parent, const std::string& in_name, size_t in_blockSize);
100 virtual ~MemoryBlocks();
101
102 void* allocate(std::size_t size);
103 bool deallocate(void* ptr, std::size_t size);
104
105 size_t deleteEmptyMemoryBlocks();
106 size_t totalAvailableSize() const;
107 size_t totalReservedSize() const;
108 size_t totalMemorySize() const;
109 };
110
111 MemoryBlocks* getMemoryBlocks(AllocatorAffinity allocatorAffinity);
112
113 MemoryBlocks* getOrCreateMemoryBlocks(AllocatorAffinity allocatorAffinity, const std::string& name, size_t blockSize);
114
115 void setBlockSize(AllocatorAffinity allocatorAffinity, size_t blockSize);
116
117 mutable std::mutex mutex;
118
119 double allocationTime = 0.0;
120 double deallocationTime = 0.0;
121
122 protected:
123 // if you are assigning a custom allocator you must retain the old allocator to manage the memory it allocated and needs to delete
124 std::unique_ptr<Allocator> nestedAllocator;
125
126 std::vector<std::unique_ptr<MemoryBlocks>> allocatorMemoryBlocks;
127 };
128
130 extern VSG_DECLSPEC void* allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS);
131
133 extern VSG_DECLSPEC void deallocate(void* ptr, std::size_t size = 0);
134
136 template<typename T>
137 struct allocator_affinity_nodes
138 {
139 using value_type = T;
140
141 allocator_affinity_nodes() = default;
142 template<class U>
143 explicit constexpr allocator_affinity_nodes(const allocator_affinity_nodes<U>&) noexcept {}
144
145 value_type* allocate(std::size_t n)
146 {
147 return static_cast<value_type*>(vsg::allocate(n * sizeof(value_type), vsg::ALLOCATOR_AFFINITY_NODES));
148 }
149
150 void deallocate(value_type* ptr, std::size_t n)
151 {
152 vsg::deallocate(ptr, n * sizeof(value_type));
153 }
154 };
155
156 template<class T, class U>
157 bool operator==(const allocator_affinity_nodes<T>&, const allocator_affinity_nodes<U>&) { return true; }
158
159 template<class T, class U>
160 bool operator!=(const allocator_affinity_nodes<T>&, const allocator_affinity_nodes<U>&) { return false; }
161
162} // namespace vsg
vsg::Allocator
Definition Allocator.h:41
vsg::Allocator::setMemoryTracking
void setMemoryTracking(int mt)
set the MemoryTracking member of the vsg::Allocator and all the MemoryBlocks that it manages.
vsg::Allocator::deallocate
virtual bool deallocate(void *ptr, std::size_t size)
deallocate, returning data to pool.
vsg::Allocator::totalMemorySize
virtual size_t totalMemorySize() const
return the total memory size of allocated MemoryBlocks
vsg::Allocator::instance
static std::unique_ptr< Allocator > & instance()
Allocator singleton.
vsg::Allocator::deleteEmptyMemoryBlocks
virtual size_t deleteEmptyMemoryBlocks()
delete any MemoryBlock that are empty
vsg::Allocator::report
virtual void report(std::ostream &out) const
report stats about blocks of memory allocated.
vsg::Allocator::allocate
virtual void * allocate(std::size_t size, AllocatorAffinity allocatorAffinity=ALLOCATOR_AFFINITY_OBJECTS)
allocate from the pool of memory blocks, or allocate from a new memory block
vsg::Allocator::totalAvailableSize
virtual size_t totalAvailableSize() const
return the total available size of allocated MemoryBlocks
vsg::Allocator::totalReservedSize
virtual size_t totalReservedSize() const
return the total reserved size of allocated MemoryBlocks
vsg::MemorySlots
Definition MemorySlots.h:36
vsg::Allocator::MemoryBlock
Definition Allocator.h:79
vsg::Allocator::MemoryBlocks
Definition Allocator.h:92
vsg::allocator_affinity_nodes
std container adapter for allocating with MEMORY_AFFINITY_NODES
Definition Allocator.h:138