| ... | ... | @@ -26,7 +26,6 @@ const Thread = struct { |
| 26 | 26 | idle_context: Context, |
| 27 | 27 | current_context: *Context, |
| 28 | 28 | ready_queue: ?*Fiber, |
| 29 | | free_queue: ?*Fiber, |
| 30 | 29 | io_uring: IoUring, |
| 31 | 30 | idle_search_index: u32, |
| 32 | 31 | steal_ready_search_index: u32, |
| ... | ... | @@ -78,12 +77,6 @@ const Fiber = struct { |
| 78 | 77 | ); |
| 79 | 78 | |
| 80 | 79 | fn allocate(el: *EventLoop) error{OutOfMemory}!*Fiber { |
| 81 | | const thread: *Thread = .current(); |
| 82 | | if (thread.free_queue) |free_fiber| { |
| 83 | | thread.free_queue = free_fiber.queue_next; |
| 84 | | free_fiber.queue_next = null; |
| 85 | | return free_fiber; |
| 86 | | } |
| 87 | 80 | return @ptrCast(try el.gpa.alignedAlloc(u8, @alignOf(Fiber), allocation_size)); |
| 88 | 81 | } |
| 89 | 82 | |
| ... | ... | @@ -129,18 +122,15 @@ const Fiber = struct { |
| 129 | 122 | )) |cancel_thread| assert(cancel_thread == Thread.canceling); |
| 130 | 123 | } |
| 131 | 124 | |
| 132 | | fn recycle(fiber: *Fiber) void { |
| 133 | | const thread: *Thread = .current(); |
| 134 | | std.log.debug("recyling {*}", .{fiber}); |
| 135 | | assert(fiber.queue_next == null); |
| 136 | | //@memset(fiber.allocatedSlice(), undefined); // (race) |
| 137 | | fiber.queue_next = thread.free_queue; |
| 138 | | thread.free_queue = fiber; |
| 139 | | } |
| 140 | | |
| 141 | 125 | const Queue = struct { head: *Fiber, tail: *Fiber }; |
| 142 | 126 | }; |
| 143 | 127 | |
| 128 | fn recycle(el: *EventLoop, fiber: *Fiber) void { |
| 129 | std.log.debug("recyling {*}", .{fiber}); |
| 130 | assert(fiber.queue_next == null); |
| 131 | el.gpa.free(fiber.allocatedSlice()); |
| 132 | } |
| 133 | |
| 144 | 134 | pub fn io(el: *EventLoop) Io { |
| 145 | 135 | return .{ |
| 146 | 136 | .userdata = el, |
| ... | ... | @@ -207,7 +197,6 @@ pub fn init(el: *EventLoop, gpa: Allocator) !void { |
| 207 | 197 | }, |
| 208 | 198 | .current_context = &main_fiber.context, |
| 209 | 199 | .ready_queue = null, |
| 210 | | .free_queue = null, |
| 211 | 200 | .io_uring = try IoUring.init(io_uring_entries, 0), |
| 212 | 201 | .idle_search_index = 1, |
| 213 | 202 | .steal_ready_search_index = 1, |
| ... | ... | @@ -227,11 +216,6 @@ pub fn deinit(el: *EventLoop) void { |
| 227 | 216 | const allocated_ptr: [*]align(@alignOf(Thread)) u8 = @alignCast(@ptrCast(el.threads.allocated.ptr)); |
| 228 | 217 | const idle_stack_end_offset = std.mem.alignForward(usize, el.threads.allocated.len * @sizeOf(Thread) + idle_stack_size, std.heap.page_size_max); |
| 229 | 218 | for (el.threads.allocated[1..active_threads]) |*thread| thread.thread.join(); |
| 230 | | for (el.threads.allocated[0..active_threads]) |*thread| while (thread.free_queue) |free_fiber| { |
| 231 | | thread.free_queue = free_fiber.queue_next; |
| 232 | | free_fiber.queue_next = null; |
| 233 | | el.gpa.free(free_fiber.allocatedSlice()); |
| 234 | | }; |
| 235 | 219 | el.gpa.free(allocated_ptr[0..idle_stack_end_offset]); |
| 236 | 220 | el.* = undefined; |
| 237 | 221 | } |
| ... | ... | @@ -343,7 +327,6 @@ fn schedule(el: *EventLoop, thread: *Thread, ready_queue: Fiber.Queue) void { |
| 343 | 327 | .idle_context = undefined, |
| 344 | 328 | .current_context = &new_thread.idle_context, |
| 345 | 329 | .ready_queue = ready_queue.head, |
| 346 | | .free_queue = null, |
| 347 | 330 | .io_uring = IoUring.init(io_uring_entries, 0) catch |err| { |
| 348 | 331 | @atomicStore(u32, &el.threads.reserved, new_thread_index, .release); |
| 349 | 332 | // no more access to `thread` after giving up reservation |
| ... | ... | @@ -501,7 +484,7 @@ const SwitchMessage = struct { |
| 501 | 484 | el.schedule(thread, .{ .head = prev_fiber, .tail = prev_fiber }); |
| 502 | 485 | }, |
| 503 | 486 | .recycle => |fiber| { |
| 504 | | fiber.recycle(); |
| 487 | el.recycle(fiber); |
| 505 | 488 | }, |
| 506 | 489 | .register_awaiter => |awaiter| { |
| 507 | 490 | const prev_fiber: *Fiber = @alignCast(@fieldParentPtr("context", message.contexts.prev)); |
| ... | ... | @@ -795,7 +778,7 @@ fn @"await"( |
| 795 | 778 | if (@atomicLoad(?*Fiber, &future_fiber.awaiter, .acquire) != Fiber.finished) |
| 796 | 779 | event_loop.yield(null, .{ .register_awaiter = &future_fiber.awaiter }); |
| 797 | 780 | @memcpy(result, future_fiber.resultBytes(result_alignment)); |
| 798 | | future_fiber.recycle(); |
| 781 | event_loop.recycle(future_fiber); |
| 799 | 782 | } |
| 800 | 783 | |
| 801 | 784 | fn cancel( |