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