authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-06 22:25:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-10 17:51:07-07:00
log3efdfe612ec7aaf252f6391b4d29bbf46118eced
treed4187a0f555e84ef23e6bbd4e8be89a9f83c1d94
parentffd53a459e1b665e5070987f68dd583171a12459

std.Thread.WaitGroup: add spawnManaged

Provides a convenient way to spawn a new thread that bypasses a thread pool. Appropriate when the spawned thread delegates all of its work.

1 files changed, 22 insertions(+), 0 deletions(-)

lib/std/Thread/WaitGroup.zig+22
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const assert = std.debug.assert;3const assert = std.debug.assert;
3const WaitGroup = @This();4const WaitGroup = @This();
...@@ -43,3 +44,24 @@ pub fn isDone(wg: *WaitGroup) bool {...@@ -43,3 +44,24 @@ pub fn isDone(wg: *WaitGroup) bool {
4344
44 return (state / one_pending) == 0;45 return (state / one_pending) == 0;
45}46}
47
48// Spawns a new thread for the task. This is appropriate when the callee
49// delegates all work.
50pub fn spawnManager(
51 wg: *WaitGroup,
52 comptime func: anytype,
53 args: anytype,
54) void {
55 if (builtin.single_threaded) {
56 @call(.auto, func, args);
57 return;
58 }
59 const Manager = struct {
60 fn run(wg_inner: *WaitGroup, args_inner: @TypeOf(args)) void {
61 defer wg_inner.finish();
62 @call(.auto, func, args_inner);
63 }
64 };
65 wg.start();
66 _ = std.Thread.spawn(.{}, Manager.run, .{ wg, args }) catch Manager.run(wg, args);
67}