| ... | @@ -309,46 +309,80 @@ pub fn getIdCount(pool: *Pool) usize { | ... | @@ -309,46 +309,80 @@ pub fn getIdCount(pool: *Pool) usize { |
| 309 | return @intCast(1 + pool.threads.len); | 309 | return @intCast(1 + pool.threads.len); |
| 310 | } | 310 | } |
| 311 | | 311 | |
| | 312 | pub fn io(pool: *Pool) std.Io { |
| | 313 | return .{ |
| | 314 | .userdata = pool, |
| | 315 | .vtable = &.{ |
| | 316 | .@"async" = @"async", |
| | 317 | .@"await" = @"await", |
| | 318 | }, |
| | 319 | }; |
| | 320 | } |
| | 321 | |
| 312 | const AsyncClosure = struct { | 322 | const AsyncClosure = struct { |
| 313 | func: *const fn (context: ?*anyopaque, result: *anyopaque) void, | 323 | func: *const fn (context: *anyopaque, result: *anyopaque) void, |
| 314 | context: ?*anyopaque, | | |
| 315 | run_node: std.Thread.Pool.RunQueue.Node = .{ .data = .{ .runFn = runFn } }, | 324 | run_node: std.Thread.Pool.RunQueue.Node = .{ .data = .{ .runFn = runFn } }, |
| 316 | reset_event: std.Thread.ResetEvent, | 325 | reset_event: std.Thread.ResetEvent, |
| | 326 | context_offset: usize, |
| | 327 | result_offset: usize, |
| 317 | | 328 | |
| 318 | fn runFn(runnable: *std.Thread.Pool.Runnable, _: ?usize) void { | 329 | fn runFn(runnable: *std.Thread.Pool.Runnable, _: ?usize) void { |
| 319 | const run_node: *std.Thread.Pool.RunQueue.Node = @fieldParentPtr("data", runnable); | 330 | const run_node: *std.Thread.Pool.RunQueue.Node = @fieldParentPtr("data", runnable); |
| 320 | const closure: *@This() = @alignCast(@fieldParentPtr("run_node", run_node)); | 331 | const closure: *AsyncClosure = @alignCast(@fieldParentPtr("run_node", run_node)); |
| 321 | closure.func(closure.context, closure.resultPointer()); | 332 | closure.func(closure.contextPointer(), closure.resultPointer()); |
| 322 | closure.reset_event.set(); | 333 | closure.reset_event.set(); |
| 323 | } | 334 | } |
| 324 | | 335 | |
| 325 | fn resultPointer(closure: *@This()) [*]u8 { | 336 | fn contextOffset(context_alignment: std.mem.Alignment) usize { |
| | 337 | return context_alignment.forward(@sizeOf(AsyncClosure)); |
| | 338 | } |
| | 339 | |
| | 340 | fn resultOffset( |
| | 341 | context_alignment: std.mem.Alignment, |
| | 342 | context_len: usize, |
| | 343 | result_alignment: std.mem.Alignment, |
| | 344 | ) usize { |
| | 345 | return result_alignment.forward(contextOffset(context_alignment) + context_len); |
| | 346 | } |
| | 347 | |
| | 348 | fn resultPointer(closure: *AsyncClosure) [*]u8 { |
| | 349 | const base: [*]u8 = @ptrCast(closure); |
| | 350 | return base + closure.result_offset; |
| | 351 | } |
| | 352 | |
| | 353 | fn contextPointer(closure: *AsyncClosure) [*]u8 { |
| 326 | const base: [*]u8 = @ptrCast(closure); | 354 | const base: [*]u8 = @ptrCast(closure); |
| 327 | return base + @sizeOf(@This()); | 355 | return base + closure.context_offset; |
| 328 | } | 356 | } |
| 329 | }; | 357 | }; |
| 330 | | 358 | |
| 331 | pub fn @"async"( | 359 | pub fn @"async"( |
| 332 | userdata: ?*anyopaque, | 360 | userdata: ?*anyopaque, |
| 333 | eager_result: []u8, | 361 | result: []u8, |
| 334 | context: ?*anyopaque, | 362 | result_alignment: std.mem.Alignment, |
| 335 | start: *const fn (context: ?*anyopaque, result: *anyopaque) void, | 363 | context: []const u8, |
| | 364 | context_alignment: std.mem.Alignment, |
| | 365 | start: *const fn (context: *const anyopaque, result: *anyopaque) void, |
| 336 | ) ?*std.Io.AnyFuture { | 366 | ) ?*std.Io.AnyFuture { |
| 337 | const pool: *std.Thread.Pool = @alignCast(@ptrCast(userdata)); | 367 | const pool: *std.Thread.Pool = @alignCast(@ptrCast(userdata)); |
| 338 | pool.mutex.lock(); | 368 | pool.mutex.lock(); |
| 339 | | 369 | |
| 340 | const gpa = pool.allocator; | 370 | const gpa = pool.allocator; |
| 341 | const n = @sizeOf(AsyncClosure) + eager_result.len; | 371 | const context_offset = context_alignment.forward(@sizeOf(AsyncClosure)); |
| | 372 | const result_offset = result_alignment.forward(context_offset + context.len); |
| | 373 | const n = result_offset + result.len; |
| 342 | const closure: *AsyncClosure = @alignCast(@ptrCast(gpa.alignedAlloc(u8, @alignOf(AsyncClosure), n) catch { | 374 | const closure: *AsyncClosure = @alignCast(@ptrCast(gpa.alignedAlloc(u8, @alignOf(AsyncClosure), n) catch { |
| 343 | pool.mutex.unlock(); | 375 | pool.mutex.unlock(); |
| 344 | start(context, eager_result.ptr); | 376 | start(context.ptr, result.ptr); |
| 345 | return null; | 377 | return null; |
| 346 | })); | 378 | })); |
| 347 | closure.* = .{ | 379 | closure.* = .{ |
| 348 | .func = start, | 380 | .func = start, |
| 349 | .context = context, | 381 | .context_offset = context_offset, |
| | 382 | .result_offset = result_offset, |
| 350 | .reset_event = .{}, | 383 | .reset_event = .{}, |
| 351 | }; | 384 | }; |
| | 385 | @memcpy(closure.contextPointer()[0..context.len], context); |
| 352 | pool.run_queue.prepend(&closure.run_node); | 386 | pool.run_queue.prepend(&closure.run_node); |
| 353 | pool.mutex.unlock(); | 387 | pool.mutex.unlock(); |
| 354 | | 388 | |