From 03a038cb8656ef70b86b215511d15bb8b956c207 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 29 Jun 2018 02:14:30 -0700 Subject: [PATCH] [vcpkg] Improve metrics performance on Windows --- toolsrc/include/vcpkg/base/system.h | 4 +++ toolsrc/src/vcpkg/base/checks.cpp | 12 ++++++-- toolsrc/src/vcpkg/base/system.cpp | 44 ++++++++++++++++++++++++----- toolsrc/src/vcpkg/metrics.cpp | 3 +- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h index 813d600cd3d..3c4326adebe 100644 --- a/toolsrc/include/vcpkg/base/system.h +++ b/toolsrc/include/vcpkg/base/system.h @@ -36,6 +36,10 @@ namespace vcpkg::System int cmd_execute(const CStringView cmd_line); +#if defined(_WIN32) + void cmd_execute_no_wait(const CStringView cmd_line); +#endif + ExitCodeAndOutput cmd_execute_and_capture_output(const CStringView cmd_line); enum class Color diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp index 2ac5f9a152d..72176e58ce2 100644 --- a/toolsrc/src/vcpkg/base/checks.cpp +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -14,12 +14,12 @@ namespace vcpkg::Checks if (have_entered) std::terminate(); have_entered = true; - const auto elapsed_us = GlobalState::timer.lock()->microseconds(); + const auto elapsed_us_inner = GlobalState::timer.lock()->microseconds(); - Debug::println("Exiting after %d us", static_cast(elapsed_us)); + bool debugging = GlobalState::debugging; auto metrics = Metrics::g_metrics.lock(); - metrics->track_metric("elapsed_us", elapsed_us); + metrics->track_metric("elapsed_us", elapsed_us_inner); GlobalState::debugging = false; metrics->flush(); @@ -28,6 +28,12 @@ namespace vcpkg::Checks SetConsoleOutputCP(GlobalState::g_init_console_output_cp); #endif + auto elapsed_us = GlobalState::timer.lock()->microseconds(); + if (debugging) + System::println("[DEBUG] Exiting after %d us (%d us)", + static_cast(elapsed_us), + static_cast(elapsed_us_inner)); + fflush(nullptr); #if defined(_WIN32) diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp index f59d31d7488..d968c6dac85 100644 --- a/toolsrc/src/vcpkg/base/system.cpp +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -129,10 +129,12 @@ namespace vcpkg::System R"("%s" %s -P "%s")", cmake_exe.u8string(), cmd_cmake_pass_variables, cmake_script.generic_u8string()); } - int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) - { - auto timer = Chrono::ElapsedTimer::create_started(); #if defined(_WIN32) + static void windows_create_clean_process(const CStringView cmd_line, + const std::unordered_map& extra_env, + PROCESS_INFORMATION& process_info, + DWORD dwCreationFlags) + { static const std::string SYSTEM_ROOT = get_environment_variable("SystemRoot").value_or_exit(VCPKG_LINE_INFO); static const std::string SYSTEM_32 = SYSTEM_ROOT + R"(\system32)"; std::string new_path = Strings::format( @@ -221,9 +223,6 @@ namespace vcpkg::System memset(&startup_info, 0, sizeof(STARTUPINFOW)); startup_info.cb = sizeof(STARTUPINFOW); - PROCESS_INFORMATION process_info; - memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - // Basically we are wrapping it in quotes const std::string actual_cmd_line = Strings::format(R"###(cmd.exe /c "%s")###", cmd_line); Debug::println("CreateProcessW(%s)", actual_cmd_line); @@ -232,13 +231,42 @@ namespace vcpkg::System nullptr, nullptr, FALSE, - IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + IDLE_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT | dwCreationFlags, env_cstr.data(), nullptr, &startup_info, &process_info); Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); + } +#endif + +#if defined(_WIN32) + void cmd_execute_no_wait(const CStringView cmd_line) + { + auto timer = Chrono::ElapsedTimer::create_started(); + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); + + windows_create_clean_process(cmd_line, {}, process_info, DETACHED_PROCESS); + + CloseHandle(process_info.hThread); + CloseHandle(process_info.hProcess); + + Debug::println("CreateProcessW() took %d us", static_cast(timer.microseconds())); + } +#endif + + int cmd_execute_clean(const CStringView cmd_line, const std::unordered_map& extra_env) + { + auto timer = Chrono::ElapsedTimer::create_started(); +#if defined(_WIN32) + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); + + windows_create_clean_process(cmd_line, extra_env, process_info, NULL); CloseHandle(process_info.hThread); @@ -248,6 +276,8 @@ namespace vcpkg::System DWORD exit_code = 0; GetExitCodeProcess(process_info.hProcess, &exit_code); + CloseHandle(process_info.hProcess); + Debug::println("CreateProcessW() returned %lu after %d us", exit_code, static_cast(timer.microseconds())); return static_cast(exit_code); #else diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp index 8890c067f3e..1d5bb381bdd 100644 --- a/toolsrc/src/vcpkg/metrics.cpp +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -437,13 +437,14 @@ namespace vcpkg::Metrics const std::string cmd_line = Strings::format("start \"vcpkgmetricsuploader.exe\" \"%s\" \"%s\"", temp_folder_path_exe.u8string(), vcpkg_metrics_txt_path.u8string()); + System::cmd_execute_no_wait(cmd_line); #else auto escaped_path = Strings::escape_string(vcpkg_metrics_txt_path.u8string(), '\'', '\\'); const std::string cmd_line = Strings::format( R"((curl "https://dc.services.visualstudio.com/v2/track" -H "Content-Type: application/json" -X POST --data '@%s' >/dev/null 2>&1; rm '%s') &)", escaped_path, escaped_path); -#endif System::cmd_execute_clean(cmd_line); +#endif } }