authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-09 14:18:23-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-10 00:28:44-04:00
log9363e995fcf49a9496523c857fa925539fc7c2d6
tree8a25d4d6d3d57201041d9ce171624093f2c3bb07
parentb3b923e51f53330403bd99a224c19bc3f01005c4

std.Progress: slightly better atomic memcpy

Let's at least do aligned usize loads/stores where possible.

1 files changed, 31 insertions(+), 4 deletions(-)

lib/std/Progress.zig+31-4
...@@ -90,7 +90,7 @@ pub const Node = struct {...@@ -90,7 +90,7 @@ pub const Node = struct {
90 /// 0 means unknown.90 /// 0 means unknown.
91 /// Little endian.91 /// Little endian.
92 estimated_total_count: u32,92 estimated_total_count: u32,
93 name: [max_name_len]u8,93 name: [max_name_len]u8 align(@alignOf(usize)),
9494
95 /// Not thread-safe.95 /// Not thread-safe.
96 fn getIpcFd(s: Storage) ?posix.fd_t {96 fn getIpcFd(s: Storage) ?posix.fd_t {
...@@ -288,8 +288,9 @@ pub const Node = struct {...@@ -288,8 +288,9 @@ pub const Node = struct {
288 @atomicStore(u32, &storage.completed_count, 0, .monotonic);288 @atomicStore(u32, &storage.completed_count, 0, .monotonic);
289 @atomicStore(u32, &storage.estimated_total_count, std.math.lossyCast(u32, estimated_total_items), .monotonic);289 @atomicStore(u32, &storage.estimated_total_count, std.math.lossyCast(u32, estimated_total_items), .monotonic);
290 const name_len = @min(max_name_len, name.len);290 const name_len = @min(max_name_len, name.len);
291 for (storage.name[0..name_len], name[0..name_len]) |*dest, src| @atomicStore(u8, dest, src, .monotonic);291 copyAtomicStore(storage.name[0..name_len], name[0..name_len]);
292 for (storage.name[name_len..]) |*dest| @atomicStore(u8, dest, 0, .monotonic);292 if (name_len < storage.name.len)
293 @atomicStore(u8, &storage.name[name_len], 0, .monotonic);
293294
294 const parent_ptr = parentByIndex(free_index);295 const parent_ptr = parentByIndex(free_index);
295 assert(parent_ptr.* == .unused);296 assert(parent_ptr.* == .unused);
...@@ -763,7 +764,7 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {...@@ -763,7 +764,7 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized {
763 var begin_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);764 var begin_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);
764 while (begin_parent != .unused) {765 while (begin_parent != .unused) {
765 const dest_storage = &serialized_buffer.storage[serialized_len];766 const dest_storage = &serialized_buffer.storage[serialized_len];
766 for (&dest_storage.name, &storage_ptr.name) |*dest, *src| dest.* = @atomicLoad(u8, src, .monotonic);767 copyAtomicLoad(&dest_storage.name, &storage_ptr.name);
767 dest_storage.estimated_total_count = @atomicLoad(u32, &storage_ptr.estimated_total_count, .acquire);768 dest_storage.estimated_total_count = @atomicLoad(u32, &storage_ptr.estimated_total_count, .acquire);
768 dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic);769 dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic);
769 const end_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);770 const end_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire);
...@@ -1384,3 +1385,29 @@ const have_sigwinch = switch (builtin.os.tag) {...@@ -1384,3 +1385,29 @@ const have_sigwinch = switch (builtin.os.tag) {
1384/// stderr mutex is held still dumps the stack trace and other debug1385/// stderr mutex is held still dumps the stack trace and other debug
1385/// information.1386/// information.
1386var stderr_mutex = std.Thread.Mutex.Recursive.init;1387var stderr_mutex = std.Thread.Mutex.Recursive.init;
1388
1389fn copyAtomicStore(dest: []align(@alignOf(usize)) u8, src: []const u8) void {
1390 assert(dest.len == src.len);
1391 const chunked_len = dest.len / @sizeOf(usize);
1392 const dest_chunked: []usize = @as([*]usize, @ptrCast(dest))[0..chunked_len];
1393 const src_chunked: []align(1) const usize = @as([*]align(1) const usize, @ptrCast(src))[0..chunked_len];
1394 for (dest_chunked, src_chunked) |*d, s| {
1395 @atomicStore(usize, d, s, .monotonic);
1396 }
1397 const remainder_start = chunked_len * @sizeOf(usize);
1398 for (dest[remainder_start..], src[remainder_start..]) |*d, s| {
1399 @atomicStore(u8, d, s, .monotonic);
1400 }
1401}
1402
1403fn copyAtomicLoad(
1404 dest: *align(@alignOf(usize)) [Node.max_name_len]u8,
1405 src: *align(@alignOf(usize)) const [Node.max_name_len]u8,
1406) void {
1407 const chunked_len = @divExact(dest.len, @sizeOf(usize));
1408 const dest_chunked: *[chunked_len]usize = @ptrCast(dest);
1409 const src_chunked: *const [chunked_len]usize = @ptrCast(src);
1410 for (dest_chunked, src_chunked) |*d, *s| {
1411 d.* = @atomicLoad(usize, s, .monotonic);
1412 }
1413}