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

vsg 1.1.13 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/Export.h>
16
17#include <map>
18#include <memory>
19#include <mutex>
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_PHYSICS,
37 ALLOCATOR_AFFINITY_LAST = ALLOCATOR_AFFINITY_PHYSICS + 1
38 };
39
41 class VSG_DECLSPEC Allocator
42 {
43 public:
44 explicit Allocator(size_t in_defaultAlignment = 8) :
45 defaultAlignment(in_defaultAlignment) {}
46 explicit Allocator(std::unique_ptr<Allocator> in_nestedAllocator, size_t in_defaultAlignment = 8) :
47 defaultAlignment(in_defaultAlignment), nestedAllocator(std::move(in_nestedAllocator)) {}
48 virtual ~Allocator() {}
49
51 static std::unique_ptr<Allocator>& instance();
52
54 virtual void* allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS) = 0;
55
57 virtual bool deallocate(void* ptr, std::size_t size) = 0;
58
60 virtual size_t deleteEmptyMemoryBlocks() = 0;
61
63 virtual size_t totalAvailableSize() const = 0;
64
66 virtual size_t totalReservedSize() const = 0;
67
69 virtual size_t totalMemorySize() const = 0;
70
71 AllocatorType allocatorType = ALLOCATOR_TYPE_VSG_ALLOCATOR; // use MemoryBlocks by default
72
73 virtual void setBlockSize(AllocatorAffinity allocatorAffinity, size_t blockSize) = 0;
74
76 virtual void report(std::ostream& out) const = 0;
77
78 mutable std::mutex mutex;
79 size_t defaultAlignment = 8;
80
81 protected:
82 // if you are assigning a custom allocator you must retain the old allocator to manage the memory it allocated and needs to delete
83 std::unique_ptr<Allocator> nestedAllocator;
84 };
85
87 extern VSG_DECLSPEC void* allocate(std::size_t size, AllocatorAffinity allocatorAffinity = ALLOCATOR_AFFINITY_OBJECTS);
88
90 extern VSG_DECLSPEC void deallocate(void* ptr, std::size_t size = 0);
91
93 template<typename T, vsg::AllocatorAffinity A>
94 struct allocator_affinity_adapter
95 {
96 using value_type = T;
97
98 allocator_affinity_adapter() = default;
99 template<class U>
100 explicit constexpr allocator_affinity_adapter(const allocator_affinity_adapter<U, A>&) noexcept {}
101
102 template<class U>
103 struct rebind
104 {
105 using other = allocator_affinity_adapter<U, A>;
106 };
107
108 value_type* allocate(std::size_t n)
109 {
110 return static_cast<value_type*>(vsg::allocate(n * sizeof(value_type), A));
111 }
112
113 void deallocate(value_type* ptr, std::size_t n)
114 {
115 vsg::deallocate(ptr, n * sizeof(value_type));
116 }
117 };
118
119 template<class T, class U, vsg::AllocatorAffinity A>
120 bool operator==(const allocator_affinity_adapter<T, A>&, const allocator_affinity_adapter<U, A>&) { return true; }
121
122 template<class T, class U, vsg::AllocatorAffinity A>
123 bool operator!=(const allocator_affinity_adapter<T, A>&, const allocator_affinity_adapter<U, A>&) { return false; }
124
125 template<typename T>
126 using allocator_affinity_objects = allocator_affinity_adapter<T, vsg::ALLOCATOR_AFFINITY_OBJECTS>;
127 template<typename T>
128 using allocator_affinity_data = allocator_affinity_adapter<T, vsg::ALLOCATOR_AFFINITY_DATA>;
129 template<typename T>
130 using allocator_affinity_nodes = allocator_affinity_adapter<T, vsg::ALLOCATOR_AFFINITY_NODES>;
131 template<typename T>
132 using allocator_affinity_physics = allocator_affinity_adapter<T, vsg::ALLOCATOR_AFFINITY_PHYSICS>;
133
134} // namespace vsg
vsg::Allocator::totalReservedSize
virtual size_t totalReservedSize() const =0
return the total reserved size of allocated MemoryBlocks
vsg::Allocator::totalAvailableSize
virtual size_t totalAvailableSize() const =0
return the total available size of allocated MemoryBlocks
vsg::Allocator::report
virtual void report(std::ostream &out) const =0
report stats about blocks of memory allocated.
vsg::Allocator::instance
static std::unique_ptr< Allocator > & instance()
Allocator singleton.
vsg::Allocator::deleteEmptyMemoryBlocks
virtual size_t deleteEmptyMemoryBlocks()=0
delete any MemoryBlock that are empty
vsg::Allocator::allocate
virtual void * allocate(std::size_t size, AllocatorAffinity allocatorAffinity=ALLOCATOR_AFFINITY_OBJECTS)=0
allocate from the pool of memory blocks, or allocate from a new memory block
vsg::Allocator::deallocate
virtual bool deallocate(void *ptr, std::size_t size)=0
deallocate, returning data to pool.
vsg::Allocator::totalMemorySize
virtual size_t totalMemorySize() const =0
return the total memory size of allocated MemoryBlocks
vsg::allocator_affinity_adapter::rebind
Definition Allocator.h:104
vsg::allocator_affinity_adapter
std container adapter for allocating with specific affinity
Definition Allocator.h:95