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

96 lines
2.4 KiB
Go
Raw Normal View History

2021-12-22 21:54:41 +00:00
//go:build windows
2014-04-18 21:28:00 +09:00
// +build windows
2014-12-30 22:09:05 +09:00
package load
2014-04-18 21:28:00 +09:00
import (
2017-12-31 15:25:49 +09:00
"context"
"log"
2020-11-09 10:00:22 +03:00
"math"
2020-10-22 17:13:43 +03:00
"sync"
"time"
2017-12-31 15:25:49 +09:00
"github.com/shirou/gopsutil/v3/internal/common"
)
2020-10-22 17:13:43 +03:00
var (
loadErr error
loadAvg1M float64 = 0.0
loadAvg5M float64 = 0.0
loadAvg15M float64 = 0.0
loadAvgMutex sync.RWMutex
loadAvgGoroutineOnce sync.Once
)
// loadAvgGoroutine updates avg data by fetching current load by interval
2020-11-06 11:07:02 +03:00
// TODO instead of this goroutine, we can register a Win32 counter just as psutil does
2020-10-22 17:13:43 +03:00
// see https://psutil.readthedocs.io/en/latest/#psutil.getloadavg
2020-11-06 11:07:02 +03:00
// code https://github.com/giampaolo/psutil/blob/8415355c8badc9c94418b19bdf26e622f06f0cce/psutil/arch/windows/wmi.c
func loadAvgGoroutine(ctx context.Context) {
2020-10-22 17:13:43 +03:00
var (
2020-11-09 10:00:22 +03:00
samplingFrequency time.Duration = 5 * time.Second
loadAvgFactor1M float64 = 1 / math.Exp(samplingFrequency.Seconds()/time.Minute.Seconds())
loadAvgFactor5M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(5*time.Minute).Seconds())
loadAvgFactor15M float64 = 1 / math.Exp(samplingFrequency.Seconds()/(15*time.Minute).Seconds())
currentLoad float64
2020-10-22 17:13:43 +03:00
)
counter, err := common.ProcessorQueueLengthCounter()
if err != nil || counter == nil {
log.Printf("unexpected processor queue length counter error, %v\n", err)
2020-10-22 17:13:43 +03:00
return
}
2020-11-09 10:00:22 +03:00
tick := time.NewTicker(samplingFrequency).C
f := func() {
2020-11-09 10:50:09 +03:00
currentLoad, err = counter.GetValue()
loadErr = err
loadAvgMutex.Lock()
2020-11-09 10:00:22 +03:00
loadAvg1M = loadAvg1M*loadAvgFactor1M + currentLoad*(1-loadAvgFactor1M)
loadAvg5M = loadAvg5M*loadAvgFactor5M + currentLoad*(1-loadAvgFactor5M)
loadAvg15M = loadAvg15M*loadAvgFactor15M + currentLoad*(1-loadAvgFactor15M)
2020-10-22 17:13:43 +03:00
loadAvgMutex.Unlock()
}
f() // run first time
for {
select {
case <-ctx.Done():
return
case <-tick:
f()
}
2020-10-22 17:13:43 +03:00
}
}
2020-11-09 10:37:31 +03:00
// Avg for Windows may return 0 values for the first few 5 second intervals
func Avg() (*AvgStat, error) {
2017-12-31 15:25:49 +09:00
return AvgWithContext(context.Background())
}
func AvgWithContext(ctx context.Context) (*AvgStat, error) {
loadAvgGoroutineOnce.Do(func() {
go loadAvgGoroutine(ctx)
})
2020-10-22 17:13:43 +03:00
loadAvgMutex.RLock()
defer loadAvgMutex.RUnlock()
ret := AvgStat{
Load1: loadAvg1M,
Load5: loadAvg5M,
Load15: loadAvg15M,
}
2014-04-18 21:28:00 +09:00
2020-10-22 17:13:43 +03:00
return &ret, loadErr
2014-04-18 21:28:00 +09:00
}
func Misc() (*MiscStat, error) {
2017-12-31 15:25:49 +09:00
return MiscWithContext(context.Background())
}
func MiscWithContext(ctx context.Context) (*MiscStat, error) {
ret := MiscStat{}
2016-04-01 21:34:39 +09:00
return &ret, common.ErrNotImplementedError
}