@@ -52,27 +52,38 @@ template <typename Fr> class BackingMemory {
5252 {
5353#ifndef __wasm__
5454 if (slow_low_memory) {
55- size_t required_bytes = size * sizeof (Fr);
56- size_t current_usage = current_storage_usage.load ();
57-
58- // Check if we're under the storage budget
59- if (current_usage + required_bytes <= storage_budget) {
60- // Try to use FileBackedMemory
61- try {
62- auto result = std::shared_ptr<BackingMemory<Fr>>(new FileBackedMemory<Fr>(size));
63- current_storage_usage.fetch_add (required_bytes);
64- return result;
65- } catch (const std::exception& e) {
66- // FileBackedMemory allocation failed, fall back to AlignedMemory
67- return std::shared_ptr<BackingMemory<Fr>>(new AlignedMemory<Fr>(size));
68- }
55+ auto file_backed = try_allocate_file_backed (size);
56+ if (file_backed) {
57+ return file_backed;
6958 }
70- // Over budget, use AlignedMemory
7159 }
7260#endif
7361 return std::shared_ptr<BackingMemory<Fr>>(new AlignedMemory<Fr>(size));
7462 }
7563
64+ private:
65+ #ifndef __wasm__
66+ static std::shared_ptr<BackingMemory<Fr>> try_allocate_file_backed (size_t size)
67+ {
68+ size_t required_bytes = size * sizeof (Fr);
69+ size_t current_usage = current_storage_usage.load ();
70+
71+ // Check if we're under the storage budget
72+ if (current_usage + required_bytes > storage_budget) {
73+ return nullptr ; // Over budget
74+ }
75+
76+ // Attempt to create FileBackedMemory without exceptions
77+ // We'll need to modify FileBackedMemory constructor to be noexcept
78+ auto file_backed = FileBackedMemory<Fr>::try_create (size);
79+ if (file_backed) {
80+ current_storage_usage.fetch_add (required_bytes);
81+ }
82+ return file_backed;
83+ }
84+ #endif
85+
86+ public:
7687 virtual ~BackingMemory () = default ;
7788};
7889
@@ -104,36 +115,17 @@ template <typename T> class FileBackedMemory : public BackingMemory<T> {
104115
105116 T* raw_data () { return memory; }
106117
107- ~FileBackedMemory ()
118+ // Try to create file-backed memory, returns nullptr on failure
119+ static std::shared_ptr<BackingMemory<T>> try_create (size_t size)
108120 {
109- if (file_size == 0 ) {
110- return ;
111- }
112- if (memory != nullptr && file_size > 0 ) {
113- munmap (memory, file_size);
114- // Decrement storage usage when FileBackedMemory is freed
115- current_storage_usage.fetch_sub (file_size);
116- }
117- if (fd >= 0 ) {
118- close (fd);
119- }
120- if (!filename.empty ()) {
121- std::filesystem::remove (filename);
122- }
123- }
124-
125- private:
126- // Create a new file-backed memory region
127- FileBackedMemory (size_t size)
128- : BackingMemory<T>()
129- , file_size(size * sizeof (T))
130- {
131- if (file_size == 0 ) {
132- return ;
121+ if (size == 0 ) {
122+ return std::shared_ptr<BackingMemory<T>>(new FileBackedMemory<T>());
133123 }
134124
125+ size_t file_size = size * sizeof (T);
135126 static std::atomic<size_t > file_counter{ 0 };
136127 size_t id = file_counter.fetch_add (1 );
128+
137129 std::filesystem::path temp_dir;
138130 try {
139131 temp_dir = std::filesystem::temp_directory_path ();
@@ -142,28 +134,65 @@ template <typename T> class FileBackedMemory : public BackingMemory<T> {
142134 temp_dir = std::filesystem::current_path ();
143135 }
144136
145- filename = temp_dir / (" poly-mmap-" + std::to_string (getpid ()) + " -" + std::to_string (id));
137+ std::string filename = temp_dir / (" poly-mmap-" + std::to_string (getpid ()) + " -" + std::to_string (id));
146138
147- fd = open (filename.c_str (), O_CREAT | O_RDWR | O_TRUNC, 0644 );
148- // Create file
139+ int fd = open (filename.c_str (), O_CREAT | O_RDWR | O_TRUNC, 0644 );
149140 if (fd < 0 ) {
150- throw_or_abort ( " Failed to create backing file: " + filename);
141+ return nullptr ; // Failed to create file
151142 }
152143
153144 // Set file size
154145 if (ftruncate (fd, static_cast <off_t >(file_size)) != 0 ) {
155- throw_or_abort (" Failed to set file size" );
146+ close (fd);
147+ std::filesystem::remove (filename);
148+ return nullptr ; // Failed to set file size
156149 }
157150
158151 // Memory map the file
159152 void * addr = mmap (nullptr , file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
160153 if (addr == MAP_FAILED) {
161- throw_or_abort (" Failed to mmap file: " + std::string (std::strerror (errno)));
154+ close (fd);
155+ std::filesystem::remove (filename);
156+ return nullptr ; // Failed to mmap
162157 }
163158
164- memory = static_cast <T*>(addr);
159+ // Create the FileBackedMemory object using private constructor
160+ auto memory = new FileBackedMemory<T>();
161+ memory->file_size = file_size;
162+ memory->filename = filename;
163+ memory->fd = fd;
164+ memory->memory = static_cast <T*>(addr);
165+
166+ return std::shared_ptr<BackingMemory<T>>(memory);
167+ }
168+
169+ ~FileBackedMemory ()
170+ {
171+ if (file_size == 0 ) {
172+ return ;
173+ }
174+ if (memory != nullptr && file_size > 0 ) {
175+ munmap (memory, file_size);
176+ // Decrement storage usage when FileBackedMemory is freed
177+ current_storage_usage.fetch_sub (file_size);
178+ }
179+ if (fd >= 0 ) {
180+ close (fd);
181+ }
182+ if (!filename.empty ()) {
183+ std::filesystem::remove (filename);
184+ }
165185 }
166186
187+ private:
188+ // Default constructor for empty file-backed memory
189+ FileBackedMemory ()
190+ : BackingMemory<T>()
191+ , file_size(0 )
192+ , fd(-1 )
193+ , memory(nullptr )
194+ {}
195+
167196 size_t file_size;
168197 std::string filename;
169198 int fd;
0 commit comments