I was using it one of my projects, and just noticed it’s gone. I tried searching about it but was not able to find much so I’m asking here.
It’s trivial to implement, I don’t see why it existed in the first place.
zigs time API is getting an overhaul with Io, you now have more control over what clock to use. Even with the removal of Timer I would say the API has generally more convenience.
You’ll find every thing, except the unit conversion amounts, under std.Io now. Perhaps that will change in the future IDK.
Yes, everything that I need is under Timestamp now and having a clock to choose from , I like.
I’ve asked a very similar question to this here!
I ended up doing this to count the time :))
const start = Io.Clock.real.now(init.io);
_ = doSomeWork();
const end = Io.Clock.real.now(init.io);
const duration = std.Io.Timestamp.durationTo(start, end);
try stdout.print("Time Elapsed: {d} ms\n", .{duration.toMilliseconds()});
I find annoying that there isn’t (or I have not seen ofc) a function in Timestamp to return the seconds as a float (eg, 3.334 s) but it can be easily done!
You can use conversion from std.time. I’ll show larger snippets so you can have more context.
Getting initial timestamp:
// Timer for switching logic and syncing threads. If time exceeds duration (specified in sec), switch endpoints.
// Block switcihing on every packet sent from server to client
var timer: ?std.Io.Clock.Timestamp = null;
const time: ?usize = config.switcher.timer;
var switcher_thread: ?std.Thread = null;
var packet_arrived = true;
// Comply with the switcher flag
if (config.switcher.enabled) if (time) |seconds| {
std.log.info("Spawning switcher thread....", .{});
timer = std.Io.Clock.Timestamp.now(io, .awake);
switcher_thread = try std.Thread.spawn(.{}, switcher, .{
io,
seconds,
&timer,
servers,
¤t_id,
&packet_arrived,
});
} else {
std.log.debug("Switcher enabled but timer interval value is: {any}", .{time});
return error.FailedToUnwrap;
} else {
std.log.info("Switching disabled, using endpoint derived form ID....", .{});
}
And my switcher thread where I do a reset and duration check:
fn switcher(
io: std.Io,
seconds: usize,
timer: *?std.Io.Clock.Timestamp,
servers: []std.Io.net.IpAddress,
current_id: *usize,
packet_arrived: *bool,
) !void {
// Unwrap timer optional
if (timer.*) |*t| {
// Declare constants once before the main loop
const duration: u64 = std.time.ns_per_s * seconds;
while (true) {
const elapsed = t.untilNow(io).raw.nanoseconds;
std.log.debug("Timer time elapsed: {d}", .{elapsed});
std.log.debug("Timer time duration: {d}", .{duration});
std.log.debug("Timer packet_arrived state: {}", .{packet_arrived.*});
// Main check is if packet has arrived
if (!packet_arrived.*) {
// Second check is if enough time has passsed before switching
if (elapsed < duration) {
try io.sleep(.fromNanoseconds(duration - elapsed), .awake);
continue;
}
const new_id = (current_id.* + 1) % servers.len;
current_id.* = new_id;
std.log.info("Switched servers endpoints!", .{});
std.log.info("Current endpoint: {f}", .{&servers[current_id.*]});
// Reset packet state
packet_arrived.* = true;
}
// Reset timer to sync threads
t.* = std.Io.Clock.Timestamp.now(io, .awake);
try io.sleep(.fromNanoseconds(duration), .awake);
}
} else {
std.log.err("Switcher got called but timer variable value is: {any}", .{timer});
return error.FailedToUnwrap;
}
}
In case you want to see more code, it’s from this tool I wrote:
For some reason I still hesitate to make an official showcase for it ![]()
FWIW you can rewrite this to:
const duration = start.durationTo(end);
…in my own code, I use this for elapsed time (where Timestamp has been imported as const Timestamp = std.Io.Timestamp;:
const startTime = Timestamp.now(io, .real);
// ...
const elapsedTime = startTime.untilNow(io, .real);
RIP Timer
. I thought it was a nice quick to understand bundle of functionality. Sad to see it go.
I recently replaced time.Timer in zbench ( GitHub - hendriknielaender/zBench: 📊 zig benchmark · GitHub ), the new “timer” is basically just
const t0 = Timestamp.now(io, .awake);
// do stuff synchronously
const t1_ns = t0.untilNow(io, .awake).toNanoseconds();
This appears plain and simple, no unnecessary abstraction. Even better, the new variant lets me choose a clock. Great work @ zig-contributors! And @floooh for highlighting this functionality here.
I was wondering how you toNanoseconds() function, and the difference is that I was using std.Io.Clock.Timestamp and you were using std.Io.Timestamp.
Yes, this is a bit confusing, that there are two kind of Timestamps. You should be able to use std.Io.Clock.Timestamp.raw to get the std.Io.Timestamp though.
just use event-driven-state-machines, like this