| ... | @@ -915,14 +915,20 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -915,14 +915,20 @@ pub fn main(init: process.Init.Minimal) !void { |
| 915 | | 915 | |
| 916 | maker.watch = body.flags.watch; | 916 | maker.watch = body.flags.watch; |
| 917 | maker.prepare(steps, &configure_source_files) catch |err| switch (err) { | 917 | maker.prepare(steps, &configure_source_files) catch |err| switch (err) { |
| 918 | error.DependencyLoopDetected, error.InsufficientMemory => { | 918 | error.DependencyLoopDetected => { |
| 919 | // TODO handle DependencyLoopDetected as error.FailedButCacheIntact | 919 | // TODO handle error.FailedButCacheIntact |
| 920 | // and handle InsufficientMemory as error.AlreadyReported | | |
| 921 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; | 920 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| 922 | process.exit(1); | 921 | process.exit(1); |
| 923 | }, | 922 | }, |
| 924 | else => |e| return e, | 923 | else => |e| return e, |
| 925 | }; | 924 | }; |
| | 925 | maker.checkSufficientMemory() catch |err| switch (err) { |
| | 926 | error.InsufficientMemory => { |
| | 927 | // TODO handle as error.AlreadyReported |
| | 928 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| | 929 | process.exit(1); |
| | 930 | }, |
| | 931 | }; |
| 926 | | 932 | |
| 927 | try maker.makeSteps(main_progress_node, null); | 933 | try maker.makeSteps(main_progress_node, null); |
| 928 | | 934 | |
| ... | @@ -980,14 +986,20 @@ pub fn main(init: process.Init.Minimal) !void { | ... | @@ -980,14 +986,20 @@ pub fn main(init: process.Init.Minimal) !void { |
| 980 | defer gpa.free(initial_steps); | 986 | defer gpa.free(initial_steps); |
| 981 | | 987 | |
| 982 | maker.prepare(initial_steps, &configure_source_files) catch |err| switch (err) { | 988 | maker.prepare(initial_steps, &configure_source_files) catch |err| switch (err) { |
| 983 | error.DependencyLoopDetected, error.InsufficientMemory => { | 989 | error.DependencyLoopDetected => { |
| 984 | // TODO handle DependencyLoopDetected as error.FailedButCacheIntact | 990 | // TODO handle as error.FailedButCacheIntact |
| 985 | // and handle InsufficientMemory as error.AlreadyReported | | |
| 986 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; | 991 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| 987 | process.exit(1); | 992 | process.exit(1); |
| 988 | }, | 993 | }, |
| 989 | else => |e| return e, | 994 | else => |e| return e, |
| 990 | }; | 995 | }; |
| | 996 | maker.checkSufficientMemory() catch |err| switch (err) { |
| | 997 | error.InsufficientMemory => { |
| | 998 | // TODO handle as error.AlreadyReported |
| | 999 | _ = io.lockStderr(&.{}, graph.stderr_mode) catch {}; |
| | 1000 | process.exit(1); |
| | 1001 | }, |
| | 1002 | }; |
| 991 | | 1003 | |
| 992 | var w: Watch = w: { | 1004 | var w: Watch = w: { |
| 993 | if (!watch_flag) break :w undefined; | 1005 | if (!watch_flag) break :w undefined; |
| ... | @@ -2695,41 +2707,44 @@ fn prepare( | ... | @@ -2695,41 +2707,44 @@ fn prepare( |
| 2695 | for (starting_steps) |s| { | 2707 | for (starting_steps) |s| { |
| 2696 | try constructGraphAndCheckForDependencyLoop(maker, s, &maker.step_stack, rand); | 2708 | try constructGraphAndCheckForDependencyLoop(maker, s, &maker.step_stack, rand); |
| 2697 | } | 2709 | } |
| | 2710 | } |
| 2698 | | 2711 | |
| 2699 | { | 2712 | fn checkSufficientMemory(maker: *Maker) error{InsufficientMemory}!void { |
| 2700 | // Check that we have enough memory to complete the build. | 2713 | const step_stack = &maker.step_stack; |
| 2701 | var any_problems = false; | 2714 | const c = &maker.scanned_config.configuration; |
| 2702 | var max_needed: u64 = 0; | 2715 | |
| 2703 | for (step_stack.keys()) |step_index| { | 2716 | // Check that we have enough memory to complete the build. |
| 2704 | const make_step = maker.stepByIndex(step_index); | 2717 | var any_problems = false; |
| 2705 | const conf_step = step_index.ptr(c); | 2718 | var max_needed: u64 = 0; |
| 2706 | const max_rss = conf_step.max_rss.toBytes(); | 2719 | for (step_stack.keys()) |step_index| { |
| 2707 | if (max_rss == 0) continue; | 2720 | const make_step = maker.stepByIndex(step_index); |
| 2708 | max_needed = @max(max_needed, max_rss); | 2721 | const conf_step = step_index.ptr(c); |
| 2709 | if (max_rss > maker.available_rss) { | 2722 | const max_rss = conf_step.max_rss.toBytes(); |
| 2710 | if (maker.skip_oom_steps) { | 2723 | if (max_rss == 0) continue; |
| 2711 | make_step.state = .skipped_oom; | 2724 | max_needed = @max(max_needed, max_rss); |
| 2712 | for (make_step.dependants.items) |dependant| { | 2725 | if (max_rss > maker.available_rss) { |
| 2713 | maker.stepByIndex(dependant).pending_deps -= 1; | 2726 | if (maker.skip_oom_steps) { |
| 2714 | } | 2727 | make_step.state = .skipped_oom; |
| 2715 | } else { | 2728 | for (make_step.dependants.items) |dependant| { |
| 2716 | log.err("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory", .{ | 2729 | maker.stepByIndex(dependant).pending_deps -= 1; |
| 2717 | conf_step.owner.depPrefixSlice(c), | | |
| 2718 | conf_step.name.slice(c), | | |
| 2719 | max_rss, | | |
| 2720 | maker.available_rss, | | |
| 2721 | }); | | |
| 2722 | any_problems = true; | | |
| 2723 | } | 2730 | } |
| | 2731 | } else { |
| | 2732 | log.err("{s}{s}: this step declares an upper bound of {d} bytes of memory, exceeding the available {d} bytes of memory", .{ |
| | 2733 | conf_step.owner.depPrefixSlice(c), |
| | 2734 | conf_step.name.slice(c), |
| | 2735 | max_rss, |
| | 2736 | maker.available_rss, |
| | 2737 | }); |
| | 2738 | any_problems = true; |
| 2724 | } | 2739 | } |
| 2725 | } | 2740 | } |
| 2726 | if (any_problems) { | 2741 | } |
| 2727 | log.info("use --skip-oom-steps to proceed, skipping memory limited steps", .{}); | 2742 | if (any_problems) { |
| 2728 | if (maker.max_rss_is_default) { | 2743 | log.info("use --skip-oom-steps to proceed, skipping memory limited steps", .{}); |
| 2729 | log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{max_needed}); | 2744 | if (maker.max_rss_is_default) { |
| 2730 | } | 2745 | log.info("use --maxrss {d} to proceed, risking system memory exhaustion", .{max_needed}); |
| 2731 | return error.InsufficientMemory; | | |
| 2732 | } | 2746 | } |
| | 2747 | return error.InsufficientMemory; |
| 2733 | } | 2748 | } |
| 2734 | } | 2749 | } |
| 2735 | | 2750 | |