feature. See also
. The project being documented here (as the example) is the Zig library itself.
Uring.groupConcurrent
fn groupConcurrent(
userdata: ?*anyopaque,
type_erased: *Io.Group,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque) void,
) Io.ConcurrentError!void
File
Code
fn groupConcurrent(
userdata: ?*anyopaque,
type_erased: *Io.Group,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque) void,
) Io.ConcurrentError!void {
assert(context_alignment.compare(.lte, Fiber.max_context_align));
assert(context.len <= Fiber.max_context_size);
const ev: *Evented = @ptrCast(@alignCast(userdata));
const group: Group = .{ .ptr = type_erased };
const fiber = Fiber.create(ev) catch |err| switch (err) {
error.OutOfMemory => return error.ConcurrencyUnavailable,
};
const closure: *Group.AsyncClosure = .fromFiber(fiber);
fiber.* = .{
.required_align = {},
.context = switch (builtin.cpu.arch) {
.aarch64 => .{
.sp = @intFromPtr(closure),
.fp = 0,
.pc = @intFromPtr(&Group.AsyncClosure.entry),
},
.riscv64 => .{
.sp = @intFromPtr(closure),
.fp = 0,
.pc = @intFromPtr(&Group.AsyncClosure.entry),
},
.x86_64 => .{
.rsp = @intFromPtr(closure) - 8,
.rbp = 0,
.rip = @intFromPtr(&Group.AsyncClosure.entry),
},
else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)),
},
.link = .{ .group = .{ .prev = null, .next = null } },
.status = .{ .queue_next = null },
.cancel_status = .unrequested,
.cancel_protection = .unblocked,
.name = if (tracy.enable) name: {
const thread: *Thread = .current();
var name_arena = thread.name_arena.promote(std.heap.page_allocator);
defer thread.name_arena = name_arena.state;
break :name std.fmt.allocPrintSentinel(
name_arena.allocator(),
"group task {d}",
.{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)},
0,
) catch return error.ConcurrencyUnavailable;
},
};
closure.* = .{
.evented = ev,
.group = group,
.fiber = fiber,
.start = start,
};
@memcpy(closure.contextPointer(), context);
group.addFiber(ev, fiber);
const thread: *Thread = .current();
if (ev.schedule(thread, .{ .head = fiber, .tail = fiber })) thread.submit();
}