summaryrefslogtreecommitdiff
path: root/src/common/virtual_buffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/virtual_buffer.h')
-rw-r--r--src/common/virtual_buffer.h38
1 files changed, 32 insertions, 6 deletions
diff --git a/src/common/virtual_buffer.h b/src/common/virtual_buffer.h
index 125cb42f0..fb1a6f81f 100644
--- a/src/common/virtual_buffer.h
+++ b/src/common/virtual_buffer.h
@@ -4,29 +4,55 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_funcs.h" 7#include <type_traits>
8#include <utility>
8 9
9namespace Common { 10namespace Common {
10 11
11void* AllocateMemoryPages(std::size_t size); 12void* AllocateMemoryPages(std::size_t size) noexcept;
12void FreeMemoryPages(void* base, std::size_t size); 13void FreeMemoryPages(void* base, std::size_t size) noexcept;
13 14
14template <typename T> 15template <typename T>
15class VirtualBuffer final : NonCopyable { 16class VirtualBuffer final {
16public: 17public:
18 // TODO: Uncomment this and change Common::PageTable::PageInfo to be trivially constructible
19 // using std::atomic_ref once libc++ has support for it
20 // static_assert(
21 // std::is_trivially_constructible_v<T>,
22 // "T must be trivially constructible, as non-trivial constructors will not be executed "
23 // "with the current allocator");
24
17 constexpr VirtualBuffer() = default; 25 constexpr VirtualBuffer() = default;
18 explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} { 26 explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} {
19 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size)); 27 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
20 } 28 }
21 29
22 ~VirtualBuffer() { 30 ~VirtualBuffer() noexcept {
23 FreeMemoryPages(base_ptr, alloc_size); 31 FreeMemoryPages(base_ptr, alloc_size);
24 } 32 }
25 33
34 VirtualBuffer(const VirtualBuffer&) = delete;
35 VirtualBuffer& operator=(const VirtualBuffer&) = delete;
36
37 VirtualBuffer(VirtualBuffer&& other) noexcept
38 : alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr),
39 nullptr} {}
40
41 VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
42 alloc_size = std::exchange(other.alloc_size, 0);
43 base_ptr = std::exchange(other.base_ptr, nullptr);
44 return *this;
45 }
46
26 void resize(std::size_t count) { 47 void resize(std::size_t count) {
48 const auto new_size = count * sizeof(T);
49 if (new_size == alloc_size) {
50 return;
51 }
52
27 FreeMemoryPages(base_ptr, alloc_size); 53 FreeMemoryPages(base_ptr, alloc_size);
28 54
29 alloc_size = count * sizeof(T); 55 alloc_size = new_size;
30 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size)); 56 base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
31 } 57 }
32 58