authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-06-12 13:20:14-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-06-12 13:20:14-04:00
log44f4abf3805eb457525a474f243b71373b5c3824
tree9558809eac9dbb93c50e128c417a2196d81f44d3
parentd9bd34fd0533295044ffb4160da41f7873aff905
parent727f1fa74316e412c32828689e569a3d1fd1981b
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20269 from ziglang/fix-progress-race


2 files changed, 20 insertions(+), 16 deletions(-)

lib/std/Progress.zig+14-5
...@@ -734,7 +734,7 @@ const Serialized = struct {...@@ -734,7 +734,7 @@ const Serialized = struct {
734 const Buffer = struct {734 const Buffer = struct {
735 parents: [node_storage_buffer_len]Node.Parent,735 parents: [node_storage_buffer_len]Node.Parent,
736 storage: [node_storage_buffer_len]Node.Storage,736 storage: [node_storage_buffer_len]Node.Storage,
737 map: [node_storage_buffer_len]Node.Index,737 map: [node_storage_buffer_len]Node.OptionalIndex,
738738
739 parents_copy: [node_storage_buffer_len]Node.Parent,739 parents_copy: [node_storage_buffer_len]Node.Parent,
740 storage_copy: [node_storage_buffer_len]Node.Storage,740 storage_copy: [node_storage_buffer_len]Node.Storage,
...@@ -753,9 +753,11 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {...@@ -753,9 +753,11 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {
753 // Iterate all of the nodes and construct a serializable copy of the state that can be examined753 // Iterate all of the nodes and construct a serializable copy of the state that can be examined
754 // without atomics.754 // without atomics.
755 const end_index = @atomicLoad(u32, &global_progress.node_end_index, .monotonic);755 const end_index = @atomicLoad(u32, &global_progress.node_end_index, .monotonic);
756 const node_parents = global_progress.node_parents[0..end_index];756 for (
757 const node_storage = global_progress.node_storage[0..end_index];757 global_progress.node_parents[0..end_index],
758 for (node_parents, node_storage, 0..) |*parent_ptr, *storage_ptr, i| {758 global_progress.node_storage[0..end_index],
759 serialized_buffer.map[0..end_index],
760 ) |*parent_ptr, *storage_ptr, *map| {
759 var begin_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);761 var begin_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);
760 while (begin_parent != .unused) {762 while (begin_parent != .unused) {
761 const dest_storage = &serialized_buffer.storage[serialized_len];763 const dest_storage = &serialized_buffer.storage[serialized_len];
...@@ -766,12 +768,19 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {...@@ -766,12 +768,19 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {
766 if (begin_parent == end_parent) {768 if (begin_parent == end_parent) {
767 any_ipc = any_ipc or (dest_storage.getIpcFd() != null);769 any_ipc = any_ipc or (dest_storage.getIpcFd() != null);
768 serialized_buffer.parents[serialized_len] = begin_parent;770 serialized_buffer.parents[serialized_len] = begin_parent;
769 serialized_buffer.map[i] = @enumFromInt(serialized_len);771 map.* = @enumFromInt(serialized_len);
770 serialized_len += 1;772 serialized_len += 1;
771 break;773 break;
772 }774 }
773775
774 begin_parent = end_parent;776 begin_parent = end_parent;
777 } else {
778 // A node may be freed during the execution of this loop, causing
779 // there to be a parent reference to a nonexistent node. Without
780 // this assignment, this would lead to the map entry containing
781 // stale data. By assigning none, the child node with the bad
782 // parent pointer will be harmlessly omitted from the tree.
783 map.* = .none;
775 }784 }
776 }785 }
777786
tools/update_cpu_features.zig+6-11
...@@ -1038,8 +1038,7 @@ pub fn main() anyerror!void {...@@ -1038,8 +1038,7 @@ pub fn main() anyerror!void {
1038 var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});1038 var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});
1039 defer zig_src_dir.close();1039 defer zig_src_dir.close();
10401040
1041 var progress = std.Progress{};1041 const root_progress = std.Progress.start(.{ .estimated_total_items = llvm_targets.len });
1042 const root_progress = progress.start("", llvm_targets.len);
1043 defer root_progress.end();1042 defer root_progress.end();
10441043
1045 if (builtin.single_threaded) {1044 if (builtin.single_threaded) {
...@@ -1074,7 +1073,7 @@ const Job = struct {...@@ -1074,7 +1073,7 @@ const Job = struct {
1074 llvm_tblgen_exe: []const u8,1073 llvm_tblgen_exe: []const u8,
1075 llvm_src_root: []const u8,1074 llvm_src_root: []const u8,
1076 zig_src_dir: std.fs.Dir,1075 zig_src_dir: std.fs.Dir,
1077 root_progress: *std.Progress.Node,1076 root_progress: std.Progress.Node,
1078 llvm_target: LlvmTarget,1077 llvm_target: LlvmTarget,
1079};1078};
10801079
...@@ -1085,12 +1084,10 @@ fn processOneTarget(job: Job) anyerror!void {...@@ -1085,12 +1084,10 @@ fn processOneTarget(job: Job) anyerror!void {
1085 defer arena_state.deinit();1084 defer arena_state.deinit();
1086 const arena = arena_state.allocator();1085 const arena = arena_state.allocator();
10871086
1088 var progress_node = job.root_progress.start(llvm_target.zig_name, 3);1087 const progress_node = job.root_progress.start(llvm_target.zig_name, 3);
1089 progress_node.activate();
1090 defer progress_node.end();1088 defer progress_node.end();
10911089
1092 var tblgen_progress = progress_node.start("invoke llvm-tblgen", 0);1090 const tblgen_progress = progress_node.start("invoke llvm-tblgen", 0);
1093 tblgen_progress.activate();
10941091
1095 const child_args = [_][]const u8{1092 const child_args = [_][]const u8{
1096 job.llvm_tblgen_exe,1093 job.llvm_tblgen_exe,
...@@ -1127,16 +1124,14 @@ fn processOneTarget(job: Job) anyerror!void {...@@ -1127,16 +1124,14 @@ fn processOneTarget(job: Job) anyerror!void {
1127 },1124 },
1128 };1125 };
11291126
1130 var json_parse_progress = progress_node.start("parse JSON", 0);1127 const json_parse_progress = progress_node.start("parse JSON", 0);
1131 json_parse_progress.activate();
11321128
1133 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});1129 const parsed = try json.parseFromSlice(json.Value, arena, json_text, .{});
1134 defer parsed.deinit();1130 defer parsed.deinit();
1135 const root_map = &parsed.value.object;1131 const root_map = &parsed.value.object;
1136 json_parse_progress.end();1132 json_parse_progress.end();
11371133
1138 var render_progress = progress_node.start("render zig code", 0);1134 const render_progress = progress_node.start("render zig code", 0);
1139 render_progress.activate();
11401135
1141 var features_table = std.StringHashMap(Feature).init(arena);1136 var features_table = std.StringHashMap(Feature).init(arena);
1142 var all_features = std.ArrayList(Feature).init(arena);1137 var all_features = std.ArrayList(Feature).init(arena);