#![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
use crate::types::*;
use std::mem::zeroed;
#[link(name = "kernel32")]
unsafe extern "system" {
fn GetCurrentThread() -> HANDLE;
fn GetCurrentProcess() -> HANDLE;
fn SetThreadPriority(hthread: HANDLE, npriority: i32) -> i32;
fn SetThreadAffinityMask(hthread: HANDLE, dwthreadaffinitymask: usize) -> usize;
fn SetThreadInformation(
hthread: HANDLE,
threadinformationclass: u32,
threadinformation: *const c_void,
threadinformationsize: u32,
) -> i32;
fn SetPriorityClass(hprocess: HANDLE, dwpriorityclass: u32) -> i32;
fn SetProcessInformation(
hprocess: HANDLE,
processinformationclass: u32,
processinformation: *const c_void,
processinformationsize: u32,
) -> i32;
fn GetSystemInfo(lpsysteminfo: *mut SYSTEM_INFO);
}
pub fn enable_eco_mode() {
unsafe {
let thread_handle = GetCurrentThread();
SetThreadPriority(thread_handle, THREAD_PRIORITY_IDLE);
let mut throttling_state: THREAD_POWER_THROTTLING_STATE = zeroed();
throttling_state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
throttling_state.ControlMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
throttling_state.StateMask = THREAD_POWER_THROTTLING_EXECUTION_SPEED;
let _ = SetThreadInformation(
thread_handle,
ThreadPowerThrottling,
&throttling_state as *const _ as *const _,
std::mem::size_of::<THREAD_POWER_THROTTLING_STATE>() as u32,
);
let mut sys_info: SYSTEM_INFO = zeroed();
GetSystemInfo(&mut sys_info);
let num_processors = sys_info.dwNumberOfProcessors as usize;
if num_processors > 4 {
let start_index = num_processors / 2;
let mut mask: usize = 0;
for i in start_index..num_processors {
if i < 64 {
mask |= 1 << i;
}
}
if mask != 0 {
SetThreadAffinityMask(thread_handle, mask);
}
}
}
}
pub fn set_process_eco_mode(enabled: bool) {
unsafe {
let process_handle = GetCurrentProcess();
if enabled {
SetPriorityClass(process_handle, IDLE_PRIORITY_CLASS);
let mut throttling_state: PROCESS_POWER_THROTTLING_STATE = zeroed();
throttling_state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
throttling_state.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
throttling_state.StateMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
let _ = SetProcessInformation(
process_handle,
ProcessPowerThrottling,
&throttling_state as *const _ as *const _,
std::mem::size_of::<PROCESS_POWER_THROTTLING_STATE>() as u32,
);
} else {
SetPriorityClass(process_handle, NORMAL_PRIORITY_CLASS);
let mut throttling_state: PROCESS_POWER_THROTTLING_STATE = zeroed();
throttling_state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
throttling_state.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
throttling_state.StateMask = 0;
let _ = SetProcessInformation(
process_handle,
ProcessPowerThrottling,
&throttling_state as *const _ as *const _,
std::mem::size_of::<PROCESS_POWER_THROTTLING_STATE>() as u32,
);
}
}
}