authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-04-04 15:19:55-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-20 10:38:39-07:00
log3f524ac5dc243585495bb16c15d00f13923fee6e
tree33afaa921414614c5822a8abcf738a6cfb3b9112
parent3178cf07f297a1a5f3e852a4f33a14dd9463ba07

Io: update for new linked list API


2 files changed, 43 insertions(+), 46 deletions(-)

lib/std/Io.zig+40-42
...@@ -1270,17 +1270,19 @@ pub const TypeErasedQueue = struct {...@@ -1270,17 +1270,19 @@ pub const TypeErasedQueue = struct {
1270 put_index: usize,1270 put_index: usize,
1271 get_index: usize,1271 get_index: usize,
12721272
1273 putters: std.DoublyLinkedList(PutNode),1273 putters: std.DoublyLinkedList,
1274 getters: std.DoublyLinkedList(GetNode),1274 getters: std.DoublyLinkedList,
12751275
1276 const PutNode = struct {1276 const Put = struct {
1277 remaining: []const u8,1277 remaining: []const u8,
1278 condition: Condition,1278 condition: Condition,
1279 node: std.DoublyLinkedList.Node,
1279 };1280 };
12801281
1281 const GetNode = struct {1282 const Get = struct {
1282 remaining: []u8,1283 remaining: []u8,
1283 condition: Condition,1284 condition: Condition,
1285 node: std.DoublyLinkedList.Node,
1284 };1286 };
12851287
1286 pub fn init(buffer: []u8) TypeErasedQueue {1288 pub fn init(buffer: []u8) TypeErasedQueue {
...@@ -1305,16 +1307,16 @@ pub const TypeErasedQueue = struct {...@@ -1305,16 +1307,16 @@ pub const TypeErasedQueue = struct {
13051307
1306 var remaining = elements;1308 var remaining = elements;
1307 while (true) {1309 while (true) {
1308 const getter = q.getters.popFirst() orelse break;1310 const getter: *Get = @fieldParentPtr("node", q.getters.popFirst() orelse break);
1309 const copy_len = @min(getter.data.remaining.len, remaining.len);1311 const copy_len = @min(getter.remaining.len, remaining.len);
1310 @memcpy(getter.data.remaining[0..copy_len], remaining[0..copy_len]);1312 @memcpy(getter.remaining[0..copy_len], remaining[0..copy_len]);
1311 remaining = remaining[copy_len..];1313 remaining = remaining[copy_len..];
1312 getter.data.remaining = getter.data.remaining[copy_len..];1314 getter.remaining = getter.remaining[copy_len..];
1313 if (getter.data.remaining.len == 0) {1315 if (getter.remaining.len == 0) {
1314 getter.data.condition.signal(io);1316 getter.condition.signal(io);
1315 continue;1317 continue;
1316 }1318 }
1317 q.getters.prepend(getter);1319 q.getters.prepend(&getter.node);
1318 assert(remaining.len == 0);1320 assert(remaining.len == 0);
1319 return elements.len;1321 return elements.len;
1320 }1322 }
...@@ -1340,12 +1342,10 @@ pub const TypeErasedQueue = struct {...@@ -1340,12 +1342,10 @@ pub const TypeErasedQueue = struct {
1340 const total_filled = elements.len - remaining.len;1342 const total_filled = elements.len - remaining.len;
1341 if (total_filled >= min) return total_filled;1343 if (total_filled >= min) return total_filled;
13421344
1343 var node: std.DoublyLinkedList(PutNode).Node = .{1345 var pending: Put = .{ .remaining = remaining, .condition = .{}, .node = .{} };
1344 .data = .{ .remaining = remaining, .condition = .{} },1346 q.putters.append(&pending.node);
1345 };1347 try pending.condition.wait(io, &q.mutex);
1346 q.putters.append(&node);1348 remaining = pending.remaining;
1347 try node.data.condition.wait(io, &q.mutex);
1348 remaining = node.data.remaining;
1349 }1349 }
1350 }1350 }
13511351
...@@ -1388,16 +1388,16 @@ pub const TypeErasedQueue = struct {...@@ -1388,16 +1388,16 @@ pub const TypeErasedQueue = struct {
1388 }1388 }
1389 // Copy directly from putters into buffer.1389 // Copy directly from putters into buffer.
1390 while (remaining.len > 0) {1390 while (remaining.len > 0) {
1391 const putter = q.putters.popFirst() orelse break;1391 const putter: *Put = @fieldParentPtr("node", q.putters.popFirst() orelse break);
1392 const copy_len = @min(putter.data.remaining.len, remaining.len);1392 const copy_len = @min(putter.remaining.len, remaining.len);
1393 @memcpy(remaining[0..copy_len], putter.data.remaining[0..copy_len]);1393 @memcpy(remaining[0..copy_len], putter.remaining[0..copy_len]);
1394 putter.data.remaining = putter.data.remaining[copy_len..];1394 putter.remaining = putter.remaining[copy_len..];
1395 remaining = remaining[copy_len..];1395 remaining = remaining[copy_len..];
1396 if (putter.data.remaining.len == 0) {1396 if (putter.remaining.len == 0) {
1397 putter.data.condition.signal(io);1397 putter.condition.signal(io);
1398 } else {1398 } else {
1399 assert(remaining.len == 0);1399 assert(remaining.len == 0);
1400 q.putters.prepend(putter);1400 q.putters.prepend(&putter.node);
1401 return fillRingBufferFromPutters(q, io, buffer.len);1401 return fillRingBufferFromPutters(q, io, buffer.len);
1402 }1402 }
1403 }1403 }
...@@ -1405,12 +1405,10 @@ pub const TypeErasedQueue = struct {...@@ -1405,12 +1405,10 @@ pub const TypeErasedQueue = struct {
1405 const total_filled = buffer.len - remaining.len;1405 const total_filled = buffer.len - remaining.len;
1406 if (total_filled >= min) return total_filled;1406 if (total_filled >= min) return total_filled;
14071407
1408 var node: std.DoublyLinkedList(GetNode).Node = .{1408 var pending: Get = .{ .remaining = remaining, .condition = .{}, .node = .{} };
1409 .data = .{ .remaining = remaining, .condition = .{} },1409 q.getters.append(&pending.node);
1410 };1410 try pending.condition.wait(io, &q.mutex);
1411 q.getters.append(&node);1411 remaining = pending.remaining;
1412 try node.data.condition.wait(io, &q.mutex);
1413 remaining = node.data.remaining;
1414 }1412 }
1415 }1413 }
14161414
...@@ -1420,26 +1418,26 @@ pub const TypeErasedQueue = struct {...@@ -1420,26 +1418,26 @@ pub const TypeErasedQueue = struct {
1420 /// buffers been fully copied.1418 /// buffers been fully copied.
1421 fn fillRingBufferFromPutters(q: *TypeErasedQueue, io: Io, len: usize) usize {1419 fn fillRingBufferFromPutters(q: *TypeErasedQueue, io: Io, len: usize) usize {
1422 while (true) {1420 while (true) {
1423 const putter = q.putters.popFirst() orelse return len;1421 const putter: *Put = @fieldParentPtr("node", q.putters.popFirst() orelse return len);
1424 const available = q.buffer[q.put_index..];1422 const available = q.buffer[q.put_index..];
1425 const copy_len = @min(available.len, putter.data.remaining.len);1423 const copy_len = @min(available.len, putter.remaining.len);
1426 @memcpy(available[0..copy_len], putter.data.remaining[0..copy_len]);1424 @memcpy(available[0..copy_len], putter.remaining[0..copy_len]);
1427 putter.data.remaining = putter.data.remaining[copy_len..];1425 putter.remaining = putter.remaining[copy_len..];
1428 q.put_index += copy_len;1426 q.put_index += copy_len;
1429 if (putter.data.remaining.len == 0) {1427 if (putter.remaining.len == 0) {
1430 putter.data.condition.signal(io);1428 putter.condition.signal(io);
1431 continue;1429 continue;
1432 }1430 }
1433 const second_available = q.buffer[0..q.get_index];1431 const second_available = q.buffer[0..q.get_index];
1434 const second_copy_len = @min(second_available.len, putter.data.remaining.len);1432 const second_copy_len = @min(second_available.len, putter.remaining.len);
1435 @memcpy(second_available[0..second_copy_len], putter.data.remaining[0..second_copy_len]);1433 @memcpy(second_available[0..second_copy_len], putter.remaining[0..second_copy_len]);
1436 putter.data.remaining = putter.data.remaining[copy_len..];1434 putter.remaining = putter.remaining[copy_len..];
1437 q.put_index = copy_len;1435 q.put_index = copy_len;
1438 if (putter.data.remaining.len == 0) {1436 if (putter.remaining.len == 0) {
1439 putter.data.condition.signal(io);1437 putter.condition.signal(io);
1440 continue;1438 continue;
1441 }1439 }
1442 q.putters.prepend(putter);1440 q.putters.prepend(&putter.node);
1443 return len;1441 return len;
1444 }1442 }
1445 }1443 }
lib/std/Io/EventLoop.zig+3-4
...@@ -13,7 +13,7 @@ main_fiber_buffer: [@sizeOf(Fiber) + Fiber.max_result_size]u8 align(@alignOf(Fib...@@ -13,7 +13,7 @@ main_fiber_buffer: [@sizeOf(Fiber) + Fiber.max_result_size]u8 align(@alignOf(Fib
13threads: Thread.List,13threads: Thread.List,
14detached: struct {14detached: struct {
15 mutex: std.Io.Mutex,15 mutex: std.Io.Mutex,
16 list: std.DoublyLinkedList(void),16 list: std.DoublyLinkedList,
17},17},
1818
19/// Empirically saw >128KB being used by the self-hosted backend to panic.19/// Empirically saw >128KB being used by the self-hosted backend to panic.
...@@ -226,7 +226,6 @@ pub fn deinit(el: *EventLoop) void {...@@ -226,7 +226,6 @@ pub fn deinit(el: *EventLoop) void {
226 detached.detached_queue_node = .{226 detached.detached_queue_node = .{
227 .prev = &detached.detached_queue_node,227 .prev = &detached.detached_queue_node,
228 .next = &detached.detached_queue_node,228 .next = &detached.detached_queue_node,
229 .data = {},
230 };229 };
231 break :detached_future @ptrCast(detached.fiber);230 break :detached_future @ptrCast(detached.fiber);
232 }, &.{}, .@"1");231 }, &.{}, .@"1");
...@@ -753,7 +752,7 @@ const DetachedClosure = struct {...@@ -753,7 +752,7 @@ const DetachedClosure = struct {
753 event_loop: *EventLoop,752 event_loop: *EventLoop,
754 fiber: *Fiber,753 fiber: *Fiber,
755 start: *const fn (context: *const anyopaque) void,754 start: *const fn (context: *const anyopaque) void,
756 detached_queue_node: std.DoublyLinkedList(void).Node,755 detached_queue_node: std.DoublyLinkedList.Node,
757756
758 fn contextPointer(closure: *DetachedClosure) [*]align(Fiber.max_context_align.toByteUnits()) u8 {757 fn contextPointer(closure: *DetachedClosure) [*]align(Fiber.max_context_align.toByteUnits()) u8 {
759 return @alignCast(@as([*]u8, @ptrCast(closure)) + @sizeOf(DetachedClosure));758 return @alignCast(@as([*]u8, @ptrCast(closure)) + @sizeOf(DetachedClosure));
...@@ -818,7 +817,7 @@ fn go(...@@ -818,7 +817,7 @@ fn go(
818 .event_loop = event_loop,817 .event_loop = event_loop,
819 .fiber = fiber,818 .fiber = fiber,
820 .start = start,819 .start = start,
821 .detached_queue_node = .{ .data = {} },820 .detached_queue_node = .{},
822 };821 };
823 {822 {
824 event_loop.detached.mutex.lock(event_loop.io()) catch |err| switch (err) {823 event_loop.detached.mutex.lock(event_loop.io()) catch |err| switch (err) {