mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
introduce std.posix.mremap and use it
in std.heap.page_allocator
This commit is contained in:
parent
a0b2a18648
commit
a4d4e086c5
@ -140,7 +140,8 @@ fn free(context: *anyopaque, slice: []u8, alignment: mem.Alignment, return_addre
|
||||
}
|
||||
}
|
||||
|
||||
fn realloc(memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
fn realloc(uncasted_memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
const memory: []align(std.heap.page_size_min) u8 = @alignCast(uncasted_memory);
|
||||
const page_size = std.heap.pageSize();
|
||||
const new_size_aligned = mem.alignForward(usize, new_len, page_size);
|
||||
|
||||
@ -153,7 +154,7 @@ fn realloc(memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
// For shrinking that is not releasing, we will only decommit
|
||||
// the pages not needed anymore.
|
||||
windows.VirtualFree(
|
||||
@as(*anyopaque, @ptrFromInt(new_addr_end)),
|
||||
@ptrFromInt(new_addr_end),
|
||||
old_addr_end - new_addr_end,
|
||||
windows.MEM_DECOMMIT,
|
||||
);
|
||||
@ -171,10 +172,11 @@ fn realloc(memory: []u8, new_len: usize, may_move: bool) ?[*]u8 {
|
||||
if (new_size_aligned == page_aligned_len)
|
||||
return memory.ptr;
|
||||
|
||||
const mremap_available = false; // native_os == .linux;
|
||||
const mremap_available = native_os == .linux;
|
||||
if (mremap_available) {
|
||||
// TODO: if the next_mmap_addr_hint is within the remapped range, update it
|
||||
return posix.mremap(memory, new_len, .{ .MAYMOVE = may_move }, null) catch return null;
|
||||
const new_memory = posix.mremap(memory.ptr, memory.len, new_len, .{ .MAYMOVE = may_move }, null) catch return null;
|
||||
return new_memory.ptr;
|
||||
}
|
||||
|
||||
if (new_size_aligned < page_aligned_len) {
|
||||
|
||||
@ -305,6 +305,13 @@ pub const MAP = switch (native_arch) {
|
||||
else => @compileError("missing std.os.linux.MAP constants for this architecture"),
|
||||
};
|
||||
|
||||
pub const MREMAP = packed struct(u32) {
|
||||
MAYMOVE: bool = false,
|
||||
FIXED: bool = false,
|
||||
DONTUNMAP: bool = false,
|
||||
_: u29 = 0,
|
||||
};
|
||||
|
||||
pub const O = switch (native_arch) {
|
||||
.x86_64 => packed struct(u32) {
|
||||
ACCMODE: ACCMODE = .RDONLY,
|
||||
@ -934,6 +941,17 @@ pub fn mprotect(address: [*]const u8, length: usize, protection: usize) usize {
|
||||
return syscall3(.mprotect, @intFromPtr(address), length, protection);
|
||||
}
|
||||
|
||||
pub fn mremap(old_addr: ?[*]const u8, old_len: usize, new_len: usize, flags: MREMAP, new_addr: ?[*]const u8) usize {
|
||||
return syscall5(
|
||||
.mremap,
|
||||
@intFromPtr(old_addr),
|
||||
old_len,
|
||||
new_len,
|
||||
@as(u32, @bitCast(flags)),
|
||||
@intFromPtr(new_addr),
|
||||
);
|
||||
}
|
||||
|
||||
pub const MSF = struct {
|
||||
pub const ASYNC = 1;
|
||||
pub const INVALIDATE = 2;
|
||||
|
||||
@ -83,6 +83,7 @@ pub const MAP = system.MAP;
|
||||
pub const MAX_ADDR_LEN = system.MAX_ADDR_LEN;
|
||||
pub const MFD = system.MFD;
|
||||
pub const MMAP2_UNIT = system.MMAP2_UNIT;
|
||||
pub const MREMAP = system.MREMAP;
|
||||
pub const MSF = system.MSF;
|
||||
pub const MSG = system.MSG;
|
||||
pub const NAME_MAX = system.NAME_MAX;
|
||||
@ -4809,6 +4810,40 @@ pub fn munmap(memory: []align(page_size_min) const u8) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub const MRemapError = error{
|
||||
LockedMemoryLimitExceeded,
|
||||
/// Either a bug in the calling code, or the operating system abused the
|
||||
/// EINVAL error code.
|
||||
InvalidSyscallParameters,
|
||||
OutOfMemory,
|
||||
} || UnexpectedError;
|
||||
|
||||
pub fn mremap(
|
||||
old_address: ?[*]align(page_size_min) u8,
|
||||
old_len: usize,
|
||||
new_len: usize,
|
||||
flags: system.MREMAP,
|
||||
new_address: ?[*]align(page_size_min) u8,
|
||||
) MRemapError![]align(page_size_min) u8 {
|
||||
const rc = system.mremap(old_address, old_len, new_len, flags, new_address);
|
||||
const err: E = if (builtin.link_libc) blk: {
|
||||
if (rc != std.c.MAP_FAILED) return @as([*]align(page_size_min) u8, @ptrCast(@alignCast(rc)))[0..new_len];
|
||||
break :blk @enumFromInt(system._errno().*);
|
||||
} else blk: {
|
||||
const err = errno(rc);
|
||||
if (err == .SUCCESS) return @as([*]align(page_size_min) u8, @ptrFromInt(rc))[0..new_len];
|
||||
break :blk err;
|
||||
};
|
||||
switch (err) {
|
||||
.SUCCESS => unreachable,
|
||||
.AGAIN => return error.LockedMemoryLimitExceeded,
|
||||
.INVAL => return error.InvalidSyscallParameters,
|
||||
.NOMEM => return error.OutOfMemory,
|
||||
.FAULT => unreachable,
|
||||
else => return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub const MSyncError = error{
|
||||
UnmappedMemory,
|
||||
PermissionDenied,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user