| ... | @@ -68,21 +68,22 @@ pub const DirectAllocator = struct { | ... | @@ -68,21 +68,22 @@ pub const DirectAllocator = struct { |
| 68 | if (addr == p.MAP_FAILED) return error.OutOfMemory; | 68 | if (addr == p.MAP_FAILED) return error.OutOfMemory; |
| 69 | if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n]; | 69 | if (alloc_size == n) return @intToPtr([*]u8, addr)[0..n]; |
| 70 | | 70 | |
| 71 | const aligned_addr = (addr & ~usize(alignment - 1)) + alignment; | 71 | const aligned_addr = mem.alignForward(addr, alignment); |
| 72 | | 72 | |
| 73 | // We can unmap the unused portions of our mmap, but we must only | 73 | // Unmap the extra bytes that were only requested in order to guarantee |
| 74 | // pass munmap bytes that exist outside our allocated pages or it | 74 | // that the range of memory we were provided had a proper alignment in |
| 75 | // will happily eat us too. | 75 | // it somewhere. The extra bytes could be at the beginning, or end, or both. |
| 76 | | 76 | const unused_start_len = aligned_addr - addr; |
| 77 | // Since alignment > page_size, we are by definition on a page boundary. | 77 | if (unused_start_len != 0) { |
| 78 | const unused_start = addr; | 78 | const err = p.munmap(addr, unused_start_len); |
| 79 | const unused_len = aligned_addr - 1 - unused_start; | 79 | assert(p.getErrno(err) == 0); |
| 80 | | 80 | } |
| 81 | const err = p.munmap(unused_start, unused_len); | 81 | const aligned_end_addr = std.mem.alignForward(aligned_addr + n, os.page_size); |
| 82 | assert(p.getErrno(err) == 0); | 82 | const unused_end_len = addr + alloc_size - aligned_end_addr; |
| 83 | | 83 | if (unused_end_len != 0) { |
| 84 | // It is impossible that there is an unoccupied page at the top of our | 84 | const err = p.munmap(aligned_end_addr, unused_end_len); |
| 85 | // mmap. | 85 | assert(p.getErrno(err) == 0); |
| | 86 | } |
| 86 | | 87 | |
| 87 | return @intToPtr([*]u8, aligned_addr)[0..n]; | 88 | return @intToPtr([*]u8, aligned_addr)[0..n]; |
| 88 | }, | 89 | }, |