| ... | @@ -423,17 +423,35 @@ fn idle(k: *Kqueue, thread: *Thread) void { | ... | @@ -423,17 +423,35 @@ fn idle(k: *Kqueue, thread: *Thread) void { |
| 423 | return; | 423 | return; |
| 424 | }, | 424 | }, |
| 425 | _ => { | 425 | _ => { |
| 426 | const fiber: *Fiber = @ptrFromInt(event.udata); | 426 | const event_head_fiber: *Fiber = @ptrFromInt(event.udata); |
| 427 | assert(fiber.queue_next == null); | 427 | const event_tail_fiber = thread.wait_queues.fetchSwapRemove(.{ |
| 428 | fiber.resultPointer(Completion).* = .{ | 428 | .ident = event.ident, |
| | 429 | .filter = event.filter, |
| | 430 | }).?.value; |
| | 431 | assert(event_tail_fiber.queue_next == null); |
| | 432 | |
| | 433 | // TODO reevaluate this logic |
| | 434 | event_head_fiber.resultPointer(Completion).* = .{ |
| 429 | .flags = event.flags, | 435 | .flags = event.flags, |
| 430 | .fflags = event.fflags, | 436 | .fflags = event.fflags, |
| 431 | .data = event.data, | 437 | .data = event.data, |
| 432 | }; | 438 | }; |
| 433 | if (maybe_ready_fiber == null) maybe_ready_fiber = fiber else if (maybe_ready_queue) |*ready_queue| { | 439 | |
| 434 | ready_queue.tail.queue_next = fiber; | 440 | queue_ready: { |
| 435 | ready_queue.tail = fiber; | 441 | const head: *Fiber = if (maybe_ready_fiber == null) f: { |
| 436 | } else maybe_ready_queue = .{ .head = fiber, .tail = fiber }; | 442 | maybe_ready_fiber = event_head_fiber; |
| | 443 | const next = event_head_fiber.queue_next orelse break :queue_ready; |
| | 444 | event_head_fiber.queue_next = null; |
| | 445 | break :f next; |
| | 446 | } else event_head_fiber; |
| | 447 | |
| | 448 | if (maybe_ready_queue) |*ready_queue| { |
| | 449 | ready_queue.tail.queue_next = head; |
| | 450 | ready_queue.tail = event_tail_fiber; |
| | 451 | } else { |
| | 452 | maybe_ready_queue = .{ .head = head, .tail = event_tail_fiber }; |
| | 453 | } |
| | 454 | } |
| 437 | }, | 455 | }, |
| 438 | }; | 456 | }; |
| 439 | if (maybe_ready_queue) |ready_queue| k.schedule(thread, ready_queue); | 457 | if (maybe_ready_queue) |ready_queue| k.schedule(thread, ready_queue); |
| ... | @@ -1477,7 +1495,6 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea | ... | @@ -1477,7 +1495,6 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea |
| 1477 | | 1495 | |
| 1478 | while (true) { | 1496 | while (true) { |
| 1479 | try k.checkCancel(); | 1497 | try k.checkCancel(); |
| 1480 | std.debug.print("calling readv\n", .{}); | | |
| 1481 | const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len)); | 1498 | const rc = posix.system.readv(fd, dest.ptr, @intCast(dest.len)); |
| 1482 | switch (posix.errno(rc)) { | 1499 | switch (posix.errno(rc)) { |
| 1483 | .SUCCESS => return @intCast(rc), | 1500 | .SUCCESS => return @intCast(rc), |
| ... | @@ -1486,19 +1503,33 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea | ... | @@ -1486,19 +1503,33 @@ fn netRead(userdata: ?*anyopaque, fd: net.Socket.Handle, data: [][]u8) net.Strea |
| 1486 | .AGAIN => { | 1503 | .AGAIN => { |
| 1487 | const thread: *Thread = .current(); | 1504 | const thread: *Thread = .current(); |
| 1488 | const fiber = thread.currentFiber(); | 1505 | const fiber = thread.currentFiber(); |
| 1489 | const changes = [_]posix.Kevent{ | 1506 | const ident: u32 = @bitCast(fd); |
| 1490 | .{ | 1507 | const filter = std.c.EVFILT.READ; |
| 1491 | .ident = @as(u32, @bitCast(fd)), | 1508 | const gop = thread.wait_queues.getOrPut(k.gpa, .{ |
| 1492 | .filter = std.c.EVFILT.READ, | 1509 | .ident = ident, |
| 1493 | .flags = std.c.EV.ADD | std.c.EV.ONESHOT, | 1510 | .filter = filter, |
| 1494 | .fflags = 0, | 1511 | }) catch return error.SystemResources; |
| 1495 | .data = 0, | 1512 | if (gop.found_existing) { |
| 1496 | .udata = @intFromPtr(fiber), | 1513 | const tail_fiber = gop.value_ptr.*; |
| 1497 | }, | 1514 | assert(tail_fiber.queue_next == null); |
| 1498 | }; | 1515 | tail_fiber.queue_next = fiber; |
| 1499 | assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { | 1516 | gop.value_ptr.* = fiber; |
| 1500 | @panic(@errorName(err)); // TODO | 1517 | } else { |
| 1501 | })); | 1518 | gop.value_ptr.* = fiber; |
| | 1519 | const changes = [_]posix.Kevent{ |
| | 1520 | .{ |
| | 1521 | .ident = ident, |
| | 1522 | .filter = filter, |
| | 1523 | .flags = std.c.EV.ADD | std.c.EV.ONESHOT, |
| | 1524 | .fflags = 0, |
| | 1525 | .data = 0, |
| | 1526 | .udata = @intFromPtr(fiber), |
| | 1527 | }, |
| | 1528 | }; |
| | 1529 | assert(0 == (posix.kevent(thread.kq_fd, &changes, &.{}, null) catch |err| { |
| | 1530 | @panic(@errorName(err)); // TODO |
| | 1531 | })); |
| | 1532 | } |
| 1502 | yield(k, null, .nothing); | 1533 | yield(k, null, .nothing); |
| 1503 | continue; | 1534 | continue; |
| 1504 | }, | 1535 | }, |