I need a countdown latch

As the title says, I couldn’t find something like this in the std. I want my threads to wait for the others at the latch and when all threads are ready, i.e. the countdown reaches 0, they get unblocked.

Could I glue something together with a std.atomic.Value and std.Io.Event? You dont have to give me a fully implemented answer unless you want, just point me in the direction.

Also, do you think this should be added to the std?
Thanks in advance!

Edit: I’ve found this CountDownLatch.zig/CountDownLatch.zig at main · fr233/CountDownLatch.zig · GitHub
but it’s quite old. Can we do better in 0.16?

I had never heard the term countdown latch. What you described is what I learned as a thread barrier.
This guy wrote a cool implementation of one.

1 Like

Thanks! I took some inspiration from that thread and other things that I’ve found and all that I really needed was this:

const std = @import("std");
const Io = std.Io;
const Event = Io.Event;
const atomic = std.atomic;

count: atomic.Value(usize),
event: Event,

pub fn init(initial_count: usize) @This() {
    return .{
        .count = .init(initial_count),
        .event = .unset,
    };
}

pub fn wait(self: *@This(), io: Io) Io.Cancelable!void {
    if (self.event.isSet()) return;

    const prev = self.count.fetchSub(1, .seq_cst);

    if (prev == 1) {
        self.event.set(io);
    } else {
        try self.event.wait(io);
    }
}
1 Like

This is generally called a semaphore, there is one provided by zig under that name

I needed an inverted semaphore i.e. all threads get unblocked when the counter is 0, AFAIK a semaphore blocks when the counter reaches 0.

1 Like