Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions assets/src/01-02.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ const std = @import("std");
const filename = "/tmp/zig-cookbook-01-02.txt";

pub fn main(init: std.process.Init) !void {
if (.windows == @import("builtin").os.tag) {
std.debug.print("MMap is not supported in Windows\n", .{});
return;
}

const io = init.io;
const file = try std.Io.Dir.cwd().createFile(io, filename, .{
.read = true,
Expand All @@ -17,25 +12,22 @@ pub fn main(init: std.process.Init) !void {
defer file.close(io);
const content_to_write = "hello zig cookbook";

// Before mmap, we need to ensure file isn't empty
// Before mapping the memory, we need to ensure file isn't empty
try file.setLength(io, content_to_write.len);

const md = try file.stat(io);
try std.testing.expectEqual(md.size, content_to_write.len);
const length = try file.length(io);
try std.testing.expectEqual(length, content_to_write.len);

const ptr = try std.posix.mmap(
null,
content_to_write.len,
.{ .READ = true, .WRITE = true },
.{ .TYPE = .SHARED },
file.handle,
0,
);
defer std.posix.munmap(ptr);
var mm = try file.createMemoryMap(io, .{ .len = content_to_write.len });
defer mm.destroy(io);

// Write file via mmap
std.mem.copyForwards(u8, ptr, content_to_write);
// Write file via mapped memory
std.mem.copyForwards(u8, mm.memory, content_to_write);
// Synchronize the mapped memory with the file (store it to the file)
try mm.write(io);

// Read file via mmap
try std.testing.expectEqualStrings(content_to_write, ptr);
// Synchronize memory with contents of file
try mm.read(io);
Comment on lines +29 to +30

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To ensure that mm.read(io) is actually reading the data from the file and not just asserting on the existing data in memory, we should clear the memory map buffer using @memset before reading.

    // Clear the memory to ensure we are actually reading from the file
    @memset(mm.memory, 0);
    // Synchronize memory with contents of file
    try mm.read(io);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh Gemini, mm.write() and mm.read() are only there to make sure memory and file are synced after they are called, this does not mean, that the file contents isn't changed before .write() is called. Doing a @memset() to 0 would overwrite the text we wrote previously making the test fail...

// Read via mapped memory
try std.testing.expectEqualStrings(content_to_write, mm.memory);
}
8 changes: 7 additions & 1 deletion src/en-US/01-02-mmap-file.smd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
.layout = "section.shtml",
---

Creates a memory map of a file using [mmap](https://man7.org/linux/man-pages/man2/mmap.2.html) and simulates some non-sequential reads from the file. Using a memory map means you just index into a slice rather than having to deal with seek to navigate a file.
Creates a memory map of a file and simulates some non-sequential reads from the file. Using a memory
map means you just index into a slice rather than having to deal with seek to navigate a file.

This uses [NtCreateSection](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntcreatesection)
and [NtMapViewOfSection](https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-zwmapviewofsection)
on Windows, and [mmap](https://man7.org/linux/man-pages/man2/mmap.2.html) on other operating
systems that support it (When using [`std.Io.Threaded`](https://codeberg.org/ziglang/zig/src/commit/9908b10d928a12731a288bd59068151d386efdac/lib/std/Io/Threaded.zig#L18222-L18355)).

[]($code.siteAsset('src/01-02.zig').language('zig'))
Loading