Merge pull request #222 from ZystemOS/feature/zig-update

Add new parameters for resize and alloc
This commit is contained in:
Sam Tebbs 2020-08-15 21:39:22 +01:00 committed by GitHub
commit 4cdc6e47ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 24 deletions

View file

@ -345,7 +345,7 @@ test "init with files cleans memory if OutOfMemory" {
} }
// Ensure we have freed any memory allocated // Ensure we have freed any memory allocated
try std.testing.allocator_instance.validate(); std.testing.expectEqual(false, std.testing.allocator_instance.detectLeaks());
} }
} }
@ -413,6 +413,14 @@ test "open fail with invalid flags" {
} }
test "open fail with NoSuchFileOrDir" { test "open fail with NoSuchFileOrDir" {
var ramdisk_bytes = try createInitrd(std.testing.allocator);
defer std.testing.allocator.free(ramdisk_bytes);
var initrd_stream = std.io.fixedBufferStream(ramdisk_bytes);
var fs = try InitrdFS.init(&initrd_stream, std.testing.allocator);
defer fs.deinit();
vfs.setRoot(fs.root_node);
expectError(error.NoSuchFileOrDir, vfs.openFile("/text10.txt", .NO_CREATION)); expectError(error.NoSuchFileOrDir, vfs.openFile("/text10.txt", .NO_CREATION));
expectError(error.NoSuchFileOrDir, vfs.openDir("/temp/", .NO_CREATION)); expectError(error.NoSuchFileOrDir, vfs.openDir("/temp/", .NO_CREATION));
} }

View file

@ -246,6 +246,7 @@ fn traversePath(path: []const u8, flags: OpenFlags) (Allocator.Error || Error)!*
child: []const u8, child: []const u8,
const Self = @This(); const Self = @This();
fn func(split: *std.mem.SplitIterator, node: *Node, rec_flags: OpenFlags) (Allocator.Error || Error)!Self { fn func(split: *std.mem.SplitIterator, node: *Node, rec_flags: OpenFlags) (Allocator.Error || Error)!Self {
// Get segment string. This will not be unreachable as we've made sure the spliterator has more segments left // Get segment string. This will not be unreachable as we've made sure the spliterator has more segments left
const seg = split.next() orelse unreachable; const seg = split.next() orelse unreachable;
@ -560,8 +561,8 @@ test "mount" {
// The root fs // The root fs
var testfs = try testInitFs(allocator); var testfs = try testInitFs(allocator);
defer testfs.deinit();
defer allocator.destroy(testfs); defer allocator.destroy(testfs);
defer testfs.deinit();
testfs.instance = 1; testfs.instance = 1;
root = testfs.tree.val; root = testfs.tree.val;
@ -594,8 +595,8 @@ test "mount" {
test "traversePath" { test "traversePath" {
var allocator = testing.allocator; var allocator = testing.allocator;
var testfs = try testInitFs(allocator); var testfs = try testInitFs(allocator);
defer testfs.deinit();
defer allocator.destroy(testfs); defer allocator.destroy(testfs);
defer testfs.deinit();
root = testfs.tree.val; root = testfs.tree.val;
// Get the root // Get the root
@ -649,8 +650,8 @@ test "isFile" {
test "open" { test "open" {
var testfs = try testInitFs(testing.allocator); var testfs = try testInitFs(testing.allocator);
defer testfs.deinit();
defer testing.allocator.destroy(testfs); defer testing.allocator.destroy(testfs);
defer testfs.deinit();
root = testfs.tree.val; root = testfs.tree.val;
// Creating a file // Creating a file
@ -698,8 +699,8 @@ test "open" {
test "read" { test "read" {
var testfs = try testInitFs(testing.allocator); var testfs = try testInitFs(testing.allocator);
defer testfs.deinit();
defer testing.allocator.destroy(testfs); defer testing.allocator.destroy(testfs);
defer testfs.deinit();
root = testfs.tree.val; root = testfs.tree.val;
var test_file = try openFile("/foo.txt", .CREATE_FILE); var test_file = try openFile("/foo.txt", .CREATE_FILE);
@ -736,8 +737,8 @@ test "read" {
test "write" { test "write" {
var testfs = try testInitFs(testing.allocator); var testfs = try testInitFs(testing.allocator);
defer testfs.deinit();
defer testing.allocator.destroy(testfs); defer testing.allocator.destroy(testfs);
defer testfs.deinit();
root = testfs.tree.val; root = testfs.tree.val;
var test_file = try openFile("/foo.txt", .CREATE_FILE); var test_file = try openFile("/foo.txt", .CREATE_FILE);

View file

@ -182,8 +182,10 @@ const FreeListAllocator = struct {
/// Arguments: /// Arguments:
/// IN allocator: *std.Allocator - The allocator to resize within. /// IN allocator: *std.Allocator - The allocator to resize within.
/// IN old_mem: []u8 - The buffer to resize. /// IN old_mem: []u8 - The buffer to resize.
/// IN old_align: u29 - The original alignment for old_mem.
/// IN new_size: usize - What to resize to. /// IN new_size: usize - What to resize to.
/// IN size_alignment: u29 - The alignment that the size should have. /// IN size_alignment: u29 - The alignment that the size should have.
/// IN ret_addr: usize - The return address passed by the high-level Allocator API. This is ignored
/// ///
/// Return: usize /// Return: usize
/// The new size of the buffer, which will be new_size if the operation was successful. /// The new size of the buffer, which will be new_size if the operation was successful.
@ -191,7 +193,7 @@ const FreeListAllocator = struct {
/// Error: std.Allocator.Error /// Error: std.Allocator.Error
/// std.Allocator.Error.OutOfMemory - If there wasn't enough free memory to expand into /// std.Allocator.Error.OutOfMemory - If there wasn't enough free memory to expand into
/// ///
fn resize(allocator: *Allocator, old_mem: []u8, new_size: usize, size_alignment: u29) Allocator.Error!usize { fn resize(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, size_alignment: u29, ret_addr: usize) Allocator.Error!usize {
var self = @fieldParentPtr(FreeListAllocator, "allocator", allocator); var self = @fieldParentPtr(FreeListAllocator, "allocator", allocator);
if (new_size == 0) { if (new_size == 0) {
self.free(old_mem); self.free(old_mem);
@ -304,6 +306,7 @@ const FreeListAllocator = struct {
/// IN size: usize - The amount of memory requested /// IN size: usize - The amount of memory requested
/// IN alignment: u29 - The alignment that the address of the allocated memory should have /// IN alignment: u29 - The alignment that the address of the allocated memory should have
/// IN size_alignment: u29 - The alignment that the length of the allocated memory should have /// IN size_alignment: u29 - The alignment that the length of the allocated memory should have
/// IN ret_addr: usize - The return address passed by the high-level Allocator API. This is ignored
/// ///
/// Return: []u8 /// Return: []u8
/// The allocated memory /// The allocated memory
@ -311,7 +314,7 @@ const FreeListAllocator = struct {
/// Error: std.Allocator.Error /// Error: std.Allocator.Error
/// std.Allocator.Error.OutOfMemory - There wasn't enough memory left to fulfill the request /// std.Allocator.Error.OutOfMemory - There wasn't enough memory left to fulfill the request
/// ///
pub fn alloc(allocator: *Allocator, size: usize, alignment: u29, size_alignment: u29) Allocator.Error![]u8 { pub fn alloc(allocator: *Allocator, size: usize, alignment: u29, size_alignment: u29, ret_addr: usize) Allocator.Error![]u8 {
var self = @fieldParentPtr(FreeListAllocator, "allocator", allocator); var self = @fieldParentPtr(FreeListAllocator, "allocator", allocator);
if (self.first_free == null) return Allocator.Error.OutOfMemory; if (self.first_free == null) return Allocator.Error.OutOfMemory;
@ -433,7 +436,7 @@ const FreeListAllocator = struct {
std.debug.warn("", .{}); std.debug.warn("", .{});
const alloc0 = try alloc(allocator, 64, 0, 0); const alloc0 = try alloc(allocator, 64, 0, 0, @returnAddress());
const alloc0_addr = @ptrToInt(alloc0.ptr); const alloc0_addr = @ptrToInt(alloc0.ptr);
// Should be at the start of the heap // Should be at the start of the heap
testing.expectEqual(alloc0_addr, start); testing.expectEqual(alloc0_addr, start);
@ -446,7 +449,7 @@ const FreeListAllocator = struct {
std.debug.warn("", .{}); std.debug.warn("", .{});
// 64 bytes aligned to 4 bytes // 64 bytes aligned to 4 bytes
const alloc1 = try alloc(allocator, 64, 4, 0); const alloc1 = try alloc(allocator, 64, 4, 0, @returnAddress());
const alloc1_addr = @ptrToInt(alloc1.ptr); const alloc1_addr = @ptrToInt(alloc1.ptr);
const alloc1_end = alloc1_addr + alloc1.len; const alloc1_end = alloc1_addr + alloc1.len;
// Should be to the right of the first allocation, with some alignment padding in between // Should be to the right of the first allocation, with some alignment padding in between
@ -459,7 +462,7 @@ const FreeListAllocator = struct {
testing.expectEqual(header.next_free, null); testing.expectEqual(header.next_free, null);
testing.expectEqual(free_list.first_free, header); testing.expectEqual(free_list.first_free, header);
const alloc2 = try alloc(allocator, 64, 256, 0); const alloc2 = try alloc(allocator, 64, 256, 0, @returnAddress());
const alloc2_addr = @ptrToInt(alloc2.ptr); const alloc2_addr = @ptrToInt(alloc2.ptr);
const alloc2_end = alloc2_addr + alloc2.len; const alloc2_end = alloc2_addr + alloc2.len;
testing.expect(alloc1_end < alloc2_addr); testing.expect(alloc1_end < alloc2_addr);
@ -475,7 +478,7 @@ const FreeListAllocator = struct {
} }
// Try allocating something smaller than @sizeOf(Header). This should scale up to @sizeOf(Header) // Try allocating something smaller than @sizeOf(Header). This should scale up to @sizeOf(Header)
var alloc3 = try alloc(allocator, 1, 0, 0); var alloc3 = try alloc(allocator, 1, 0, 0, @returnAddress());
const alloc3_addr = @ptrToInt(alloc3.ptr); const alloc3_addr = @ptrToInt(alloc3.ptr);
const alloc3_end = alloc3_addr + @sizeOf(Header); const alloc3_end = alloc3_addr + @sizeOf(Header);
const header2 = @intToPtr(*Header, alloc3_end); const header2 = @intToPtr(*Header, alloc3_end);
@ -486,10 +489,10 @@ const FreeListAllocator = struct {
// Attempting to allocate more than the size of the largest free node should fail // Attempting to allocate more than the size of the largest free node should fail
const remaining_size = second_header.size + @sizeOf(Header); const remaining_size = second_header.size + @sizeOf(Header);
testing.expectError(Allocator.Error.OutOfMemory, alloc(&free_list.allocator, remaining_size + 1, 0, 0)); testing.expectError(Allocator.Error.OutOfMemory, alloc(&free_list.allocator, remaining_size + 1, 0, 0, @returnAddress()));
// Alloc a non aligned to header // Alloc a non aligned to header
var alloc4 = try alloc(allocator, 13, 1, 0); var alloc4 = try alloc(allocator, 13, 1, 0, @returnAddress());
const alloc4_addr = @ptrToInt(alloc4.ptr); const alloc4_addr = @ptrToInt(alloc4.ptr);
const alloc4_end = alloc4_addr + std.mem.alignForward(13, @alignOf(Header)); const alloc4_end = alloc4_addr + std.mem.alignForward(13, @alignOf(Header));
const header3 = @intToPtr(*Header, alloc4_end); const header3 = @intToPtr(*Header, alloc4_end);
@ -512,9 +515,9 @@ const FreeListAllocator = struct {
var free_list = &(try FreeListAllocator.init(start, size)); var free_list = &(try FreeListAllocator.init(start, size));
var allocator = &free_list.allocator; var allocator = &free_list.allocator;
var alloc0 = try alloc(allocator, 128, 0, 0); var alloc0 = try alloc(allocator, 128, 0, 0, @returnAddress());
var alloc1 = try alloc(allocator, 256, 0, 0); var alloc1 = try alloc(allocator, 256, 0, 0, @returnAddress());
var alloc2 = try alloc(allocator, 64, 0, 0); var alloc2 = try alloc(allocator, 64, 0, 0, @returnAddress());
// There should be a single free node after alloc2 // There should be a single free node after alloc2
const free_node3 = @intToPtr(*Header, @ptrToInt(alloc2.ptr) + alloc2.len); const free_node3 = @intToPtr(*Header, @ptrToInt(alloc2.ptr) + alloc2.len);
@ -551,14 +554,14 @@ const FreeListAllocator = struct {
var free_list = &(try FreeListAllocator.init(start, size)); var free_list = &(try FreeListAllocator.init(start, size));
var allocator = &free_list.allocator; var allocator = &free_list.allocator;
var alloc0 = try alloc(allocator, 128, 0, 0); var alloc0 = try alloc(allocator, 128, 0, 0, @returnAddress());
var alloc1 = try alloc(allocator, 256, 0, 0); var alloc1 = try alloc(allocator, 256, 0, 0, @returnAddress());
// Expanding alloc0 should fail as alloc1 is right next to it // Expanding alloc0 should fail as alloc1 is right next to it
testing.expectError(Allocator.Error.OutOfMemory, resize(&free_list.allocator, alloc0, 136, 0)); testing.expectError(Allocator.Error.OutOfMemory, resize(&free_list.allocator, alloc0, 0, 136, 0, @returnAddress()));
// Expanding alloc1 should succeed // Expanding alloc1 should succeed
testing.expectEqual(try resize(allocator, alloc1, 512, 0), 512); testing.expectEqual(try resize(allocator, alloc1, 0, 512, 0, @returnAddress()), 512);
alloc1 = alloc1.ptr[0..512]; alloc1 = alloc1.ptr[0..512];
// And there should be a free node on the right of it // And there should be a free node on the right of it
var header = @intToPtr(*Header, @ptrToInt(alloc1.ptr) + 512); var header = @intToPtr(*Header, @ptrToInt(alloc1.ptr) + 512);
@ -567,7 +570,7 @@ const FreeListAllocator = struct {
testing.expectEqual(free_list.first_free, header); testing.expectEqual(free_list.first_free, header);
// Shrinking alloc1 should produce a big free node on the right // Shrinking alloc1 should produce a big free node on the right
testing.expectEqual(try resize(allocator, alloc1, 128, 0), 128); testing.expectEqual(try resize(allocator, alloc1, 0, 128, 0, @returnAddress()), 128);
alloc1 = alloc1.ptr[0..128]; alloc1 = alloc1.ptr[0..128];
header = @intToPtr(*Header, @ptrToInt(alloc1.ptr) + 128); header = @intToPtr(*Header, @ptrToInt(alloc1.ptr) + 128);
testing.expectEqual(header.size, size - 128 - 128 - @sizeOf(Header)); testing.expectEqual(header.size, size - 128 - 128 - @sizeOf(Header));
@ -575,9 +578,9 @@ const FreeListAllocator = struct {
testing.expectEqual(free_list.first_free, header); testing.expectEqual(free_list.first_free, header);
// Shrinking by less space than would allow for a new Header shouldn't work // Shrinking by less space than would allow for a new Header shouldn't work
testing.expectEqual(resize(allocator, alloc1, alloc1.len - @sizeOf(Header) / 2, 0), 128); testing.expectEqual(resize(allocator, alloc1, 0, alloc1.len - @sizeOf(Header) / 2, 0, @returnAddress()), 128);
// Shrinking to less space than would allow for a new Header shouldn't work // Shrinking to less space than would allow for a new Header shouldn't work
testing.expectEqual(resize(allocator, alloc1, @sizeOf(Header) / 2, 0), @sizeOf(Header)); testing.expectEqual(resize(allocator, alloc1, 0, @sizeOf(Header) / 2, 0, @returnAddress()), @sizeOf(Header));
} }
}; };