84 static thread_local size_t last_handled_file_id = -1;
91 if (address >= link_file->memory && address < link_file->memory + link_file->length) {
97 if (file ==
nullptr) {
118 if (file->
id == last_handled_file_id) {
126 "Error: Unexpected exception in mapped file which was already remapped with zeros.");
130 last_handled_file_id = file->
id;
134 last_handled_file_id = file->
id;
138 print_error(
"Error: Could not replace mapped file with zeros.");
146using MapViewOfFile3Fn = PVOID(WINAPI *)(HANDLE FileMapping,
152 ULONG PageProtection,
153 MEM_EXTENDED_PARAMETER *ExtendedParameters,
154 ULONG ParameterCount);
156using VirtualAlloc2Fn = PVOID(WINAPI *)(HANDLE Process,
160 ULONG PageProtection,
161 MEM_EXTENDED_PARAMETER *ExtendedParameters,
162 ULONG ParameterCount);
167static MapViewOfFile3Fn mmap_MapViewOfFile3 =
nullptr;
169static VirtualAlloc2Fn mmap_VirtualAlloc2 =
nullptr;
175 HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
176 WriteFile(stderr_handle, buffer,
length,
nullptr,
nullptr);
181 if (!UnmapViewOfFileEx(file->
memory, MEM_PRESERVE_PLACEHOLDER)) {
185 if (!CloseHandle(file->
handle)) {
189 ULARGE_INTEGER length_ularge_int;
190 length_ularge_int.QuadPart = file->
length;
191 file->
handle = CreateFileMapping(INVALID_HANDLE_VALUE,
194 length_ularge_int.HighPart,
195 length_ularge_int.LowPart,
197 if (file->
handle ==
nullptr) {
201 void *memory = mmap_MapViewOfFile3(file->
handle,
206 MEM_REPLACE_PLACEHOLDER,
210 if (memory ==
nullptr) {
219static LONG page_exception_handler(EXCEPTION_POINTERS *ExceptionInfo)
noexcept
225 if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR ||
226 ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
228 if (ExceptionInfo->ExceptionRecord->NumberParameters >= 2) {
231 if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == 1) {
232 return EXCEPTION_CONTINUE_SEARCH;
234 const void *address =
reinterpret_cast<const void *
>(
235 ExceptionInfo->ExceptionRecord->ExceptionInformation[1]);
237 return EXCEPTION_CONTINUE_EXECUTION;
241 return EXCEPTION_CONTINUE_SEARCH;
255 HMODULE kernelbase = ::LoadLibraryA(
"kernelbase.dll");
257 mmap_MapViewOfFile3 =
reinterpret_cast<MapViewOfFile3Fn
>(
258 ::GetProcAddress(kernelbase,
"MapViewOfFile3"));
259 mmap_VirtualAlloc2 =
reinterpret_cast<VirtualAlloc2Fn
>(
260 ::GetProcAddress(kernelbase,
"VirtualAlloc2"));
262 if (mmap_MapViewOfFile3 && mmap_VirtualAlloc2) {
264 AddVectoredExceptionHandler(
FALSE, page_exception_handler);
267 print_error(
"Could not load necessary functions for MMAP error handling.");
278 if (write(STDERR_FILENO, buffer,
length) < 0) {
286 const void *mapped_memory = mmap(
287 file->
memory, file->
length, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
288 if (mapped_memory == MAP_FAILED) {
334 struct sigaction newact = {{
nullptr}}, oldact = {{
nullptr}};
337 newact.sa_flags = SA_SIGINFO;
339 if (sigaction(SIGBUS, &newact, &oldact)) {
369 static std::atomic_size_t id_counter = 0;
371 void *memory, *handle =
nullptr;
384 memory = mmap(
nullptr,
length, PROT_READ, MAP_PRIVATE, fd, 0);
385 if (memory == MAP_FAILED) {
390 void *file_handle = (
void *)_get_osfhandle(fd);
397 if (mmap_MapViewOfFile3 && mmap_VirtualAlloc2) {
398 memory = mmap_VirtualAlloc2(
nullptr,
401 MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
405 if (memory ==
nullptr) {
409 handle = CreateFileMapping(file_handle,
nullptr, PAGE_READONLY, 0, 0,
nullptr);
410 if (handle ==
nullptr) {
411 VirtualFree(memory, 0, MEM_RELEASE);
415 if (mmap_MapViewOfFile3(handle,
420 MEM_REPLACE_PLACEHOLDER,
425 VirtualFree(memory, 0, MEM_RELEASE);
433 handle = CreateFileMapping(file_handle,
nullptr, PAGE_READONLY, 0, 0,
nullptr);
434 if (handle ==
nullptr) {
438 memory = MapViewOfFile(handle, FILE_MAP_READ, 0, 0, 0);
439 if (memory ==
nullptr) {
448 file->
memory =
static_cast<char *
>(memory);
451 file->
id = id_counter++;
493 UnmapViewOfFile(file->
memory);
494 CloseHandle(file->
handle);
File and directory operations.
int64_t BLI_lseek(int fd, int64_t offset, int whence)
static void print_error(const char *message)
void BLI_mmap_free(BLI_mmap_file *file)
bool BLI_mmap_read(BLI_mmap_file *file, void *dest, size_t offset, size_t length)
static blender::Mutex mmap_mutex
static bool try_handle_error_for_address(const void *address)
BLI_mmap_file * BLI_mmap_open(int fd)
static blender::Vector< BLI_mmap_file * > & open_mmaps_vector()
static void sigbus_handler(int sig, siginfo_t *siginfo, void *ptr) noexcept
static bool try_map_zeros(BLI_mmap_file *file)
static struct sigaction next_handler
size_t BLI_mmap_get_length(const BLI_mmap_file *file)
bool BLI_mmap_any_io_error(const BLI_mmap_file *file)
static void error_handler_remove(BLI_mmap_file *file)
void * BLI_mmap_get_pointer(BLI_mmap_file *file)
static void error_handler_add(BLI_mmap_file *file)
static bool ensure_mmap_initialized()
#define BLI_string_join(...)
Compatibility-like things for windows.
Read Guarded memory(de)allocation.
float length(VecOp< float, D >) RET
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)