-
Notifications
You must be signed in to change notification settings - Fork 0
/
km_memory.cpp
143 lines (118 loc) · 2.94 KB
/
km_memory.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "km_memory.h"
#include <stdlib.h>
void MemCopy(void* dst, const void* src, uint64 numBytes)
{
DEBUG_ASSERT(((const char*)dst + numBytes <= src)
|| (dst >= (const char*)src + numBytes));
// TODO maybe see about reimplementing this? would be informative
memcpy(dst, src, numBytes);
}
void MemMove(void* dst, const void* src, uint64 numBytes)
{
memmove(dst, src, numBytes);
}
void MemSet(void* dst, uint8 value, uint64 numBytes)
{
uint8* d = (uint8*)dst;
for (uint32 i = 0; i < numBytes; i++) {
*d = value;
d++;
}
}
int MemComp(const void* mem1, const void* mem2, uint64 numBytes)
{
return memcmp(mem1, mem2, numBytes);
}
void* StandardAllocator::Allocate(uint64 size)
{
return malloc(size);
}
template <typename T> T* StandardAllocator::New()
{
return (T*)Allocate(sizeof(T));
}
void* StandardAllocator::ReAllocate(void* memory, uint64 size)
{
return realloc(memory, size);
}
void StandardAllocator::Free(void* memory)
{
free(memory);
}
LinearAllocator::LinearAllocator(const LargeArray<uint8>& memory)
: used(0), capacity(memory.size), data(memory.data)
{
}
LinearAllocator::LinearAllocator(uint64 capacity, void* data)
: used(0), capacity(capacity), data(data)
{
}
void LinearAllocator::Initialize(const LargeArray<uint8>& memory)
{
used = 0;
capacity = memory.size;
data = memory.data;
}
void LinearAllocator::Initialize(uint64 capacity, void* data)
{
used = 0;
this->capacity = capacity;
this->data = data;
}
void* LinearAllocator::Allocate(uint64 size)
{
if (used + size > capacity) {
return nullptr;
}
uint64 start = used;
used += size;
return (void*)((uint8*)data + start);
}
template <typename T> T* LinearAllocator::New()
{
return (T*)Allocate(sizeof(T));
}
template <typename T> T* LinearAllocator::New(uint64 n)
{
return (T*)Allocate(n * sizeof(T));
}
template <typename T> Array<T> LinearAllocator::NewArray(uint32 size)
{
return Array<T> { .size = size, .data = New<T>(size) };
}
void* LinearAllocator::ReAllocate(void* memory, uint64 size)
{
void* newData = Allocate(size);
if (newData == nullptr) {
return nullptr;
}
// TODO extremely hacky way of copying memory, but otherwise, we would have had to know the previous alloc size
uint64 diff = (uint64)newData - (uint64)memory;
MemCopy(newData, memory, MinUInt64(diff, size));
return newData;
}
void LinearAllocator::Free(void* memory)
{
DEBUG_ASSERT(memory >= data);
uint64 memoryInd = (uint64)memory - (uint64)data;
DEBUG_ASSERT(memoryInd < capacity);
used = memoryInd;
}
void LinearAllocator::Clear()
{
used = 0;
}
uint64 LinearAllocator::GetRemainingBytes()
{
return capacity - used;
}
LinearAllocatorState LinearAllocator::SaveState()
{
LinearAllocatorState state;
state.used = used;
return state;
}
void LinearAllocator::LoadState(const LinearAllocatorState& state)
{
used = state.used;
}