| ... | @@ -7998,7 +7998,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) | ... | @@ -7998,7 +7998,7 @@ fn fileReadStreamingPosix(userdata: ?*anyopaque, file: File, data: []const []u8) |
| 7998 | .FAULT => |err| return errnoBug(err), | 7998 | .FAULT => |err| return errnoBug(err), |
| 7999 | .AGAIN => return error.WouldBlock, | 7999 | .AGAIN => return error.WouldBlock, |
| 8000 | .BADF => |err| { | 8000 | .BADF => |err| { |
| 8001 | if (native_os == .wasi) return error.NotOpenForReading; // File operation on directory. | 8001 | if (native_os == .wasi) return error.IsDir; // File operation on directory. |
| 8002 | return errnoBug(err); // File descriptor used after closed. | 8002 | return errnoBug(err); // File descriptor used after closed. |
| 8003 | }, | 8003 | }, |
| 8004 | .IO => return error.InputOutput, | 8004 | .IO => return error.InputOutput, |
| ... | @@ -8089,7 +8089,7 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 | ... | @@ -8089,7 +8089,7 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 |
| 8089 | syscall.finish(); | 8089 | syscall.finish(); |
| 8090 | return nread; | 8090 | return nread; |
| 8091 | }, | 8091 | }, |
| 8092 | .INTR => { | 8092 | .INTR, .TIMEDOUT => { |
| 8093 | try syscall.checkCancel(); | 8093 | try syscall.checkCancel(); |
| 8094 | continue; | 8094 | continue; |
| 8095 | }, | 8095 | }, |
| ... | @@ -8103,7 +8103,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 | ... | @@ -8103,7 +8103,6 @@ fn fileReadPositionalPosix(userdata: ?*anyopaque, file: File, data: []const []u8 |
| 8103 | .ISDIR => return syscall.fail(error.IsDir), | 8103 | .ISDIR => return syscall.fail(error.IsDir), |
| 8104 | .NOBUFS => return syscall.fail(error.SystemResources), | 8104 | .NOBUFS => return syscall.fail(error.SystemResources), |
| 8105 | .NOMEM => return syscall.fail(error.SystemResources), | 8105 | .NOMEM => return syscall.fail(error.SystemResources), |
| 8106 | .TIMEDOUT => return syscall.fail(error.Timeout), | | |
| 8107 | .NXIO => return syscall.fail(error.Unseekable), | 8106 | .NXIO => return syscall.fail(error.Unseekable), |
| 8108 | .SPIPE => return syscall.fail(error.Unseekable), | 8107 | .SPIPE => return syscall.fail(error.Unseekable), |
| 8109 | .OVERFLOW => return syscall.fail(error.Unseekable), | 8108 | .OVERFLOW => return syscall.fail(error.Unseekable), |
| ... | @@ -12588,7 +12587,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { | ... | @@ -12588,7 +12587,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { |
| 12588 | .atime = timestampFromPosix(&atime), | 12587 | .atime = timestampFromPosix(&atime), |
| 12589 | .mtime = timestampFromPosix(&mtime), | 12588 | .mtime = timestampFromPosix(&mtime), |
| 12590 | .ctime = timestampFromPosix(&ctime), | 12589 | .ctime = timestampFromPosix(&ctime), |
| 12591 | .block_size = st.blksize, | 12590 | .block_size = @intCast(st.blksize), |
| 12592 | }; | 12591 | }; |
| 12593 | } | 12592 | } |
| 12594 | | 12593 | |
| ... | @@ -16292,9 +16291,14 @@ fn createFileMap( | ... | @@ -16292,9 +16291,14 @@ fn createFileMap( |
| 16292 | .WRITE = protection.write, | 16291 | .WRITE = protection.write, |
| 16293 | .EXEC = protection.execute, | 16292 | .EXEC = protection.execute, |
| 16294 | }; | 16293 | }; |
| 16295 | const flags: posix.MAP = .{ | 16294 | const flags: posix.MAP = switch (native_os) { |
| 16296 | .TYPE = if (native_os == .linux) .SHARED_VALIDATE else .SHARED, | 16295 | .linux => .{ |
| 16297 | .POPULATE = populate, | 16296 | .TYPE = .SHARED_VALIDATE, |
| | 16297 | .POPULATE = populate, |
| | 16298 | }, |
| | 16299 | else => .{ |
| | 16300 | .TYPE = .SHARED, |
| | 16301 | }, |
| 16298 | }; | 16302 | }; |
| 16299 | | 16303 | |
| 16300 | const page_align = std.heap.page_size_min; | 16304 | const page_align = std.heap.page_size_min; |
| ... | @@ -16348,20 +16352,20 @@ fn createFileMap( | ... | @@ -16348,20 +16352,20 @@ fn createFileMap( |
| 16348 | fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { | 16352 | fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 16349 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 16353 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 16350 | const memory = mm.memory; | 16354 | const memory = mm.memory; |
| 16351 | if (mm.section) |section| { | 16355 | if (mm.section) |section| switch (native_os) { |
| 16352 | if (is_windows) { | 16356 | .windows => { |
| 16353 | const current_process: windows.HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))); | 16357 | const current_process: windows.HANDLE = @ptrFromInt(@as(usize, @bitCast(@as(isize, -1)))); |
| 16354 | _ = windows.ntdll.NtUnmapViewOfSection(current_process, memory.ptr); | 16358 | _ = windows.ntdll.NtUnmapViewOfSection(current_process, memory.ptr); |
| 16355 | windows.CloseHandle(section); | 16359 | windows.CloseHandle(section); |
| 16356 | } else { | 16360 | }, |
| 16357 | switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { | 16361 | .wasi => unreachable, |
| 16358 | .SUCCESS => {}, | 16362 | else => switch (posix.errno(posix.system.munmap(memory.ptr, memory.len))) { |
| 16359 | else => |e| { | 16363 | .SUCCESS => {}, |
| 16360 | if (builtin.mode == .Debug) | 16364 | else => |e| { |
| 16361 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); | 16365 | if (builtin.mode == .Debug) |
| 16362 | }, | 16366 | std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ memory.len, memory.ptr, e }); |
| 16363 | } | 16367 | }, |
| 16364 | } | 16368 | }, |
| 16365 | } else { | 16369 | } else { |
| 16366 | const gpa = t.allocator; | 16370 | const gpa = t.allocator; |
| 16367 | gpa.rawFree(memory, .fromByteUnits(std.heap.pageSize()), @returnAddress()); | 16371 | gpa.rawFree(memory, .fromByteUnits(std.heap.pageSize()), @returnAddress()); |
| ... | @@ -16372,15 +16376,17 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { | ... | @@ -16372,15 +16376,17 @@ fn fileMemoryMapDestroy(userdata: ?*anyopaque, mm: *File.MemoryMap) void { |
| 16372 | fn fileMemoryMapSetLength( | 16376 | fn fileMemoryMapSetLength( |
| 16373 | userdata: ?*anyopaque, | 16377 | userdata: ?*anyopaque, |
| 16374 | mm: *File.MemoryMap, | 16378 | mm: *File.MemoryMap, |
| 16375 | new_len: usize, | 16379 | options: File.MemoryMap.CreateOptions, |
| 16376 | ) File.MemoryMap.SetLengthError!void { | 16380 | ) File.MemoryMap.SetLengthError!void { |
| 16377 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 16381 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 16378 | const page_size = std.heap.pageSize(); | 16382 | const page_size = std.heap.pageSize(); |
| 16379 | const alignment: Alignment = .fromByteUnits(page_size); | 16383 | const alignment: Alignment = .fromByteUnits(page_size); |
| 16380 | const page_align = std.heap.page_size_min; | 16384 | const page_align = std.heap.page_size_min; |
| | 16385 | const old_memory = mm.memory; |
| | 16386 | const new_len = options.len; |
| 16381 | | 16387 | |
| 16382 | if (mm.section) |section| { | 16388 | if (mm.section) |section| { |
| 16383 | if (alignment.forward(new_len) == alignment.forward(mm.memory.len)) { | 16389 | if (alignment.forward(new_len) == alignment.forward(old_memory.len)) { |
| 16384 | mm.memory.len = new_len; | 16390 | mm.memory.len = new_len; |
| 16385 | return; | 16391 | return; |
| 16386 | } | 16392 | } |
| ... | @@ -16390,12 +16396,12 @@ fn fileMemoryMapSetLength( | ... | @@ -16390,12 +16396,12 @@ fn fileMemoryMapSetLength( |
| 16390 | @panic("TODO"); | 16396 | @panic("TODO"); |
| 16391 | }, | 16397 | }, |
| 16392 | .wasi => unreachable, | 16398 | .wasi => unreachable, |
| 16393 | else => { | 16399 | .linux => { |
| 16394 | const flags: posix.MREMAP = .{ .MAYMOVE = true }; | 16400 | const flags: posix.MREMAP = .{ .MAYMOVE = true }; |
| 16395 | const addr_hint: ?[*]const u8 = null; | 16401 | const addr_hint: ?[*]const u8 = null; |
| 16396 | const new_memory = while (true) { | 16402 | const new_memory = while (true) { |
| 16397 | const syscall: Syscall = try .start(); | 16403 | const syscall: Syscall = try .start(); |
| 16398 | const rc = posix.system.mremap(mm.memory.ptr, mm.memory.len, new_len, flags, addr_hint); | 16404 | const rc = posix.system.mremap(old_memory.ptr, old_memory.len, new_len, flags, addr_hint); |
| 16399 | syscall.finish(); | 16405 | syscall.finish(); |
| 16400 | const err: posix.E = if (builtin.link_libc) e: { | 16406 | const err: posix.E = if (builtin.link_libc) e: { |
| 16401 | if (rc != std.c.MAP_FAILED) break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..new_len]; | 16407 | if (rc != std.c.MAP_FAILED) break @as([*]align(page_align) u8, @ptrCast(@alignCast(rc)))[0..new_len]; |
| ... | @@ -16417,6 +16423,30 @@ fn fileMemoryMapSetLength( | ... | @@ -16417,6 +16423,30 @@ fn fileMemoryMapSetLength( |
| 16417 | }; | 16423 | }; |
| 16418 | mm.memory = new_memory; | 16424 | mm.memory = new_memory; |
| 16419 | }, | 16425 | }, |
| | 16426 | else => { |
| | 16427 | switch (posix.errno(posix.system.munmap(old_memory.ptr, old_memory.len))) { |
| | 16428 | .SUCCESS => {}, |
| | 16429 | else => |e| { |
| | 16430 | if (builtin.mode == .Debug) std.log.err("failed to unmap {d} bytes at {*}: {t}", .{ |
| | 16431 | old_memory.len, old_memory.ptr, e, |
| | 16432 | }); |
| | 16433 | // munmap must be infallible, or we cannot design reliable software. |
| | 16434 | return error.Unexpected; |
| | 16435 | }, |
| | 16436 | } |
| | 16437 | if (createFileMap(mm.file, options.protection, mm.offset, options.populate, new_len)) |result| { |
| | 16438 | mm.* = result; |
| | 16439 | return; |
| | 16440 | } else |err| switch (err) { |
| | 16441 | error.OperationUnsupported, |
| | 16442 | error.Unseekable, |
| | 16443 | error.SectionOversize, |
| | 16444 | error.MappingAlreadyExists, |
| | 16445 | error.FileLockConflict, |
| | 16446 | => return error.Unexpected, // It worked before on the same open file. |
| | 16447 | else => |e| return e, |
| | 16448 | } |
| | 16449 | }, |
| 16420 | } | 16450 | } |
| 16421 | } else { | 16451 | } else { |
| 16422 | const gpa = t.allocator; | 16452 | const gpa = t.allocator; |