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