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(
13061306 run: *Run,
13071307) void {
13081308 const io = b.graph.io;
1309 const gpa = run.gpa;
13091310
13101311 // First, check the conditions for running this step. If they are not met,
13111312 // then we return without doing the step, relying on another worker to
......@@ -1341,7 +1342,7 @@ fn workerMakeOneStep(
13411342 if (new_claimed_rss > run.max_rss) {
13421343 // Running this step right now could possibly exceed the allotted RSS.
13431344 // 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");
13451346 return;
13461347 }
13471348
......@@ -1366,7 +1367,7 @@ fn workerMakeOneStep(
13661367 .web_server = if (run.web_server) |*ws| ws else null,
13671368 .ttyconf = run.ttyconf,
13681369 .unit_test_timeout_ns = run.unit_test_timeout_ns,
1369 .gpa = run.gpa,
1370 .gpa = gpa,
13701371 });
13711372
13721373 // No matter the result, we want to display error/warning messages.
......@@ -1377,7 +1378,7 @@ fn workerMakeOneStep(
13771378 const bw, _ = std.debug.lockStderrWriter(&stdio_buffer_allocation);
13781379 defer std.debug.unlockStderrWriter();
13791380 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 {};
13811382 }
13821383
13831384 handle_result: {
......@@ -1406,29 +1407,36 @@ fn workerMakeOneStep(
14061407 // If this is a step that claims resources, we must now queue up other
14071408 // steps that are waiting for resources.
14081409 if (s.max_rss != 0) {
1409 run.max_rss_mutex.lockUncancelable(io);
1410 defer run.max_rss_mutex.unlock(io);
1410 var dispatch_deps: std.ArrayList(*Step) = .empty;
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.
1413 run.claimed_rss -= s.max_rss;
1414 // Avoid kicking off too many tasks that we already know will not have
1415 // enough resources.
1416 var remaining = run.max_rss - run.claimed_rss;
1417 var i: usize = 0;
1418 var j: usize = 0;
1419 while (j < run.memory_blocked_steps.items.len) : (j += 1) {
1420 const dep = run.memory_blocked_steps.items[j];
1421 assert(dep.max_rss != 0);
1422 if (dep.max_rss <= remaining) {
1423 remaining -= dep.max_rss;
1424
1425 group.async(io, workerMakeOneStep, .{ group, b, dep, prog_node, run });
1426 } else {
1427 run.memory_blocked_steps.items[i] = dep;
1428 i += 1;
1414 {
1415 run.max_rss_mutex.lockUncancelable(io);
1416 defer run.max_rss_mutex.unlock(io);
1417
1418 // Give the memory back to the scheduler.
1419 run.claimed_rss -= s.max_rss;
1420 // Avoid kicking off too many tasks that we already know will not have
1421 // enough resources.
1422 var remaining = run.max_rss - run.claimed_rss;
1423 var i: usize = 0;
1424 for (run.memory_blocked_steps.items) |dep| {
1425 assert(dep.max_rss != 0);
1426 if (dep.max_rss <= remaining) {
1427 remaining -= dep.max_rss;
1428 dispatch_deps.appendAssumeCapacity(dep);
1429 } else {
1430 run.memory_blocked_steps.items[i] = dep;
1431 i += 1;
1432 }
14291433 }
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 });
14301439 }
1431 run.memory_blocked_steps.shrinkRetainingCapacity(i);
14321440 }
14331441}
14341442