authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-11-24 14:33:59-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-11-24 14:34:18-08:00
log84353183c724298d2341b857bbd69975d315ec8a
tree53bdf6b9b6a3ecc13e15af5426d7e43266c2f779
parentece62a0223cfad5e49a5c75a944a21e735a01a05

build runner: fix recursive locking of max_rss_mutex


1 files changed, 31 insertions(+), 23 deletions(-)

lib/compiler/build_runner.zig+31-23
...@@ -1306,6 +1306,7 @@ fn workerMakeOneStep(...@@ -1306,6 +1306,7 @@ fn workerMakeOneStep(
1306 run: *Run,1306 run: *Run,
1307) void {1307) void {
1308 const io = b.graph.io;1308 const io = b.graph.io;
1309 const gpa = run.gpa;
13091310
1310 // First, check the conditions for running this step. If they are not met,1311 // First, check the conditions for running this step. If they are not met,
1311 // then we return without doing the step, relying on another worker to1312 // then we return without doing the step, relying on another worker to
...@@ -1341,7 +1342,7 @@ fn workerMakeOneStep(...@@ -1341,7 +1342,7 @@ fn workerMakeOneStep(
1341 if (new_claimed_rss > run.max_rss) {1342 if (new_claimed_rss > run.max_rss) {
1342 // Running this step right now could possibly exceed the allotted RSS.1343 // Running this step right now could possibly exceed the allotted RSS.
1343 // Add this step to the queue of memory-blocked steps.1344 // Add this step to the queue of memory-blocked steps.
1344 run.memory_blocked_steps.append(run.gpa, s) catch @panic("OOM");1345 run.memory_blocked_steps.append(gpa, s) catch @panic("OOM");
1345 return;1346 return;
1346 }1347 }
13471348
...@@ -1366,7 +1367,7 @@ fn workerMakeOneStep(...@@ -1366,7 +1367,7 @@ fn workerMakeOneStep(
1366 .web_server = if (run.web_server) |*ws| ws else null,1367 .web_server = if (run.web_server) |*ws| ws else null,
1367 .ttyconf = run.ttyconf,1368 .ttyconf = run.ttyconf,
1368 .unit_test_timeout_ns = run.unit_test_timeout_ns,1369 .unit_test_timeout_ns = run.unit_test_timeout_ns,
1369 .gpa = run.gpa,1370 .gpa = gpa,
1370 });1371 });
13711372
1372 // No matter the result, we want to display error/warning messages.1373 // No matter the result, we want to display error/warning messages.
...@@ -1377,7 +1378,7 @@ fn workerMakeOneStep(...@@ -1377,7 +1378,7 @@ fn workerMakeOneStep(
1377 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);1378 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
1378 defer std.debug.unlockStderrWriter();1379 defer std.debug.unlockStderrWriter();
1379 const ttyconf = run.ttyconf;1380 const ttyconf = run.ttyconf;
1380 printErrorMessages(run.gpa, s, .{}, bw, ttyconf, run.error_style, run.multiline_errors) catch {};1381 printErrorMessages(gpa, s, .{}, bw, ttyconf, run.error_style, run.multiline_errors) catch {};
1381 }1382 }
13821383
1383 handle_result: {1384 handle_result: {
...@@ -1406,29 +1407,36 @@ fn workerMakeOneStep(...@@ -1406,29 +1407,36 @@ fn workerMakeOneStep(
1406 // If this is a step that claims resources, we must now queue up other1407 // If this is a step that claims resources, we must now queue up other
1407 // steps that are waiting for resources.1408 // steps that are waiting for resources.
1408 if (s.max_rss != 0) {1409 if (s.max_rss != 0) {
1409 run.max_rss_mutex.lockUncancelable(io);1410 var dispatch_deps: std.ArrayList(*Step) = .empty;
1410 defer run.max_rss_mutex.unlock(io);1411 defer dispatch_deps.deinit(gpa);
1412 dispatch_deps.ensureUnusedCapacity(gpa, run.memory_blocked_steps.items.len) catch @panic("OOM");
14111413
1412 // Give the memory back to the scheduler.1414 {
1413 run.claimed_rss -= s.max_rss;1415 run.max_rss_mutex.lockUncancelable(io);
1414 // Avoid kicking off too many tasks that we already know will not have1416 defer run.max_rss_mutex.unlock(io);
1415 // enough resources.1417
1416 var remaining = run.max_rss - run.claimed_rss;1418 // Give the memory back to the scheduler.
1417 var i: usize = 0;1419 run.claimed_rss -= s.max_rss;
1418 var j: usize = 0;1420 // Avoid kicking off too many tasks that we already know will not have
1419 while (j < run.memory_blocked_steps.items.len) : (j += 1) {1421 // enough resources.
1420 const dep = run.memory_blocked_steps.items[j];1422 var remaining = run.max_rss - run.claimed_rss;
1421 assert(dep.max_rss != 0);1423 var i: usize = 0;
1422 if (dep.max_rss <= remaining) {1424 for (run.memory_blocked_steps.items) |dep| {
1423 remaining -= dep.max_rss;1425 assert(dep.max_rss != 0);
14241426 if (dep.max_rss <= remaining) {
1425 group.async(io, workerMakeOneStep, .{ group, b, dep, prog_node, run });1427 remaining -= dep.max_rss;
1426 } else {1428 dispatch_deps.appendAssumeCapacity(dep);
1427 run.memory_blocked_steps.items[i] = dep;1429 } else {
1428 i += 1;1430 run.memory_blocked_steps.items[i] = dep;
1431 i += 1;
1432 }
1429 }1433 }
1434 run.memory_blocked_steps.shrinkRetainingCapacity(i);
1435 }
1436 for (dispatch_deps.items) |dep| {
1437 // Must be called without max_rss_mutex held in case it executes recursively.
1438 group.async(io, workerMakeOneStep, .{ group, b, dep, prog_node, run });
1430 }1439 }
1431 run.memory_blocked_steps.shrinkRetainingCapacity(i);
1432 }1440 }
1433}1441}
14341442