diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-12-15 23:43:50 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-12-16 18:05:58 +0100 |
| commit | 585c21e54d339f207028d871a45546da2d1b6871 (patch) | |
| tree | 0b830739f4a388e4767b54d55a7f070e2209ece4 /src/link/MachO/CodeSignature.zig | |
| parent | 1928ed7dab3949db964d96dad82beb776e69554f (diff) | |
| download | zig-585c21e54d339f207028d871a45546da2d1b6871.tar.gz zig-585c21e54d339f207028d871a45546da2d1b6871.zip | |
macho: move parallel file hashing back to CodeSignature
I need to think some more how to calculate UUID in parallel, if
it is even possible, to preserve UUID's determinism.
Diffstat (limited to 'src/link/MachO/CodeSignature.zig')
| -rw-r--r-- | src/link/MachO/CodeSignature.zig | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/src/link/MachO/CodeSignature.zig b/src/link/MachO/CodeSignature.zig index 391ac28efa..116ed254f8 100644 --- a/src/link/MachO/CodeSignature.zig +++ b/src/link/MachO/CodeSignature.zig @@ -10,8 +10,9 @@ const testing = std.testing; const Allocator = mem.Allocator; const Compilation = @import("../../Compilation.zig"); -const Hasher = @import("hasher.zig").ParallelHasher; const Sha256 = std.crypto.hash.sha2.Sha256; +const ThreadPool = @import("../../ThreadPool.zig"); +const WaitGroup = @import("../../WaitGroup.zig"); const hash_size = Sha256.digest_length; @@ -288,11 +289,7 @@ pub fn writeAdhocSignature( self.code_directory.inner.nCodeSlots = total_pages; // Calculate hash for each page (in file) and write it to the buffer - var hasher = Hasher(Sha256){}; - try hasher.hash(gpa, comp.thread_pool, opts.file, self.code_directory.code_slots.items, .{ - .chunk_size = self.page_size, - .max_file_size = opts.file_size, - }); + try self.parallelHash(gpa, comp.thread_pool, opts.file, opts.file_size); try blobs.append(.{ .code_directory = &self.code_directory }); header.length += @sizeOf(macho.BlobIndex); @@ -351,6 +348,62 @@ pub fn writeAdhocSignature( } } +fn parallelHash( + self: *CodeSignature, + gpa: Allocator, + pool: *ThreadPool, + file: fs.File, + file_size: u64, +) !void { + var wg: WaitGroup = .{}; + + const total_num_chunks = mem.alignForward(file_size, self.page_size) / self.page_size; + assert(self.code_directory.code_slots.items.len >= total_num_chunks); + + const buffer = try gpa.alloc(u8, self.page_size * total_num_chunks); + defer gpa.free(buffer); + + const results = try gpa.alloc(fs.File.PReadError!usize, total_num_chunks); + defer gpa.free(results); + + { + wg.reset(); + defer wg.wait(); + + var i: usize = 0; + while (i < total_num_chunks) : (i += 1) { + const fstart = i * self.page_size; + const fsize = if (fstart + self.page_size > file_size) + file_size - fstart + else + self.page_size; + wg.start(); + try pool.spawn(worker, .{ + file, + fstart, + buffer[fstart..][0..fsize], + &self.code_directory.code_slots.items[i], + &results[i], + &wg, + }); + } + } + for (results) |result| _ = try result; +} + +fn worker( + file: fs.File, + fstart: usize, + buffer: []u8, + out: *[hash_size]u8, + err: *fs.File.PReadError!usize, + wg: *WaitGroup, +) void { + defer wg.finish(); + err.* = file.preadAll(buffer, fstart); + Sha256.hash(buffer, out, .{}); +} + pub fn size(self: CodeSignature) u32 { var ssize: u32 = @sizeOf(macho.SuperBlob) + @sizeOf(macho.BlobIndex) + self.code_directory.size(); if (self.requirements) |req| { |
