| ... | @@ -439,15 +439,14 @@ pub const Loop = struct { | ... | @@ -439,15 +439,14 @@ pub const Loop = struct { |
| 439 | | 439 | |
| 440 | pub async fn waitFd(self: *Loop, fd: i32) !void { | 440 | pub async fn waitFd(self: *Loop, fd: i32) !void { |
| 441 | defer self.removeFd(fd); | 441 | defer self.removeFd(fd); |
| 442 | var resume_node = ResumeNode{ | | |
| 443 | .id = ResumeNode.Id.Basic, | | |
| 444 | .handle = undefined, | | |
| 445 | }; | | |
| 446 | suspend |p| { | 442 | suspend |p| { |
| 447 | resume_node.handle = p; | 443 | // TODO explicitly put this memory in the coroutine frame #1194 |
| | 444 | var resume_node = ResumeNode{ |
| | 445 | .id = ResumeNode.Id.Basic, |
| | 446 | .handle = p, |
| | 447 | }; |
| 448 | try self.addFd(fd, &resume_node); | 448 | try self.addFd(fd, &resume_node); |
| 449 | } | 449 | } |
| 450 | var a = &resume_node; // TODO better way to explicitly put memory in coro frame | | |
| 451 | } | 450 | } |
| 452 | | 451 | |
| 453 | /// Bring your own linked list node. This means it can't fail. | 452 | /// Bring your own linked list node. This means it can't fail. |
| ... | @@ -618,8 +617,7 @@ pub const Loop = struct { | ... | @@ -618,8 +617,7 @@ pub const Loop = struct { |
| 618 | while (true) { | 617 | while (true) { |
| 619 | var nbytes: windows.DWORD = undefined; | 618 | var nbytes: windows.DWORD = undefined; |
| 620 | var overlapped: ?*windows.OVERLAPPED = undefined; | 619 | var overlapped: ?*windows.OVERLAPPED = undefined; |
| 621 | switch (std.os.windowsGetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, | 620 | switch (std.os.windowsGetQueuedCompletionStatus(self.os_data.io_port, &nbytes, &completion_key, &overlapped, windows.INFINITE)) { |
| 622 | &overlapped, windows.INFINITE)) { | | |
| 623 | std.os.WindowsWaitResult.Aborted => return, | 621 | std.os.WindowsWaitResult.Aborted => return, |
| 624 | std.os.WindowsWaitResult.Normal => {}, | 622 | std.os.WindowsWaitResult.Normal => {}, |
| 625 | } | 623 | } |
| ... | @@ -1062,10 +1060,13 @@ pub const Lock = struct { | ... | @@ -1062,10 +1060,13 @@ pub const Lock = struct { |
| 1062 | } | 1060 | } |
| 1063 | | 1061 | |
| 1064 | pub async fn acquire(self: *Lock) Held { | 1062 | pub async fn acquire(self: *Lock) Held { |
| 1065 | var my_tick_node: Loop.NextTickNode = undefined; | | |
| 1066 | | | |
| 1067 | s: suspend |handle| { | 1063 | s: suspend |handle| { |
| 1068 | my_tick_node.data = handle; | 1064 | // TODO explicitly put this memory in the coroutine frame #1194 |
| | 1065 | var my_tick_node = Loop.NextTickNode{ |
| | 1066 | .data = handle, |
| | 1067 | .next = undefined, |
| | 1068 | }; |
| | 1069 | |
| 1069 | self.queue.put(&my_tick_node); | 1070 | self.queue.put(&my_tick_node); |
| 1070 | | 1071 | |
| 1071 | // At this point, we are in the queue, so we might have already been resumed and this coroutine | 1072 | // At this point, we are in the queue, so we might have already been resumed and this coroutine |
| ... | @@ -1107,10 +1108,6 @@ pub const Lock = struct { | ... | @@ -1107,10 +1108,6 @@ pub const Lock = struct { |
| 1107 | } | 1108 | } |
| 1108 | } | 1109 | } |
| 1109 | | 1110 | |
| 1110 | // TODO this workaround to force my_tick_node to be in the coroutine frame should | | |
| 1111 | // not be necessary | | |
| 1112 | var trash1 = &my_tick_node; | | |
| 1113 | | | |
| 1114 | return Held{ .lock = self }; | 1111 | return Held{ .lock = self }; |
| 1115 | } | 1112 | } |
| 1116 | }; | 1113 | }; |
| ... | @@ -1176,6 +1173,10 @@ test "std.event.Lock" { | ... | @@ -1176,6 +1173,10 @@ test "std.event.Lock" { |
| 1176 | } | 1173 | } |
| 1177 | | 1174 | |
| 1178 | async fn testLock(loop: *Loop, lock: *Lock) void { | 1175 | async fn testLock(loop: *Loop, lock: *Lock) void { |
| | 1176 | // TODO explicitly put next tick node memory in the coroutine frame #1194 |
| | 1177 | suspend |p| { |
| | 1178 | resume p; |
| | 1179 | } |
| 1179 | const handle1 = async lockRunner(lock) catch @panic("out of memory"); | 1180 | const handle1 = async lockRunner(lock) catch @panic("out of memory"); |
| 1180 | var tick_node1 = Loop.NextTickNode{ | 1181 | var tick_node1 = Loop.NextTickNode{ |
| 1181 | .next = undefined, | 1182 | .next = undefined, |
| ... | @@ -1200,12 +1201,6 @@ async fn testLock(loop: *Loop, lock: *Lock) void { | ... | @@ -1200,12 +1201,6 @@ async fn testLock(loop: *Loop, lock: *Lock) void { |
| 1200 | await handle1; | 1201 | await handle1; |
| 1201 | await handle2; | 1202 | await handle2; |
| 1202 | await handle3; | 1203 | await handle3; |
| 1203 | | | |
| 1204 | // TODO this is to force tick node memory to be in the coro frame | | |
| 1205 | // there should be a way to make it explicit where the memory is | | |
| 1206 | var a = &tick_node1; | | |
| 1207 | var b = &tick_node2; | | |
| 1208 | var c = &tick_node3; | | |
| 1209 | } | 1204 | } |
| 1210 | | 1205 | |
| 1211 | var shared_test_data = [1]i32{0} ** 10; | 1206 | var shared_test_data = [1]i32{0} ** 10; |
| ... | @@ -1216,7 +1211,8 @@ async fn lockRunner(lock: *Lock) void { | ... | @@ -1216,7 +1211,8 @@ async fn lockRunner(lock: *Lock) void { |
| 1216 | | 1211 | |
| 1217 | var i: usize = 0; | 1212 | var i: usize = 0; |
| 1218 | while (i < shared_test_data.len) : (i += 1) { | 1213 | while (i < shared_test_data.len) : (i += 1) { |
| 1219 | const handle = await (async lock.acquire() catch @panic("out of memory")); | 1214 | const lock_promise = async lock.acquire() catch @panic("out of memory"); |
| | 1215 | const handle = await lock_promise; |
| 1220 | defer handle.release(); | 1216 | defer handle.release(); |
| 1221 | | 1217 | |
| 1222 | shared_test_index = 0; | 1218 | shared_test_index = 0; |