authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-06-19 20:33:27+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-06-19 20:33:27+02:00
logef9d6331fc9067f7ba47eccee204fa2f0c5d0a18
treed6fb2a3a0722bea29d94c1511e57f1a809a01c54
parent8087c134dbeaa2925948597883d6a401f251a716

macho: clean up hasher interface


3 files changed, 27 insertions(+), 21 deletions(-)

src/link/MachO/CodeSignature.zig+2-2
...@@ -288,8 +288,8 @@ pub fn writeAdhocSignature(...@@ -288,8 +288,8 @@ pub fn writeAdhocSignature(
288 self.code_directory.inner.nCodeSlots = total_pages;288 self.code_directory.inner.nCodeSlots = total_pages;
289289
290 // Calculate hash for each page (in file) and write it to the buffer290 // Calculate hash for each page (in file) and write it to the buffer
291 var hasher = Hasher(Sha256){};291 var hasher = Hasher(Sha256){ .allocator = gpa, .thread_pool = comp.thread_pool };
292 try hasher.hash(gpa, comp.thread_pool, opts.file, self.code_directory.code_slots.items, .{292 try hasher.hash(opts.file, self.code_directory.code_slots.items, .{
293 .chunk_size = self.page_size,293 .chunk_size = self.page_size,
294 .max_file_size = opts.file_size,294 .max_file_size = opts.file_size,
295 });295 });
src/link/MachO/hasher.zig+20-13
...@@ -11,34 +11,39 @@ pub fn ParallelHasher(comptime Hasher: type) type {...@@ -11,34 +11,39 @@ pub fn ParallelHasher(comptime Hasher: type) type {
11 const hash_size = Hasher.digest_length;11 const hash_size = Hasher.digest_length;
1212
13 return struct {13 return struct {
14 pub fn hash(self: @This(), gpa: Allocator, pool: *ThreadPool, file: fs.File, out: [][hash_size]u8, opts: struct {14 allocator: Allocator,
15 chunk_size: u16 = 0x4000,15 thread_pool: *ThreadPool,
16
17 pub fn hash(self: Self, file: fs.File, out: [][hash_size]u8, opts: struct {
18 chunk_size: u64 = 0x4000,
16 max_file_size: ?u64 = null,19 max_file_size: ?u64 = null,
17 }) !void {20 }) !void {
18 _ = self;
19
20 var wg: WaitGroup = .{};21 var wg: WaitGroup = .{};
2122
22 const file_size = opts.max_file_size orelse try file.getEndPos();23 const file_size = opts.max_file_size orelse try file.getEndPos();
23 const total_num_chunks = mem.alignForward(u64, file_size, opts.chunk_size) / opts.chunk_size;
24 assert(out.len >= total_num_chunks);
2524
26 const buffer = try gpa.alloc(u8, opts.chunk_size * total_num_chunks);25 const buffer = try self.allocator.alloc(u8, opts.chunk_size * out.len);
27 defer gpa.free(buffer);26 defer self.allocator.free(buffer);
2827
29 const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks);28 const results = try self.allocator.alloc(fs.File.PReadError!usize, out.len);
30 defer gpa.free(results);29 defer self.allocator.free(results);
3130
32 {31 {
33 wg.reset();32 wg.reset();
34 defer wg.wait();33 defer wg.wait();
3534
36 var i: usize = 0;35 for (out, results, 0..) |*out_buf, *result, i| {
37 while (i < total_num_chunks) : (i += 1) {
38 const fstart = i * opts.chunk_size;36 const fstart = i * opts.chunk_size;
39 const fsize = if (fstart + opts.chunk_size > file_size) file_size - fstart else opts.chunk_size;37 const fsize = if (fstart + opts.chunk_size > file_size) file_size - fstart else opts.chunk_size;
40 wg.start();38 wg.start();
41 try pool.spawn(worker, .{ file, fstart, buffer[fstart..][0..fsize], &out[i], &results[i], &wg });39 try self.thread_pool.spawn(worker, .{
40 file,
41 fstart,
42 buffer[fstart..][0..fsize],
43 &(out_buf.*),
44 &(result.*),
45 &wg,
46 });
42 }47 }
43 }48 }
44 for (results) |result| _ = try result;49 for (results) |result| _ = try result;
...@@ -56,5 +61,7 @@ pub fn ParallelHasher(comptime Hasher: type) type {...@@ -56,5 +61,7 @@ pub fn ParallelHasher(comptime Hasher: type) type {
56 err.* = file.preadAll(buffer, fstart);61 err.* = file.preadAll(buffer, fstart);
57 Hasher.hash(buffer, out, .{});62 Hasher.hash(buffer, out, .{});
58 }63 }
64
65 const Self = @This();
59 };66 };
60}67}
src/link/MachO/uuid.zig+5-6
...@@ -14,20 +14,19 @@ const Hasher = @import("hasher.zig").ParallelHasher;...@@ -14,20 +14,19 @@ const Hasher = @import("hasher.zig").ParallelHasher;
14/// TODO LLD also hashes the output filename to disambiguate between same builds with different14/// TODO LLD also hashes the output filename to disambiguate between same builds with different
15/// output files. Should we also do that?15/// output files. Should we also do that?
16pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[Md5.digest_length]u8) !void {16pub fn calcUuid(comp: *const Compilation, file: fs.File, file_size: u64, out: *[Md5.digest_length]u8) !void {
17 const num_chunks = @intCast(u64, comp.thread_pool.threads.len) * 10;17 const num_chunks = comp.thread_pool.threads.len * 0x10;
18 const chunk_size = @divTrunc(file_size + num_chunks - 1, num_chunks);18 const chunk_size = @divTrunc(file_size + num_chunks - 1, num_chunks);
19 const total_hashes = mem.alignForward(u64, file_size, chunk_size) / chunk_size;
2019
21 const hashes = try comp.gpa.alloc([Md5.digest_length]u8, total_hashes);20 const hashes = try comp.gpa.alloc([Md5.digest_length]u8, num_chunks);
22 defer comp.gpa.free(hashes);21 defer comp.gpa.free(hashes);
2322
24 var hasher = Hasher(Md5){};23 var hasher = Hasher(Md5){ .allocator = comp.gpa, .thread_pool = comp.thread_pool };
25 try hasher.hash(comp.gpa, comp.thread_pool, file, hashes, .{24 try hasher.hash(file, hashes, .{
26 .chunk_size = chunk_size,25 .chunk_size = chunk_size,
27 .max_file_size = file_size,26 .max_file_size = file_size,
28 });27 });
2928
30 const final_buffer = try comp.gpa.alloc(u8, total_hashes * Md5.digest_length);29 const final_buffer = try comp.gpa.alloc(u8, num_chunks * Md5.digest_length);
31 defer comp.gpa.free(final_buffer);30 defer comp.gpa.free(final_buffer);
3231
33 for (hashes, 0..) |hash, i| {32 for (hashes, 0..) |hash, i| {