diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index 9f6f3ec352..8f8fb6ba7b 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -546,6 +546,7 @@ namespace vcpkg inline constexpr StringLiteral EnvironmentVariableVcpkgForceSystemBinaries = "VCPKG_FORCE_SYSTEM_BINARIES"; inline constexpr StringLiteral EnvironmentVariableVcpkgKeepEnvVars = "VCPKG_KEEP_ENV_VARS"; inline constexpr StringLiteral EnvironmentVariableVcpkgMaxConcurrency = "VCPKG_MAX_CONCURRENCY"; + inline constexpr StringLiteral EnvironmentVariableVcpkgSubprocessPriority = "VCPKG_SUBPROCESS_PRIORITY"; inline constexpr StringLiteral EnvironmentVariableVcpkgNoCi = "VCPKG_NO_CI"; inline constexpr StringLiteral EnvironmentVariableVcpkgNuGetRepository = "VCPKG_NUGET_REPOSITORY"; inline constexpr StringLiteral EnvironmentVariableVcpkgOverlayPorts = "VCPKG_OVERLAY_PORTS"; diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 412500eb4b..0a4528f052 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -1147,6 +1147,11 @@ DECLARE_MESSAGE(EnvInvalidMaxConcurrency, (msg::env_var, msg::value), "{value} is the invalid value of an environment variable", "{env_var} is {value}, must be > 0") +DECLARE_MESSAGE(EnvInvalidPriority, + (msg::env_var, msg::value), + "'{value} is a user-supplied value for {env_var} environment variable.'", + "invalid value \"{value}\" for {env_var}." + "Valid values are '', 'IDLE', 'BELOW_NORMAL', 'NORMAL', 'ABOVE_NORMAL', 'HIGH' and 'REALTIME'") DECLARE_MESSAGE(EnvStrFailedToExtract, (), "", "could not expand the environment string:") DECLARE_MESSAGE(EnvPlatformNotSupported, (), "", "Build environment commands are not supported on this platform") DECLARE_MESSAGE(EnvVarMustBeAbsolutePath, (msg::path, msg::env_var), "", "{env_var} ({path}) was not an absolute path") diff --git a/include/vcpkg/base/system.h b/include/vcpkg/base/system.h index aaa4ec8b04..8b1d941727 100644 --- a/include/vcpkg/base/system.h +++ b/include/vcpkg/base/system.h @@ -63,6 +63,10 @@ namespace vcpkg unsigned int get_concurrency(); +#if defined(_WIN32) + DWORD get_subprocess_priority(); +#endif + Optional guess_visual_studio_prompt_target_architecture(); } diff --git a/locales/messages.json b/locales/messages.json index c6aa16f284..2666f4e2b0 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -676,6 +676,8 @@ "EndOfStringInCodeUnit": "found end of string in middle of code point", "EnvInvalidMaxConcurrency": "{env_var} is {value}, must be > 0", "_EnvInvalidMaxConcurrency.comment": "{value} is the invalid value of an environment variable An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", + "EnvInvalidPriority": "invalid value \"{value}\" for {env_var}.Valid values are '', 'IDLE', 'BELOW_NORMAL', 'NORMAL', 'ABOVE_NORMAL', 'HIGH' and 'REALTIME'", + "_EnvInvalidPriority.comment": "'{value} is a user-supplied value for {env_var} environment variable.' An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", "EnvPlatformNotSupported": "Build environment commands are not supported on this platform", "EnvStrFailedToExtract": "could not expand the environment string:", "EnvVarMustBeAbsolutePath": "{env_var} ({path}) was not an absolute path", diff --git a/src/vcpkg/base/system.cpp b/src/vcpkg/base/system.cpp index 7592d18ed0..d5a5c70bad 100644 --- a/src/vcpkg/base/system.cpp +++ b/src/vcpkg/base/system.cpp @@ -733,6 +733,53 @@ namespace vcpkg return concurrency; } +#if defined(_WIN32) + DWORD get_subprocess_priority() + { + static const DWORD priority = []() { + const auto opt_user_defined_priority = get_environment_variable(EnvironmentVariableVcpkgSubprocessPriority); + if (!opt_user_defined_priority.has_value()) + { + return IDLE_PRIORITY_CLASS; + } + const auto user_defined_priority = opt_user_defined_priority.value_or_exit(VCPKG_LINE_INFO); + if (user_defined_priority.empty() || Strings::case_insensitive_ascii_equals(user_defined_priority, "idle")) + { + return IDLE_PRIORITY_CLASS; + } + else if (Strings::case_insensitive_ascii_equals(user_defined_priority, "below_normal")) + { + return BELOW_NORMAL_PRIORITY_CLASS; + } + else if (Strings::case_insensitive_ascii_equals(user_defined_priority, "normal")) + { + return NORMAL_PRIORITY_CLASS; + } + else if (Strings::case_insensitive_ascii_equals(user_defined_priority, "above_normal")) + { + return ABOVE_NORMAL_PRIORITY_CLASS; + } + else if (Strings::case_insensitive_ascii_equals(user_defined_priority, "high")) + { + return HIGH_PRIORITY_CLASS; + } + else if (Strings::case_insensitive_ascii_equals(user_defined_priority, "realtime")) + { + return REALTIME_PRIORITY_CLASS; + } + else + { + Checks::msg_exit_with_message(VCPKG_LINE_INFO, + msgEnvInvalidPriority, + msg::env_var = EnvironmentVariableVcpkgSubprocessPriority, + msg::value = user_defined_priority); + } + return IDLE_PRIORITY_CLASS; + }(); + return priority; + } +#endif + Optional guess_visual_studio_prompt_target_architecture() { // Check for the "vsdevcmd" infrastructure used by Visual Studio 2017 and later diff --git a/src/vcpkg/base/system.process.cpp b/src/vcpkg/base/system.process.cpp index 799542c8e8..c3fbaddc1c 100644 --- a/src/vcpkg/base/system.process.cpp +++ b/src/vcpkg/base/system.process.cpp @@ -818,6 +818,8 @@ namespace call_environment = environment_block.data(); } + DWORD dwPriority = get_subprocess_priority(); + // Leaking process information handle 'process_info.proc_info.hProcess' // /analyze can't tell that we transferred ownership here VCPKG_MSVC_WARNING(suppress : 6335) @@ -826,8 +828,7 @@ namespace nullptr, nullptr, bInheritHandles, - IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | - dwCreationFlags, + dwPriority | CREATE_UNICODE_ENVIRONMENT | EXTENDED_STARTUPINFO_PRESENT | dwCreationFlags, call_environment, working_directory_arg, &startup_info.StartupInfo,