aboutsummaryrefslogtreecommitdiff
path: root/src/scheduler.zig
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2025-04-26 23:21:56 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2025-04-26 23:21:56 +0200
commite2f01d5df22704bfe62396a0f9a260f86edbde0e (patch)
tree86eba9adc57cbf1cab53b48bc56df73477a2dc7a /src/scheduler.zig
parent922db9c5fc50b82182fb5a0b4e3c8bb18fc2e0ab (diff)
generate: add multi-threading
Diffstat (limited to 'src/scheduler.zig')
-rw-r--r--src/scheduler.zig60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/scheduler.zig b/src/scheduler.zig
new file mode 100644
index 0000000..b2ab0db
--- /dev/null
+++ b/src/scheduler.zig
@@ -0,0 +1,60 @@
+const std = @import("std");
+
+pub fn Scheduler(function: anytype) type {
+ const FuncType = @TypeOf(function);
+ const func_info = @typeInfo(FuncType).Fn;
+ const R = func_info.return_type orelse std.builtin.Type.Void;
+ const ArgType = std.meta.ArgsTuple(FuncType);
+
+ const wrapper = struct {
+ pub fn call(args: ArgType, result: *R) void {
+ result.* = @call(.auto, function, args);
+ }
+ }.call;
+
+ return struct {
+ const Self = @This();
+
+ allocator: std.mem.Allocator,
+ pool: std.Thread.Pool,
+ wait_group: std.Thread.WaitGroup,
+ results: std.ArrayList(*R),
+
+ pub fn init(self: *Self, allocator: std.mem.Allocator) !void {
+ self.allocator = allocator;
+ self.results = std.ArrayList(*R).init(allocator);
+ self.wait_group.reset();
+
+ try self.pool.init(.{
+ .allocator = allocator,
+ });
+ }
+
+ pub fn push_task(self: *Self, args: ArgType) !void {
+ const result = try self.allocator.create(R);
+ try self.results.append(result);
+ self.pool.spawnWg(
+ &self.wait_group,
+ wrapper,
+ .{ args, result }
+ );
+ }
+
+ pub fn deinit(self: *Self) ![]R {
+ self.pool.waitAndWork(&self.wait_group);
+ self.pool.deinit();
+
+ const results = try self.allocator.alloc(R, self.results.items.len);
+
+ for (self.results.items, 0..) |result, index| {
+ results[index] = result.*;
+ self.allocator.destroy(result);
+ }
+
+ self.results.deinit();
+ self.* = undefined;
+
+ return results;
+ }
+ };
+}