Skip to content

Commit

Permalink
Basic Allocator abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-van-bergen committed Feb 19, 2022
1 parent d846ab6 commit 255f0d5
Show file tree
Hide file tree
Showing 17 changed files with 316 additions and 101 deletions.
3 changes: 3 additions & 0 deletions Pathtracer.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,9 @@
<ClInclude Include="Src\BVH\Converters\BVH8Converter.h" />
<ClInclude Include="Src\BVH\Converters\BVH4Converter.h" />
<ClInclude Include="Src\Config.h" />
<ClInclude Include="Src\Core\Allocators\Allocator.h" />
<ClInclude Include="Src\Core\Allocators\LinearAllocator.h" />
<ClInclude Include="Src\Core\Allocators\PinnedAllocator.h" />
<ClInclude Include="Src\Core\Array.h" />
<ClInclude Include="Src\Core\Assertion.h" />
<ClInclude Include="Src\Core\BitArray.h" />
Expand Down
12 changes: 12 additions & 0 deletions Pathtracer.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,9 @@
<Filter Include="Renderer\Integrators">
<UniqueIdentifier>{19bb3711-1af8-4298-89b6-e719d008a79f}</UniqueIdentifier>
</Filter>
<Filter Include="Core\Allocators">
<UniqueIdentifier>{4b1e0e24-b96c-4dac-884c-8f76c2f50eaf}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\Assets\OBJLoader.h">
Expand Down Expand Up @@ -421,5 +424,14 @@
<ClInclude Include="Src\Renderer\Integrators\AO.h">
<Filter>Renderer\Integrators</Filter>
</ClInclude>
<ClInclude Include="Src\Core\Allocators\Allocator.h">
<Filter>Core\Allocators</Filter>
</ClInclude>
<ClInclude Include="Src\Core\Allocators\PinnedAllocator.h">
<Filter>Core\Allocators</Filter>
</ClInclude>
<ClInclude Include="Src\Core\Allocators\LinearAllocator.h">
<Filter>Core\Allocators</Filter>
</ClInclude>
</ItemGroup>
</Project>
36 changes: 19 additions & 17 deletions Src/Assets/Mitsuba/XMLParser.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
#include "XMLParser.h"

inline XMLNode parse_tag(Parser & parser) {
if (parser.reached_end()) return { };
XMLNode XMLParser::parse_root() {
XMLNode root = XMLNode(&allocator);
root.location = parser.location;

while (!parser.reached_end()) {
parser_skip_xml_whitespace(parser);
root.children.push_back(parse_tag());
parser_skip_xml_whitespace(parser);
}

return root;
}

XMLNode XMLParser::parse_tag() {
XMLNode node = XMLNode(&allocator);
if (parser.reached_end()) {
return node;
}

parser.expect('<');

XMLNode node = { };
node.location = parser.location;
node.is_question_mark = parser.match('?');

Expand Down Expand Up @@ -66,7 +81,7 @@ inline XMLNode parse_tag(Parser & parser) {

// Parse children
while (!parser.match("</")) {
node.children.push_back(parse_tag(parser));
node.children.push_back(parse_tag());
parser_skip_xml_whitespace(parser);
}

Expand All @@ -82,16 +97,3 @@ inline XMLNode parse_tag(Parser & parser) {

return node;
}

XMLNode XMLParser::parse_root() {
XMLNode root = { };
root.location = parser.location;

while (!parser.reached_end()) {
parser_skip_xml_whitespace(parser);
root.children.push_back(parse_tag(parser));
parser_skip_xml_whitespace(parser);
}

return root;
}
13 changes: 13 additions & 0 deletions Src/Assets/Mitsuba/XMLParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "Core/Array.h"
#include "Core/Parser.h"
#include "Core/Allocators/LinearAllocator.h"

inline void parser_skip_xml_whitespace(Parser & parser) {
parser.skip_whitespace_or_newline();
Expand Down Expand Up @@ -98,6 +99,13 @@ struct XMLNode {

SourceLocation location;

XMLNode(Allocator * allocator) : attributes(allocator), children(allocator) { }

DEFAULT_MOVEABLE(XMLNode);
DEFAULT_COPYABLE(XMLNode);

~XMLNode() { }

template<typename Predicate>
const XMLAttribute * get_attribute(Predicate predicate) const {
for (int i = 0; i < attributes.size(); i++) {
Expand Down Expand Up @@ -180,7 +188,12 @@ struct XMLParser {
String source;
Parser parser;

LinearAllocator<GIGABYTE(1)> allocator;

XMLParser(const String & filename) : source(IO::file_read(filename)), parser(source.view(), filename.view()) { }

XMLNode parse_root();

private:
XMLNode parse_tag();
};
6 changes: 6 additions & 0 deletions Src/BVH/BVH.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,23 @@ struct BVH {
struct BVH2 final : BVH {
Array<BVHNode2> nodes;

BVH2(Allocator * allocator = nullptr) : nodes(allocator) { }

size_t node_count() const override { return nodes.size(); }
};

struct BVH4 final : BVH {
Array<BVHNode4> nodes;

BVH4(Allocator * allocator = nullptr) : nodes(allocator) { }

size_t node_count() const override{ return nodes.size(); }
};

struct BVH8 final : BVH {
Array<BVHNode8> nodes;

BVH8(Allocator * allocator = nullptr) : nodes(allocator) { }

size_t node_count() const override { return nodes.size(); }
};
57 changes: 57 additions & 0 deletions Src/Core/Allocators/Allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once
#include <new>

#include "Util/Util.h"

#define KILOBYTE(n) (n * 1024)
#define MEGABYTE(n) (n * 1024 * 1024)
#define GIGABYTE(n) (n * 1024 * 1024 * 1024)

struct Allocator {
Allocator() = default;

NON_COPYABLE(Allocator);
NON_MOVEABLE(Allocator);

virtual ~Allocator() { }

template<typename T, typename ... Args>
static T * alloc(Allocator * allocator, Args && ... args) {
if (allocator) {
return new (allocator->alloc(sizeof(T))) T { std::forward<Args>(args) ... };
} else {
return new T { std::forward<Args>(args) ... };
}
}

template<typename T, typename ... Args>
static T * alloc_array(Allocator * allocator, size_t count) {
if (allocator) {
return new (allocator->alloc(count * sizeof(T))) T[count];
} else {
return new T[count];
}
}

template<typename T>
static void free(Allocator * allocator, T * ptr) {
if (allocator) {
allocator->free(ptr);
} else {
delete ptr;
}
}

template<typename T>
static void free_array(Allocator * allocator, T * ptr) {
if (allocator) {
allocator->free(ptr);
} else {
delete [] ptr;
}
}

protected:
virtual char * alloc(size_t num_bytes) = 0;
virtual void free (void * ptr) = 0;
};
45 changes: 45 additions & 0 deletions Src/Core/Allocators/LinearAllocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include "Allocator.h"

template<size_t Size = MEGABYTE(4)>
struct LinearAllocator final : Allocator {
char * data = nullptr;
size_t offset = 0;
LinearAllocator<Size> * next = nullptr;

LinearAllocator() {
data = new char[Size];
}

~LinearAllocator() {
ASSERT(data);
delete [] data;
if (next) {
next->~LinearAllocator();
}
}

char * alloc(size_t num_bytes) override {
if (num_bytes >= Size) {
return new char[num_bytes]; // Fall back to heap allocation
}
if (offset + num_bytes <= Size) {
char * result = data + offset;
offset += num_bytes;
return result;
} else if (!next) {
next = new LinearAllocator();
}
return next->alloc(num_bytes);
}

void free(void * ptr) override {
if (ptr >= data && ptr < data + Size) {
// Do nothing, memory will be freed in bulk inside the destructor
} else if (next) {
next->free(ptr);
} else {
delete [] ptr; // ptr was not in any valid range, must have been a heap allocated pointer
}
}
};
19 changes: 19 additions & 0 deletions Src/Core/Allocators/PinnedAllocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once
#include "Allocator.h"

#include "Device/CUDAMemory.h"

struct PinnedAllocator final : Allocator {
char * alloc(size_t num_bytes) override {
return CUDAMemory::malloc_pinned<char>(num_bytes);
}

void free(void * ptr) override {
CUDAMemory::free_pinned(ptr);
}

static PinnedAllocator * instance() {
static PinnedAllocator allocator = { };
return &allocator;
}
};
Loading

0 comments on commit 255f0d5

Please sign in to comment.