Zig 0.16: Thread.Mutex -> Io.Mutex

Ignoring errors as unreachable since the only error is Cancellable -
nothing is cancelling anything.
This commit is contained in:
LN Liberda 2026-05-22 21:51:29 +02:00
parent 8c5bef6cb4
commit 1e0087e5dc
5 changed files with 46 additions and 46 deletions

View file

@ -13,7 +13,7 @@ pub const global = struct {
var fd: std.Io.File = undefined;
var index: std.ArrayListUnmanaged(u8) = .empty;
var file_off: u64 = 0;
var lock: std.Thread.Mutex = .{};
var lock: std.Io.Mutex = .init;
var root_itemref: u64 = 0;
};
@ -125,8 +125,8 @@ pub const Thread = struct {
var block = createBlock(t);
defer block.deinit(main.allocator);
global.lock.lock();
defer global.lock.unlock();
global.lock.lock(main.io) catch unreachable;
defer global.lock.unlock(main.io);
// This can only really happen when the root path exceeds our block size,
// in which case we would probably have error'ed out earlier anyway.
if (expected_len > t.buf.len) ui.die("Error writing data: path too long.\n", .{});
@ -246,7 +246,7 @@ pub const Dir = struct {
// I'm not expecting much lock contention, but it's possible to turn
// last_item into an atomic integer and other fields could be split up for
// subdir use.
lock: std.Thread.Mutex = .{},
lock: std.Io.Mutex = .init,
last_sub: ?u64 = null,
stat: sink.Stat,
items: u64 = 0,
@ -268,8 +268,8 @@ pub const Dir = struct {
pub fn addSpecial(d: *Dir, t: *Thread, name: []const u8, sp: model.EType) void {
d.lock.lock();
defer d.lock.unlock();
d.lock.lock(main.io) catch unreachable;
defer d.lock.unlock(main.io);
d.items += 1;
if (sp == .err) d.suberr = true;
d.last_sub = t.itemStart(sp, d.last_sub, name);
@ -277,8 +277,8 @@ pub const Dir = struct {
}
pub fn addStat(d: *Dir, t: *Thread, name: []const u8, stat: *const sink.Stat) void {
d.lock.lock();
defer d.lock.unlock();
d.lock.lock(main.io) catch unreachable;
defer d.lock.unlock(main.io);
d.items += 1;
if (stat.etype != .link) {
d.size +|= stat.size;
@ -309,8 +309,8 @@ pub const Dir = struct {
}
pub fn addDir(d: *Dir, stat: *const sink.Stat) Dir {
d.lock.lock();
defer d.lock.unlock();
d.lock.lock(main.io) catch unreachable;
defer d.lock.unlock(main.io);
d.items += 1;
d.size +|= stat.size;
d.blocks +|= stat.blocks;
@ -318,8 +318,8 @@ pub const Dir = struct {
}
pub fn setReadError(d: *Dir) void {
d.lock.lock();
defer d.lock.unlock();
d.lock.lock(main.io) catch unreachable;
defer d.lock.unlock(main.io);
d.err = true;
}
@ -375,8 +375,8 @@ pub const Dir = struct {
}
pub fn final(d: *Dir, t: *Thread, name: []const u8, parent: ?*Dir) void {
if (parent) |p| p.lock.lock();
defer if (parent) |p| p.lock.unlock();
if (parent) |p| p.lock.lock(main.io) catch unreachable;
defer if (parent) |p| p.lock.unlock(main.io);
if (parent) |p| {
// Different dev? Don't merge the 'inodes' sets, just count the

View file

@ -28,8 +28,8 @@ pub fn statToEntry(stat: *const sink.Stat, e: *model.Entry, parent: *model.Dir)
l.parent = parent;
l.ino = stat.ino;
l.pack.nlink = stat.nlink;
model.inodes.lock.lock();
defer model.inodes.lock.unlock();
model.inodes.lock.lock(main.io) catch unreachable;
defer model.inodes.lock.unlock(main.io);
l.addLink();
}
if (e.ext()) |ext| ext.* = stat.ext;
@ -49,7 +49,7 @@ pub const Dir = struct {
items: u32 = 0,
mtime: u64 = 0,
suberr: bool = false,
lock: std.Thread.Mutex = .{},
lock: std.Io.Mutex = .init,
const Map = std.HashMap(*model.Entry, void, HashContext, 80);
@ -161,8 +161,8 @@ pub const Dir = struct {
// Add own counts to parent
if (parent) |p| {
p.lock.lock();
defer p.lock.unlock();
p.lock.lock(main.io) catch unreachable;
defer p.lock.unlock(main.io);
p.blocks +|= self.dir.entry.pack.blocks - self.own_blocks;
p.bytes +|= self.dir.entry.size - self.own_bytes;
p.items +|= self.dir.items;

View file

@ -350,15 +350,15 @@ pub const Ext = extern struct {
// List of st_dev entries. Those are typically 64bits, but that's quite a waste
// of space when a typical scan won't cover many unique devices.
pub const devices = struct {
var lock = std.Thread.Mutex{};
var lock = std.Io.Mutex.init;
// id -> dev
pub var list: std.ArrayListUnmanaged(u64) = .empty;
// dev -> id
var lookup = std.AutoHashMap(u64, DevId).init(main.allocator);
pub fn getId(dev: u64) DevId {
lock.lock();
defer lock.unlock();
lock.lock(main.io) catch unreachable;
defer lock.unlock(main.io);
const d = lookup.getOrPut(dev) catch unreachable;
if (!d.found_existing) {
if (list.items.len >= std.math.maxInt(DevId)) ui.die("Maximum number of device identifiers exceeded.\n", .{});
@ -386,7 +386,7 @@ pub const inodes = struct {
var uncounted = std.HashMap(*Link, void, HashContext, 80).init(main.allocator);
var uncounted_full = true; // start with true for the initial scan
pub var lock = std.Thread.Mutex{};
pub var lock = std.Io.Mutex.init;
const HashContext = struct {
pub fn hash(_: @This(), l: *Link) u64 {

View file

@ -107,7 +107,7 @@ const State = struct {
// impossible for me to predict how that ends up affecting performance.
queue: [QUEUE_SIZE]*Dir = undefined,
queue_len: std.atomic.Value(usize) = std.atomic.Value(usize).init(0),
queue_lock: std.Thread.Mutex = .{},
queue_lock: std.Io.Mutex = .init,
queue_cond: std.Thread.Condition = .{},
threads: []Thread,
@ -121,8 +121,8 @@ const State = struct {
fn tryPush(self: *State, d: *Dir) bool {
if (self.queue_len.load(.acquire) == QUEUE_SIZE) return false;
{
self.queue_lock.lock();
defer self.queue_lock.unlock();
self.queue_lock.lock(main.io) catch unreachable;
defer self.queue_lock.unlock(main.io);
if (self.queue_len.load(.monotonic) == QUEUE_SIZE) return false;
const slot = self.queue_len.fetchAdd(1, .monotonic);
self.queue[slot] = d;
@ -133,8 +133,8 @@ const State = struct {
// Blocks while the queue is empty, returns null when all threads are blocking.
fn waitPop(self: *State) ?*Dir {
self.queue_lock.lock();
defer self.queue_lock.unlock();
self.queue_lock.lock(main.io) catch unreachable;
defer self.queue_lock.unlock(main.io);
self.waiting += 1;
while (self.queue_len.load(.monotonic) == 0) {

View file

@ -86,8 +86,8 @@ pub const Dir = struct {
.bin => |*b| b.addSpecial(&t.sink.bin, name, sp),
}
if (sp == .err) {
global.last_error_lock.lock();
defer global.last_error_lock.unlock();
global.last_error_lock.lock(main.io) catch unreachable;
defer global.last_error_lock.unlock(main.io);
if (global.last_error) |p| main.allocator.free(p);
const p = d.path();
global.last_error = std.fs.path.joinZ(main.allocator, &.{ p, name }) catch unreachable;
@ -133,8 +133,8 @@ pub const Dir = struct {
.json => |*j| j.setReadError(),
.bin => |*b| b.setReadError(),
}
global.last_error_lock.lock();
defer global.last_error_lock.unlock();
global.last_error_lock.lock(main.io) catch unreachable;
defer global.last_error_lock.unlock(main.io);
if (global.last_error) |p| main.allocator.free(p);
global.last_error = d.path();
}
@ -180,7 +180,7 @@ pub const Dir = struct {
pub const Thread = struct {
current_dir: ?*Dir = null,
lock: std.Thread.Mutex = .{},
lock: std.Io.Mutex = .init,
// On 32-bit architectures, bytes_seen is protected by the above mutex instead.
bytes_seen: std.atomic.Value(u64) = std.atomic.Value(u64).init(0),
files_seen: std.atomic.Value(u32) = std.atomic.Value(u32).init(0),
@ -194,8 +194,8 @@ pub const Thread = struct {
fn addBytes(t: *Thread, bytes: u64) void {
if (@bitSizeOf(usize) >= 64) _ = t.bytes_seen.fetchAdd(bytes, .monotonic)
else {
t.lock.lock();
defer t.lock.unlock();
t.lock.lock(main.io) catch unreachable;
defer t.lock.unlock(main.io);
t.bytes_seen.raw += bytes;
}
}
@ -203,15 +203,15 @@ pub const Thread = struct {
fn getBytes(t: *Thread) u64 {
if (@bitSizeOf(usize) >= 64) return t.bytes_seen.load(.monotonic)
else {
t.lock.lock();
defer t.lock.unlock();
t.lock.lock(main.io) catch unreachable;
defer t.lock.unlock(main.io);
return t.bytes_seen.raw;
}
}
pub fn setDir(t: *Thread, d: ?*Dir) void {
t.lock.lock();
defer t.lock.unlock();
t.lock.lock(main.io) catch unreachable;
defer t.lock.unlock(main.io);
t.current_dir = d;
}
};
@ -223,7 +223,7 @@ pub const global = struct {
pub var sink: enum { json, mem, bin } = .mem;
pub var last_error: ?[:0]u8 = null;
var last_error_lock = std.Thread.Mutex{};
var last_error_lock = std.Io.Mutex.init;
var need_confirm_quit = false;
};
@ -327,8 +327,8 @@ fn drawConsole() void {
for (global.threads, 0..) |*t, i| {
const dir = blk: {
t.lock.lock();
defer t.lock.unlock();
t.lock.lock(main.io) catch unreachable;
defer t.lock.unlock(main.io);
break :blk if (t.current_dir) |d| d.path() else null;
};
wr.print(" #{}: {s}\n", .{i+1, ui.shorten(ui.toUtf8(dir orelse "(waiting)"), 73)}) catch {};
@ -369,8 +369,8 @@ fn drawProgress() void {
box.move(3+@as(u32, @intCast(i)), 4);
const dir = blk: {
const t = &global.threads[i];
t.lock.lock();
defer t.lock.unlock();
t.lock.lock(main.io) catch unreachable;
defer t.lock.unlock(main.io);
break :blk if (t.current_dir) |d| d.path() else null;
};
ui.addstr(ui.shorten(ui.toUtf8(dir orelse "(waiting)"), width -| 6));
@ -378,8 +378,8 @@ fn drawProgress() void {
}
blk: {
global.last_error_lock.lock();
defer global.last_error_lock.unlock();
global.last_error_lock.lock(main.io) catch unreachable;
defer global.last_error_lock.unlock(main.io);
const err = global.last_error orelse break :blk;
box.move(4 + numthreads, 2);
ui.style(.bold);