summaryrefslogtreecommitdiffstats
path: root/Whisper/CPU/BufferAllocator.h
blob: 750a565466ea8b4eed0597b2dcabc04fcbfcbc76 (plain)
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
#pragma once
#include "LargeBuffer.h"
#include "Tensor.h"

namespace CpuCompute
{
#ifdef NDEBUG
	inline void dbgMarkUninitializedMemory( void* pv, size_t cb ) { }
	inline void dbgMarkFreedMemory( void* pv, size_t cb ) { }
#else
	void dbgMarkUninitializedMemory( void* pv, size_t cb );
	void dbgMarkFreedMemory( void* pv, size_t cb );
#endif

	// An implementation of arena allocator which slices pieces of a large buffer allocated in advance
	class BufferAllocator : public iArenaAllocator
	{
		LargeBuffer buffer;
		size_t head = 0;
		size_t size = 0;

		void resetArena() noexcept override final
		{
			head = 0;
			dbgMarkFreedMemory( buffer.pointer(), size );
		}

		void* allocate( size_t cb, size_t align ) noexcept override final;

	public:
		BufferAllocator() = default;
		BufferAllocator( const BufferAllocator& ) = delete;
		~BufferAllocator() = default;

		// Allocate a large buffer with the specified count of bytes
		HRESULT create( size_t cb );
	};

	// An implementation of arena allocator which allocates a large chunk of virtual memory, and maps new physical pages into that memory region as needed.
	class VirtualAllocator : public iArenaAllocator
	{
		uint8_t* pointer = nullptr;
		size_t head = 0;
		size_t sizeAllocated = 0;
		size_t sizeVirtual = 0;

		void resetArena() noexcept override final
		{
			head = 0;
			dbgMarkFreedMemory( pointer, sizeAllocated );
		}

		void* allocate( size_t cb, size_t align ) noexcept override final;

	public:

		VirtualAllocator() = default;
		VirtualAllocator( const VirtualAllocator& ) = delete;
		~VirtualAllocator();

		// Reserve virtual memory space for the specified count of bytes in the arena, but don't allocate any pages
		HRESULT create( size_t cb );
	};
}