| ... | ... | @@ -90,7 +90,7 @@ pub const Node = struct { |
| 90 | 90 | /// 0 means unknown. |
| 91 | 91 | /// Little endian. |
| 92 | 92 | estimated_total_count: u32, |
| 93 | | name: [max_name_len]u8, |
| 93 | name: [max_name_len]u8 align(@alignOf(usize)), |
| 94 | 94 | |
| 95 | 95 | /// Not thread-safe. |
| 96 | 96 | fn getIpcFd(s: Storage) ?posix.fd_t { |
| ... | ... | @@ -288,8 +288,9 @@ pub const Node = struct { |
| 288 | 288 | @atomicStore(u32, &storage.completed_count, 0, .monotonic); |
| 289 | 289 | @atomicStore(u32, &storage.estimated_total_count, std.math.lossyCast(u32, estimated_total_items), .monotonic); |
| 290 | 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); |
| 292 | | for (storage.name[name_len..]) |*dest| @atomicStore(u8, dest, 0, .monotonic); |
| 291 | copyAtomicStore(storage.name[0..name_len], name[0..name_len]); |
| 292 | if (name_len < storage.name.len) |
| 293 | @atomicStore(u8, &storage.name[name_len], 0, .monotonic); |
| 293 | 294 | |
| 294 | 295 | const parent_ptr = parentByIndex(free_index); |
| 295 | 296 | assert(parent_ptr.* == .unused); |
| ... | ... | @@ -763,7 +764,7 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized { |
| 763 | 764 | var begin_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire); |
| 764 | 765 | while (begin_parent != .unused) { |
| 765 | 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 | 768 | dest_storage.estimated_total_count = @atomicLoad(u32, &storage_ptr.estimated_total_count, .acquire); |
| 768 | 769 | dest_storage.completed_count = @atomicLoad(u32, &storage_ptr.completed_count, .monotonic); |
| 769 | 770 | const end_parent = @atomicLoad(Node.Parent, parent_ptr, .acquire); |
| ... | ... | @@ -1384,3 +1385,29 @@ const have_sigwinch = switch (builtin.os.tag) { |
| 1384 | 1385 | /// stderr mutex is held still dumps the stack trace and other debug |
| 1385 | 1386 | /// information. |
| 1386 | 1387 | var stderr_mutex = std.Thread.Mutex.Recursive.init; |
| 1388 | |
| 1389 | fn 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 | |
| 1403 | fn 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 | } |