feature. See also
. The project being documented here (as the example) is the Zig library itself.
Uring.concurrent
fn concurrent(
userdata: ?*anyopaque,
result_len: usize,
result_alignment: Alignment,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque, result: *anyopaque) void,
) Io.ConcurrentError!*std.Io.AnyFuture
File
Code
fn concurrent(
userdata: ?*anyopaque,
result_len: usize,
result_alignment: Alignment,
context: []const u8,
context_alignment: Alignment,
start: *const fn (context: *const anyopaque, result: *anyopaque) void,
) Io.ConcurrentError!*std.Io.AnyFuture {
assert(result_alignment.compare(.lte, Fiber.max_result_align));
assert(context_alignment.compare(.lte, Fiber.max_context_align));
assert(result_len <= Fiber.max_result_size);
assert(context.len <= Fiber.max_context_size);
const ev: *Evented = @ptrCast(@alignCast(userdata));
const fiber = Fiber.create(ev) catch |err| switch (err) {
error.OutOfMemory => return error.ConcurrencyUnavailable,
};
const closure: *AsyncClosure = .fromFiber(fiber);
fiber.* = .{
.required_align = {},
.context = switch (builtin.cpu.arch) {
.aarch64 => .{
.sp = @intFromPtr(closure),
.fp = 0,
.pc = @intFromPtr(&AsyncClosure.entry),
},
.riscv64 => .{
.sp = @intFromPtr(closure),
.fp = 0,
.pc = @intFromPtr(&AsyncClosure.entry),
},
.x86_64 => .{
.rsp = @intFromPtr(closure) - 8,
.rbp = 0,
.rip = @intFromPtr(&AsyncClosure.entry),
},
else => |arch| @compileError("unimplemented architecture: " ++ @tagName(arch)),
},
.link = .{ .awaiter = 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(),
"task {d}",
.{@atomicRmw(u64, &Fiber.next_name, .Add, 1, .monotonic)},
0,
) catch return error.ConcurrencyUnavailable;
},
};
closure.* = .{
.evented = ev,
.fiber = fiber,
.start = start,
.result_align = result_alignment,
};
@memcpy(closure.contextPointer(), context);
const thread: *Thread = .current();
if (ev.schedule(thread, .{ .head = fiber, .tail = fiber })) thread.submit();
return @ptrCast(fiber);
}