| // +build windows |
| |
| package cpu |
| |
| import ( |
| "fmt" |
| "syscall" |
| "time" |
| "unsafe" |
| |
| "github.com/StackExchange/wmi" |
| |
| "github.com/shirou/gopsutil/internal/common" |
| ) |
| |
| type Win32_Processor struct { |
| LoadPercentage *uint16 |
| Family uint16 |
| Manufacturer string |
| Name string |
| NumberOfLogicalProcessors uint32 |
| ProcessorId *string |
| Stepping *string |
| MaxClockSpeed uint32 |
| } |
| |
| // TODO: Get percpu |
| func CPUTimes(percpu bool) ([]CPUTimesStat, error) { |
| var ret []CPUTimesStat |
| |
| var lpIdleTime common.FILETIME |
| var lpKernelTime common.FILETIME |
| var lpUserTime common.FILETIME |
| r, _, _ := common.ProcGetSystemTimes.Call( |
| uintptr(unsafe.Pointer(&lpIdleTime)), |
| uintptr(unsafe.Pointer(&lpKernelTime)), |
| uintptr(unsafe.Pointer(&lpUserTime))) |
| if r == 0 { |
| return ret, syscall.GetLastError() |
| } |
| |
| LOT := float64(0.0000001) |
| HIT := (LOT * 4294967296.0) |
| idle := ((HIT * float64(lpIdleTime.DwHighDateTime)) + (LOT * float64(lpIdleTime.DwLowDateTime))) |
| user := ((HIT * float64(lpUserTime.DwHighDateTime)) + (LOT * float64(lpUserTime.DwLowDateTime))) |
| kernel := ((HIT * float64(lpKernelTime.DwHighDateTime)) + (LOT * float64(lpKernelTime.DwLowDateTime))) |
| system := (kernel - idle) |
| |
| ret = append(ret, CPUTimesStat{ |
| Idle: float64(idle), |
| User: float64(user), |
| System: float64(system), |
| }) |
| return ret, nil |
| } |
| |
| func CPUInfo() ([]CPUInfoStat, error) { |
| var ret []CPUInfoStat |
| var dst []Win32_Processor |
| q := wmi.CreateQuery(&dst, "") |
| err := wmi.Query(q, &dst) |
| if err != nil { |
| return ret, err |
| } |
| |
| var procID string |
| for i, l := range dst { |
| procID = "" |
| if l.ProcessorId != nil { |
| procID = *l.ProcessorId |
| } |
| |
| cpu := CPUInfoStat{ |
| CPU: int32(i), |
| Family: fmt.Sprintf("%d", l.Family), |
| VendorID: l.Manufacturer, |
| ModelName: l.Name, |
| Cores: int32(l.NumberOfLogicalProcessors), |
| PhysicalID: procID, |
| Mhz: float64(l.MaxClockSpeed), |
| Flags: []string{}, |
| } |
| ret = append(ret, cpu) |
| } |
| |
| return ret, nil |
| } |
| |
| func CPUPercent(interval time.Duration, percpu bool) ([]float64, error) { |
| var ret []float64 |
| var dst []Win32_Processor |
| q := wmi.CreateQuery(&dst, "") |
| err := wmi.Query(q, &dst) |
| if err != nil { |
| return ret, err |
| } |
| for _, l := range dst { |
| // use range but windows can only get one percent. |
| if l.LoadPercentage == nil { |
| continue |
| } |
| ret = append(ret, float64(*l.LoadPercentage)) |
| } |
| return ret, nil |
| } |