Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
backing_memory.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8
11#include "unistd.h"
12#include <atomic>
13#include <cstring>
14#include <fcntl.h>
15#include <filesystem>
16#include <memory>
17#ifndef __wasm__
18#include <sys/mman.h>
19#endif
20
21// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
22extern bool slow_low_memory;
23
24// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
25extern size_t storage_budget;
26
27// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
28extern std::atomic<size_t> current_storage_usage;
29
30// Parse storage size string (e.g., "500m", "2g", "1024k")
31size_t parse_size_string(const std::string& size_str);
32
33template <typename Fr> struct BackingMemory {
34 // Common raw data pointer used by all storage types
35 Fr* raw_data = nullptr;
36
37#ifndef __wasm__
38 // File-backed data substruct with cleanup metadata
40 size_t file_size;
41 std::string filename;
42 int fd;
44
46 {
47 if (raw_data_ptr != nullptr && file_size > 0) {
48 munmap(raw_data_ptr, file_size);
50 }
51 if (fd >= 0) {
52 close(fd);
53 }
54 if (!filename.empty()) {
55 std::filesystem::remove(filename);
56 }
57 }
58 };
60#endif
61 // Aligned memory data substruct
63
64 BackingMemory() = default;
65
66 BackingMemory(const BackingMemory&) = default;
68
69 BackingMemory(BackingMemory&& other) noexcept
70 : raw_data(other.raw_data)
71#ifndef __wasm__
72 , file_backed(std::move(other.file_backed))
73#endif
74 , aligned_memory(std::move(other.aligned_memory))
75 {
76 other.raw_data = nullptr;
77 }
78
80 {
81 if (this != &other) {
82 raw_data = other.raw_data;
83#ifndef __wasm__
84 file_backed = std::move(other.file_backed);
85#endif
86 aligned_memory = std::move(other.aligned_memory);
87 other.raw_data = nullptr;
88 }
89 return *this;
90 }
91
92 // Allocate memory, preferring file-backed if in low memory mode
93 static BackingMemory allocate(size_t size)
94 {
96#ifndef __wasm__
97 if (slow_low_memory) {
99 return memory;
100 }
101 }
102#endif
104 return memory;
105 }
106
107 ~BackingMemory() = default;
108
109 private:
110 static void allocate_aligned(BackingMemory& memory, size_t size)
111 {
112 // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
113 memory.aligned_memory = std::static_pointer_cast<Fr[]>(std::move(bb::get_mem_slab(sizeof(Fr) * size)));
114 memory.raw_data = memory.aligned_memory.get();
115 }
116
117#ifndef __wasm__
119 {
120 if (size == 0) {
121 return false;
122 }
123
124 size_t required_bytes = size * sizeof(Fr);
125 size_t current_usage = current_storage_usage.load();
126
127 // Check if we're under the storage budget
128 if (current_usage + required_bytes > storage_budget) {
129 return false;
130 }
131
132 size_t file_size = required_bytes;
133 static std::atomic<size_t> file_counter{ 0 };
134 size_t id = file_counter.fetch_add(1);
135
136 std::filesystem::path temp_dir;
137 try {
138 temp_dir = std::filesystem::temp_directory_path();
139 } catch (const std::exception&) {
140 temp_dir = std::filesystem::current_path();
141 }
142
143 std::string filename = temp_dir / ("poly-mmap-" + std::to_string(getpid()) + "-" + std::to_string(id));
144
145 int fd = open(filename.c_str(), O_CREAT | O_RDWR | O_TRUNC, 0644);
146 if (fd < 0) {
147 return false;
148 }
149
150 if (ftruncate(fd, static_cast<off_t>(file_size)) != 0) {
151 close(fd);
152 std::filesystem::remove(filename);
153 return false;
154 }
155
156 void* addr = mmap(nullptr, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
157 if (addr == MAP_FAILED) {
158 close(fd);
159 std::filesystem::remove(filename);
160 return false;
161 }
162
163 auto file_backed_data = std::make_shared<FileBackedData>();
164 file_backed_data->file_size = file_size;
165 file_backed_data->filename = filename;
166 file_backed_data->fd = fd;
167 file_backed_data->raw_data_ptr = static_cast<Fr*>(addr);
168
169 memory.raw_data = static_cast<Fr*>(addr);
170 memory.file_backed = std::move(file_backed_data);
171
172 current_storage_usage.fetch_add(required_bytes);
173
174 return true;
175 }
176#endif
177};
size_t parse_size_string(const std::string &size_str)
std::atomic< size_t > current_storage_usage
bool slow_low_memory
size_t storage_budget
std::shared_ptr< void > get_mem_slab(size_t size)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
Curve::ScalarField Fr
MemoryStore memory
~BackingMemory()=default
BackingMemory()=default
static bool try_allocate_file_backed(BackingMemory &memory, size_t size)
static void allocate_aligned(BackingMemory &memory, size_t size)
std::shared_ptr< Fr[]> aligned_memory
BackingMemory & operator=(const BackingMemory &)=default
static BackingMemory allocate(size_t size)
BackingMemory(BackingMemory &&other) noexcept
BackingMemory(const BackingMemory &)=default
BackingMemory & operator=(BackingMemory &&other) noexcept
std::shared_ptr< FileBackedData > file_backed