1
0
mirror of https://github.com/shirou/gopsutil.git synced 2025-04-26 13:48:59 +08:00

Merge pull request #706 from Lomanic/windows-process-nice

[process][windows] Use win32 API in process.Nice() instead of slow WMI call
This commit is contained in:
shirou 2019-07-06 11:20:58 +09:00 committed by GitHub
commit 14ba67b0ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -34,6 +34,7 @@ var (
procAdjustTokenPrivileges = advapi32.NewProc("AdjustTokenPrivileges")
procQueryFullProcessImageNameW = common.Modkernel32.NewProc("QueryFullProcessImageNameW")
procGetPriorityClass = common.Modkernel32.NewProc("GetPriorityClass")
)
type SystemProcessInformation struct {
@ -392,17 +393,39 @@ func (p *Process) TerminalWithContext(ctx context.Context) (string, error) {
return "", common.ErrNotImplementedError
}
// priorityClasses maps a win32 priority class to its WMI equivalent Win32_Process.Priority
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-getpriorityclass
// https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-process
var priorityClasses = map[int]int32{
0x00008000: 10, // ABOVE_NORMAL_PRIORITY_CLASS
0x00004000: 6, // BELOW_NORMAL_PRIORITY_CLASS
0x00000080: 13, // HIGH_PRIORITY_CLASS
0x00000040: 4, // IDLE_PRIORITY_CLASS
0x00000020: 8, // NORMAL_PRIORITY_CLASS
0x00000100: 24, // REALTIME_PRIORITY_CLASS
}
// Nice returns priority in Windows
func (p *Process) Nice() (int32, error) {
return p.NiceWithContext(context.Background())
}
func (p *Process) NiceWithContext(ctx context.Context) (int32, error) {
dst, err := GetWin32ProcWithContext(ctx, p.Pid)
// 0x1000 is PROCESS_QUERY_LIMITED_INFORMATION
c, err := syscall.OpenProcess(0x1000, false, uint32(p.Pid))
if err != nil {
return 0, fmt.Errorf("could not get Priority: %s", err)
return 0, err
}
return int32(dst[0].Priority), nil
defer syscall.CloseHandle(c)
ret, _, err := procGetPriorityClass.Call(uintptr(c))
if ret == 0 {
return 0, err
}
priority, ok := priorityClasses[int(ret)]
if !ok {
return 0, fmt.Errorf("unknown priority class %s", ret)
}
return priority, nil
}
func (p *Process) IOnice() (int32, error) {
return p.IOniceWithContext(context.Background())