| author | |
| committer | |
| log | ef9d6331fc9067f7ba47eccee204fa2f0c5d0a18 |
| tree | d6fb2a3a0722bea29d94c1511e57f1a809a01c54 |
| parent | 8087c134dbeaa2925948597883d6a401f251a716 |
3 files changed, 27 insertions(+), 21 deletions(-)
src/link/MachO/CodeSignature.zig+2-2| ... | ... | @@ -288,8 +288,8 @@ pub fn writeAdhocSignature( |
| 288 | 288 | self.code_directory.inner.nCodeSlots = total_pages; |
| 289 | 289 | |
| 290 | 290 | // Calculate hash for each page (in file) and write it to the buffer |
| 291 | var hasher = Hasher(Sha256){}; | |
| 292 | try hasher.hash(gpa, comp.thread_pool, opts.file, self.code_directory.code_slots.items, .{ | |
| 291 | var hasher = Hasher(Sha256){ .allocator = gpa, .thread_pool = comp.thread_pool }; | |
| 292 | try hasher.hash(opts.file, self.code_directory.code_slots.items, .{ | |
| 293 | 293 | .chunk_size = self.page_size, |
| 294 | 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 | 11 | const hash_size = Hasher.digest_length; |
| 12 | 12 | |
| 13 | 13 | return struct { |
| 14 | pub fn hash(self: @This(), gpa: Allocator, pool: *ThreadPool, file: fs.File, out: [][hash_size]u8, opts: struct { | |
| 15 | chunk_size: u16 = 0x4000, | |
| 14 | allocator: Allocator, | |
| 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 | 19 | max_file_size: ?u64 = null, |
| 17 | 20 | }) !void { |
| 18 | _ = self; | |
| 19 | ||
| 20 | 21 | var wg: WaitGroup = .{}; |
| 21 | 22 | |
| 22 | 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); | |
| 25 | 24 | |
| 26 | const buffer = try gpa.alloc(u8, opts.chunk_size * total_num_chunks); | |
| 27 | defer gpa.free(buffer); | |
| 25 | const buffer = try self.allocator.alloc(u8, opts.chunk_size * out.len); | |
| 26 | defer self.allocator.free(buffer); | |
| 28 | 27 | |
| 29 | const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks); | |
| 30 | defer gpa.free(results); | |
| 28 | const results = try self.allocator.alloc(fs.File.PReadError!usize, out.len); | |
| 29 | defer self.allocator.free(results); | |
| 31 | 30 | |
| 32 | 31 | { |
| 33 | 32 | wg.reset(); |
| 34 | 33 | defer wg.wait(); |
| 35 | 34 | |
| 36 | var i: usize = 0; | |
| 37 | while (i < total_num_chunks) : (i += 1) { | |
| 35 | for (out, results, 0..) |*out_buf, *result, i| { | |
| 38 | 36 | const fstart = i * opts.chunk_size; |
| 39 | 37 | const fsize = if (fstart + opts.chunk_size > file_size) file_size - fstart else opts.chunk_size; |
| 40 | 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 | 49 | for (results) |result| _ = try result; |
| ... | ... | @@ -56,5 +61,7 @@ pub fn ParallelHasher(comptime Hasher: type) type { |
| 56 | 61 | err.* = file.preadAll(buffer, fstart); |
| 57 | 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 | 14 | /// TODO LLD also hashes the output filename to disambiguate between same builds with different |
| 15 | 15 | /// output files. Should we also do that? |
| 16 | 16 | pub 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 | 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; | |
| 20 | 19 | |
| 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 | 21 | defer comp.gpa.free(hashes); |
| 23 | 22 | |
| 24 | var hasher = Hasher(Md5){}; | |
| 25 | try hasher.hash(comp.gpa, comp.thread_pool, file, hashes, .{ | |
| 23 | var hasher = Hasher(Md5){ .allocator = comp.gpa, .thread_pool = comp.thread_pool }; | |
| 24 | try hasher.hash(file, hashes, .{ | |
| 26 | 25 | .chunk_size = chunk_size, |
| 27 | 26 | .max_file_size = file_size, |
| 28 | 27 | }); |
| 29 | 28 | |
| 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 | 30 | defer comp.gpa.free(final_buffer); |
| 32 | 31 | |
| 33 | 32 | for (hashes, 0..) |hash, i| { |