Backlog/projects/headless/main.zig

128 lines
3.2 KiB
Zig

allocator: std.mem.Allocator = undefined,
timeLeft: f64 = 5.0,
pub var NeonObjectTable: core.EngineObjectVTable = core.EngineObjectVTable.from(@This(), "Headless");
pub fn create(allocator: std.mem.Allocator) !*@This() {
const self = try allocator.create(@This());
self.* = .{
.allocator = allocator,
};
return self;
}
pub fn prepare(self: *@This()) !void {
try self.testThing();
}
pub fn tick(self: *@This(), dt: f64) void {
// std.Thread.sleep(1000_000);
self.timeLeft -= dt;
if (self.timeLeft < 0)
core.exitNow();
const start = core.getEngineTime();
// wait 10 ms
while (core.getEngineTime() - start < 0.010) {
std.Thread.sleep(10_000_000);
}
}
pub fn deinit(self: *@This()) void {
self.allocator.destroy(self);
}
const Src = std.builtin.SourceLocation;
pub fn Barrier(src: Src) type {
return struct {
pub const Src = src;
pub var count: u32 = 0;
pub var generation: u32 = 0;
pub var mutex: std.Thread.Mutex = .{};
pub var cv: std.Thread.Condition = .{};
pub fn sync(threadId: u32) !void {
_ = threadId;
const barrierCount = core.getBarrierCount();
mutex.lock();
defer mutex.unlock();
count += 1;
if (count == barrierCount) {
// 2 second timeout
count = 0;
generation += 1;
cv.broadcast();
} else {
try cv.timedWait(&mutex, 1000 * 1000 * 1000 * 2);
}
}
};
}
const MultiJob = struct {
pub var WorkGroupData = WorkGroupData.from(@This());
threadId: u32 = 0,
threadName: []const u8,
pub var cv: std.Thread.Condition = .{};
pub var mutex: std.Thread.Mutex = .{};
pub fn func(ctx: @This(), job: *core.JobContext) void {
_ = job;
core.tracy.SetThreadName(@ptrCast(ctx.threadName.ptr));
ctx.loop() catch {};
if (core.getEngine().isShuttingDown()) {}
}
pub fn loop(ctx: @This()) !void {
while (!core.getEngine().isShuttingDown()) {
try Barrier(@src()).sync(ctx.threadId);
try ctx.tick();
if (ctx.threadId == 0) {
const z = core.tracy.ZoneN(@src(), "Thread 0 sleep");
defer z.End();
core.waitSeconds(0.01);
}
}
}
pub fn tick(ctx: @This()) !void {
const z = core.tracy.ZoneN(@src(), "MultiJob Tick");
defer z.End();
// std.Thread.sleep(100_000 * ctx.threadId);
try Barrier(@src()).sync(ctx.threadId);
}
};
pub fn testThing(self: *@This()) !void {
_ = self;
const workerCount = 16;
core.setBarrierCount(workerCount);
for (0..workerCount) |i| {
const name = try std.fmt.allocPrintZ(std.heap.c_allocator, "MultiJob{d}", .{i});
try core.dispatchJob(MultiJob{ .threadName = name, .threadId = @intCast(i) });
}
}
pub fn main() anyerror!void {
var spec = try backlog.getSpec("headless");
// try spec.put("useGPA", .{ .boolean = false });
_ = backlog.startEngine(&NeonObjectTable, &spec);
}
const std = @import("std");
const backlog = @import("backlog");
const core = backlog.core;