diff options
author | 2021-10-04 18:37:51 -0700 | |
---|---|---|
committer | 2021-10-04 18:37:51 -0700 | |
commit | 3ebb4feb986c3b3aacf33d441645314b587ef5b3 (patch) | |
tree | 7e2e2c4511da87acf779fb7042360c34a4f7c909 /src/fs.zig | |
parent | e8dab9bfcf4b7822253eaf290cf2f72291b39167 (diff) | |
download | bun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.tar.gz bun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.tar.zst bun-3ebb4feb986c3b3aacf33d441645314b587ef5b3.zip |
Attempt to optimize `bun bun` on Linux by using memfd_create and copying the resulting file via sendfile()
Diffstat (limited to '')
-rw-r--r-- | src/fs.zig | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/fs.zig b/src/fs.zig index 8a6d4e5f7..434f4ce36 100644 --- a/src/fs.zig +++ b/src/fs.zig @@ -513,6 +513,79 @@ pub const FileSystem = struct { return file; } + pub const Tmpfile = struct { + fd: std.os.fd_t = 0, + dir_fd: std.os.fd_t = 0, + + pub inline fn dir(this: *Tmpfile) std.fs.Dir { + return std.fs.Dir{ + .fd = this.dir_fd, + }; + } + + pub inline fn file(this: *Tmpfile) std.fs.File { + return std.fs.File{ + .handle = this.fd, + }; + } + + pub fn close(this: *Tmpfile) void { + if (this.fd != 0) std.os.close(this.fd); + } + + pub fn create(this: *Tmpfile, rfs: *RealFS, name: [*:0]const u8) !void { + if (comptime Environment.isLinux) { + this.fd = try std.os.memfd_createZ(name, std.os.MFD_CLOEXEC); + return; + } + + var tmpdir_ = try rfs.openTmpDir(); + this.dir_fd = tmpdir_.fd; + this.fd = try std.os.openatZ(tmpdir_.fd, name, std.os.O_CREAT | std.os.O_EXCL | std.os.O_RDWR | std.os.O_CLOEXEC, 0666); + } + + pub fn promoteLinux(this: *Tmpfile, destination_fd: std.os.fd_t, name: [*:0]const u8) !void { + std.debug.assert(this.fd != 0); + + const out_handle = try std.os.openatZ(destination_fd, name, std.os.O_WRONLY | std.os.O_CREAT | std.os.O_CLOEXEC, 022); + defer std.os.close(out_handle); + const read = try std.os.sendfile( + out_handle, + this.fd, + 0, + 0, + &[_]std.c.iovec_const{}, + &[_]std.c.iovec_const{}, + 0, + ); + try std.os.ftruncate(out_handle, read); + this.close(); + } + + pub fn promote(this: *Tmpfile, from_name: [*:0]const u8, destination_fd: std.os.fd_t, name: [*:0]const u8) !void { + if (comptime Environment.isLinux) { + try @call(.{ .modifier = .always_inline }, promoteLinux, .{ this, destination_fd, name }); + return; + } + + std.debug.assert(this.fd != 0); + std.debug.assert(this.dir_fd != 0); + + try C.moveFileZWithHandle(this.fd, this.dir_fd, from_name, destination_fd, name); + this.close(); + } + + pub fn closeAndDelete(this: *Tmpfile, name: [*:0]const u8) void { + this.close(); + + if (comptime !Environment.isLinux) { + if (this.dir_fd == 0) return; + + this.dir().deleteFileZ(name) catch {}; + } + } + }; + inline fn _fetchCacheFile(fs: *RealFS, basename: string) !std.fs.File { var parts = [_]string{ "node_modules", ".cache", basename }; var path = fs.parent_fs.join(&parts); |