Cogs.Core
MemoryContext.cpp
1#include "MemoryContext.h"
2
3#include "Foundation/Logging/Logger.h"
4#include "Foundation/Memory/Allocator.h"
5#include "Foundation/Platform/Atomic.h"
6#include "Foundation/StringView.h"
7
8#include <algorithm>
9
10namespace
11{
13}
14
15namespace Cogs::Core
16{
18 {
19 public:
20 CoreAllocator(Memory::Allocator * baseAllocator, StringView tag, bool base = false) :
21 baseAllocator(baseAllocator),
22 tag(tag),
23 base(base)
24 {
25 }
26
28 {
29 if (!base && tag != "Strings") {
30 if (allocationCount || allocationSize) {
31 LOG_WARNING(logger, "[%.*s] Leaked %zu allocations, %zu bytes.", StringViewFormat(tag), allocationCount.load(), allocationSize.load());
32 assert(allocationSize == 0 && "Core memory leaked.");
33 }
34 }
35 }
36
37 size_t size() const { return allocationSize; }
38 size_t count() const { return allocationCount; }
39
40 size_t peakSize() const { return peakAllocationSize; }
41 size_t peakCount() const { return peakAllocationCount; }
42
43 void * allocate(size_t size, size_t alignment, MemBlockType type = MemBlockType::CoreAllocator) override
44 {
45 allocationSize += size;
46 peakAllocationSize = std::max(peakAllocationSize.load(), allocationSize.load());
47 ++allocationCount;
48 peakAllocationCount = std::max(peakAllocationCount.load(), allocationCount.load());
49
50 return baseAllocator->allocate(size, alignment, type);
51 }
52
53 void deallocate(void * ptr, size_t size, MemBlockType type = MemBlockType::CoreAllocator) override
54 {
55 allocationSize -= size;
56 --allocationCount;
57
58 baseAllocator->deallocate(ptr, size, type);
59 }
60
61 size_t getAllocatedBytes() const override { return allocationSize; }
62
64 size_t getAllocationCount() const override { return allocationCount; }
65
66 private:
67 Memory::Allocator * baseAllocator;
68
69 Atomic<size_t> allocationSize{ 0 };
70 Atomic<size_t> allocationCount{ 0 };
71 Atomic<size_t> peakAllocationSize{ 0 };
72 Atomic<size_t> peakAllocationCount{ 0 };
73
74 StringView tag;
75 bool base = false;
76 };
77
79 {
81 baseAllocator(Memory::Allocator::defaultAllocator(), "Core", true),
82 resourceAllocator(&baseAllocator, "Resources"),
83 componentAllocator(&baseAllocator, "Components"),
84 ioAllocator(&baseAllocator, "IO"),
85 scriptAllocator(&baseAllocator, "Script")
86 {
87 }
88
89 CoreAllocator baseAllocator;
90 CoreAllocator resourceAllocator;
91 CoreAllocator componentAllocator;
92 CoreAllocator ioAllocator;
93 CoreAllocator scriptAllocator;
94 };
95
96
97 size_t getAllocatedBytes(const Memory::Allocator * allocator)
98 {
99 return ((CoreAllocator *)allocator)->size();
100 }
101
102 size_t getAllocationCount(const Memory::Allocator * allocator)
103 {
104 return ((CoreAllocator *)allocator)->count();
105 }
106
107 size_t getPeakBytes(const Memory::Allocator * allocator)
108 {
109 return ((CoreAllocator *)allocator)->peakSize();
110 }
111
112 size_t getPeakCount(const Memory::Allocator * allocator)
113 {
114 return ((CoreAllocator *)allocator)->peakCount();
115 }
116}
117
118Cogs::Memory::Allocator * Cogs::Core::MemoryContext::getStringsAllocator() {
119 static CoreAllocator cSringsAllocator(Memory::Allocator::defaultAllocator(), "Strings");
120
121 return &cSringsAllocator;
122}
123
124Cogs::Core::MemoryContext::MemoryContext() :
125 storage(std::make_unique<MemoryContextStorage>()),
126 baseAllocator(&storage->baseAllocator),
127 resourceAllocator(&storage->resourceAllocator),
128 ioAllocator(&storage->ioAllocator),
129 componentAllocator(&storage->componentAllocator),
130 scriptAllocator(&storage->scriptAllocator)
131{
132
133}
134
135Cogs::Core::MemoryContext::~MemoryContext()
136{
137
138}
void * allocate(size_t size, size_t alignment, MemBlockType type=MemBlockType::CoreAllocator) override
Allocate raw memory.
void deallocate(void *ptr, size_t size, MemBlockType type=MemBlockType::CoreAllocator) override
Deallocate the memory block at the given pointer, with the given size.
size_t getAllocationCount() const override
Return the number of allocations currently allocated by this allocator.
size_t getAllocatedBytes() const override
Return the number of bytes currently allocated by this allocator.
Log implementation class.
Definition: LogManager.h:139
Base allocator implementation.
Definition: Allocator.h:30
static Allocator * defaultAllocator()
Gets the system default allocator.
Definition: Allocator.cpp:17
virtual void deallocate(void *ptr, size_t size, MemBlockType type=MemBlockType::Block)
Deallocate the memory block at the given pointer, with the given size.
Definition: Allocator.cpp:58
virtual void * allocate(size_t size, size_t alignment=0, MemBlockType type=MemBlockType::Block)
Allocate raw memory.
Definition: Allocator.cpp:29
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
STL namespace.