summaryrefslogtreecommitdiffstats
path: root/hal/windows/WindowsProcessPriority.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hal/windows/WindowsProcessPriority.cpp')
-rw-r--r--hal/windows/WindowsProcessPriority.cpp85
1 files changed, 85 insertions, 0 deletions
diff --git a/hal/windows/WindowsProcessPriority.cpp b/hal/windows/WindowsProcessPriority.cpp
new file mode 100644
index 0000000000..3f2153f569
--- /dev/null
+++ b/hal/windows/WindowsProcessPriority.cpp
@@ -0,0 +1,85 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// SetProcessInformation is only defined for Win8 and newer.
+#if defined(_WIN32_WINNT)
+# undef _WIN32_WINNT
+# define _WIN32_WINNT _WIN32_WINNT_WIN8
+#endif // defined(_WIN32_WINNT)
+
+#include "Hal.h"
+#include "HalLog.h"
+#include "nsWindowsHelpers.h" // for nsAutoHandle and nsModuleHandle
+#include "mozilla/StaticPrefs_dom.h"
+
+#include <windows.h>
+
+using namespace mozilla::hal;
+
+namespace mozilla {
+namespace hal_impl {
+
+void SetProcessPriority(int aPid, ProcessPriority aPriority) {
+ HAL_LOG("WindowsProcessPriority - SetProcessPriority(%d, %s)\n", aPid,
+ ProcessPriorityToString(aPriority));
+
+ nsAutoHandle processHandle(
+ ::OpenProcess(PROCESS_SET_INFORMATION, FALSE, aPid));
+ if (processHandle) {
+ DWORD priority = NORMAL_PRIORITY_CLASS;
+ if (aPriority == PROCESS_PRIORITY_BACKGROUND) {
+ priority = IDLE_PRIORITY_CLASS;
+ } else if (aPriority == PROCESS_PRIORITY_BACKGROUND_PERCEIVABLE) {
+ priority = BELOW_NORMAL_PRIORITY_CLASS;
+ }
+
+ if (::SetPriorityClass(processHandle, priority)) {
+ HAL_LOG("WindowsProcessPriority - priority set to %d for pid %d\n",
+ aPriority, aPid);
+ }
+
+ // Set the process into or out of EcoQoS.
+ static bool alreadyInitialized = false;
+ static decltype(::SetProcessInformation)* setProcessInformation = nullptr;
+ if (!alreadyInitialized) {
+ if (aPriority == PROCESS_PRIORITY_PARENT_PROCESS ||
+ !StaticPrefs::dom_ipc_processPriorityManager_backgroundUsesEcoQoS()) {
+ return;
+ }
+
+ alreadyInitialized = true;
+ // SetProcessInformation only exists on Windows 8 and later.
+ nsModuleHandle module(LoadLibrary(L"Kernel32.dll"));
+ if (module) {
+ setProcessInformation =
+ (decltype(::SetProcessInformation)*)GetProcAddress(
+ module, "SetProcessInformation");
+ }
+ }
+ if (!setProcessInformation) {
+ return;
+ }
+
+ PROCESS_POWER_THROTTLING_STATE PowerThrottling;
+ RtlZeroMemory(&PowerThrottling, sizeof(PowerThrottling));
+ PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
+ PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
+ PowerThrottling.StateMask =
+ (aPriority == PROCESS_PRIORITY_BACKGROUND) &&
+ StaticPrefs::
+ dom_ipc_processPriorityManager_backgroundUsesEcoQoS()
+ ? PROCESS_POWER_THROTTLING_EXECUTION_SPEED
+ : 0;
+ if (setProcessInformation(processHandle, ProcessPowerThrottling,
+ &PowerThrottling, sizeof(PowerThrottling))) {
+ HAL_LOG("SetProcessInformation(%d, %s)\n", aPid,
+ aPriority == PROCESS_PRIORITY_BACKGROUND ? "eco" : "normal");
+ } else {
+ HAL_LOG("SetProcessInformation failed for %d\n", aPid);
+ }
+ }
+}
+
+} // namespace hal_impl
+} // namespace mozilla