| ... | @@ -16,8 +16,8 @@ const Allocator = std.mem.Allocator; | ... | @@ -16,8 +16,8 @@ const Allocator = std.mem.Allocator; |
| 16 | /// This protection is conditionally compiled depending on `want_debug_deadlock`. | 16 | /// This protection is conditionally compiled depending on `want_debug_deadlock`. |
| 17 | var all_cache_digest_set: std.AutoHashMapUnmanaged(BinDigest, void) = .{}; | 17 | var all_cache_digest_set: std.AutoHashMapUnmanaged(BinDigest, void) = .{}; |
| 18 | var all_cache_digest_lock: std.Mutex = .{}; | 18 | var all_cache_digest_lock: std.Mutex = .{}; |
| 19 | // TODO: Figure out how to make sure that `all_cache_digest_set` does not leak memory! | 19 | var all_cache_digest_allocator: ?*Allocator = null; |
| 20 | pub const want_debug_deadlock = false; | 20 | const want_debug_deadlock = std.debug.runtime_safety; |
| 21 | const DebugBinDigest = if (want_debug_deadlock) BinDigest else void; | 21 | const DebugBinDigest = if (want_debug_deadlock) BinDigest else void; |
| 22 | const null_debug_bin_digest = if (want_debug_deadlock) ([1]u8{0} ** bin_digest_len) else {}; | 22 | const null_debug_bin_digest = if (want_debug_deadlock) ([1]u8{0} ** bin_digest_len) else {}; |
| 23 | | 23 | |
| ... | @@ -273,6 +273,14 @@ pub const Manifest = struct { | ... | @@ -273,6 +273,14 @@ pub const Manifest = struct { |
| 273 | const held = all_cache_digest_lock.acquire(); | 273 | const held = all_cache_digest_lock.acquire(); |
| 274 | defer held.release(); | 274 | defer held.release(); |
| 275 | | 275 | |
| | 276 | if (all_cache_digest_allocator) |prev_gpa| { |
| | 277 | if (prev_gpa != self.cache.gpa) { |
| | 278 | @panic("The deadlock debug code in Cache depends on using the same allocator for everything"); |
| | 279 | } |
| | 280 | } else { |
| | 281 | all_cache_digest_allocator = self.cache.gpa; |
| | 282 | } |
| | 283 | |
| 276 | const gop = try all_cache_digest_set.getOrPut(self.cache.gpa, bin_digest); | 284 | const gop = try all_cache_digest_set.getOrPut(self.cache.gpa, bin_digest); |
| 277 | if (gop.found_existing) { | 285 | if (gop.found_existing) { |
| 278 | std.debug.print("Cache deadlock detected in Cache.hit. Manifest has {d} files:\n", .{self.files.items.len}); | 286 | std.debug.print("Cache deadlock detected in Cache.hit. Manifest has {d} files:\n", .{self.files.items.len}); |
| ... | @@ -717,15 +725,22 @@ fn isProblematicTimestamp(fs_clock: i128) bool { | ... | @@ -717,15 +725,22 @@ fn isProblematicTimestamp(fs_clock: i128) bool { |
| 717 | return wall_nsec == fs_nsec and wall_sec == fs_sec; | 725 | return wall_nsec == fs_nsec and wall_sec == fs_sec; |
| 718 | } | 726 | } |
| 719 | | 727 | |
| | 728 | pub fn deinitDebugMap() void { |
| | 729 | if (!want_debug_deadlock) return; |
| | 730 | |
| | 731 | if (all_cache_digest_set.count() != 0) { |
| | 732 | @panic("there's a Cache not deinitialized somewhere"); |
| | 733 | } |
| | 734 | const gpa = all_cache_digest_allocator orelse return; |
| | 735 | all_cache_digest_set.clearAndFree(gpa); |
| | 736 | } |
| | 737 | |
| 720 | test "cache file and then recall it" { | 738 | test "cache file and then recall it" { |
| 721 | if (std.Target.current.os.tag == .wasi) { | 739 | if (std.Target.current.os.tag == .wasi) { |
| 722 | // https://github.com/ziglang/zig/issues/5437 | 740 | // https://github.com/ziglang/zig/issues/5437 |
| 723 | return error.SkipZigTest; | 741 | return error.SkipZigTest; |
| 724 | } | 742 | } |
| 725 | defer if (want_debug_deadlock) { | 743 | defer deinitDebugMap(); |
| 726 | testing.expect(all_cache_digest_set.count() == 0); | | |
| 727 | all_cache_digest_set.clearAndFree(testing.allocator); | | |
| 728 | }; | | |
| 729 | | 744 | |
| 730 | const cwd = fs.cwd(); | 745 | const cwd = fs.cwd(); |
| 731 | | 746 | |
| ... | @@ -804,10 +819,7 @@ test "check that changing a file makes cache fail" { | ... | @@ -804,10 +819,7 @@ test "check that changing a file makes cache fail" { |
| 804 | // https://github.com/ziglang/zig/issues/5437 | 819 | // https://github.com/ziglang/zig/issues/5437 |
| 805 | return error.SkipZigTest; | 820 | return error.SkipZigTest; |
| 806 | } | 821 | } |
| 807 | defer if (want_debug_deadlock) { | 822 | defer deinitDebugMap(); |
| 808 | testing.expect(all_cache_digest_set.count() == 0); | | |
| 809 | all_cache_digest_set.clearAndFree(testing.allocator); | | |
| 810 | }; | | |
| 811 | const cwd = fs.cwd(); | 823 | const cwd = fs.cwd(); |
| 812 | | 824 | |
| 813 | const temp_file = "cache_hash_change_file_test.txt"; | 825 | const temp_file = "cache_hash_change_file_test.txt"; |
| ... | @@ -884,10 +896,7 @@ test "no file inputs" { | ... | @@ -884,10 +896,7 @@ test "no file inputs" { |
| 884 | // https://github.com/ziglang/zig/issues/5437 | 896 | // https://github.com/ziglang/zig/issues/5437 |
| 885 | return error.SkipZigTest; | 897 | return error.SkipZigTest; |
| 886 | } | 898 | } |
| 887 | defer if (want_debug_deadlock) { | 899 | defer deinitDebugMap(); |
| 888 | testing.expect(all_cache_digest_set.count() == 0); | | |
| 889 | all_cache_digest_set.clearAndFree(testing.allocator); | | |
| 890 | }; | | |
| 891 | const cwd = fs.cwd(); | 900 | const cwd = fs.cwd(); |
| 892 | const temp_manifest_dir = "no_file_inputs_manifest_dir"; | 901 | const temp_manifest_dir = "no_file_inputs_manifest_dir"; |
| 893 | defer cwd.deleteTree(temp_manifest_dir) catch {}; | 902 | defer cwd.deleteTree(temp_manifest_dir) catch {}; |
| ... | @@ -933,10 +942,7 @@ test "Manifest with files added after initial hash work" { | ... | @@ -933,10 +942,7 @@ test "Manifest with files added after initial hash work" { |
| 933 | // https://github.com/ziglang/zig/issues/5437 | 942 | // https://github.com/ziglang/zig/issues/5437 |
| 934 | return error.SkipZigTest; | 943 | return error.SkipZigTest; |
| 935 | } | 944 | } |
| 936 | defer if (want_debug_deadlock) { | 945 | defer deinitDebugMap(); |
| 937 | testing.expect(all_cache_digest_set.count() == 0); | | |
| 938 | all_cache_digest_set.clearAndFree(testing.allocator); | | |
| 939 | }; | | |
| 940 | const cwd = fs.cwd(); | 946 | const cwd = fs.cwd(); |
| 941 | | 947 | |
| 942 | const temp_file1 = "cache_hash_post_file_test1.txt"; | 948 | const temp_file1 = "cache_hash_post_file_test1.txt"; |