| ... | @@ -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; |
| 1309 | | 1310 | |
| 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 to | 1312 | // 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 | } |
| 1347 | | 1348 | |
| ... | @@ -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 | }); |
| 1371 | | 1372 | |
| 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 | } |
| 1382 | | 1383 | |
| 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 other | 1407 | // 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"); |
| 1411 | | 1413 | |
| 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 have | 1416 | 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); |
| 1424 | | 1426 | 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 | } |
| 1434 | | 1442 | |