package backend import ( "fmt" "get-container/cmd/hytop/lib" "math" "strconv" "strings" "sync" "time" ) var ( DCUSInfoMap *DCUInfoMap = nil // 记录dcu信息 Rocmlib = lib.Rocmlib_instance DriverVersion = "" ) const ( ENVUser = "USER" ) // Init 初始化本包的数据 func Init() error { Rocmlib = lib.GetRocmlib() _, err := Rocmlib.Init() if err != nil { return err } DriverVersion, err = Rocmlib.GetSystemDriverVersion() if err != nil { return err } _, err = Rocmlib.GetDevNumber() DCUSInfoMap = &DCUInfoMap{ info: make(map[int]*DCUInfo), lock: sync.RWMutex{}, } return err } func Shutdown() { Rocmlib.Shutdown() } type DCUInfoMap struct { lock sync.RWMutex info map[int]*DCUInfo } type DCUInfo struct { lock sync.RWMutex Id int Name string PerformanceLevel string Fan string Temp float32 // 单位是摄氏度 PwrAvg float32 // 单位是瓦 PwrCap float32 // 单位是瓦 BusId string MemTotal uint64 MemUsed uint64 MemUsedPerent float32 DCUUTil float32 } func (m *DCUInfoMap) UpdateInfo() error { num, err := Rocmlib.GetDevNumber() if err != nil { return err } names, err := Rocmlib.GetDevName() if err != nil { return err } plevel, err := Rocmlib.GetPerfLevel() if err != nil { return err } fan, err := Rocmlib.GetFanSpeed() if err != nil { return err } temp, err := Rocmlib.GetTemp() if err != nil { return err } pwrAvg, err := Rocmlib.GetPowerAvg() if err != nil { return err } pwrCap, err := Rocmlib.GetPowerCap() if err != nil { return err } busid, err := Rocmlib.GetPCIBusId() if err != nil { return err } memTotal, err := Rocmlib.GetMemTotal() if err != nil { return err } memUsed, err := Rocmlib.GetMemUsed() if err != nil { return err } dcu, err := Rocmlib.GetBusyPercent() if err != nil { return err } set := make(map[int]bool) m.lock.Lock() defer m.lock.Unlock() for i := range num { info, have := m.info[i] if !have { info = &DCUInfo{} m.info[i] = info } info.lock.Lock() info.Id = i info.Name = names[i] info.PerformanceLevel = plevel[i] if rpm, have := fan[i]; !have || rpm == 0 { info.Fan = "N/A" } else { info.Fan = strconv.Itoa(int(rpm)) } info.Temp = float32(temp[i]) / 1000 info.PwrAvg = float32(pwrAvg[i]) / 1000000 info.PwrCap = float32(pwrCap[i]) / 1000000 info.BusId = busid[i] info.MemTotal = memTotal[i] info.MemUsed = memUsed[i] if info.MemTotal == 0 { info.MemUsedPerent = 0 } else { info.MemUsedPerent = float32(info.MemUsed) / float32(info.MemTotal) * 100 } info.DCUUTil = float32(dcu[i]) info.lock.Unlock() set[i] = true } for k := range m.info { a, b := set[k] if a && b { continue } delete(m.info, k) } return nil } func (m *DCUInfoMap) GetInfo() (map[int]*DCUInfo, sync.Locker) { rl := m.lock.RLocker() rl.Lock() return m.info, rl } // DurationStr 将时间段格式化为 小时:分钟:秒 的格式 func DurationStr(d time.Duration) string { h := int(math.Floor(d.Hours())) m := int(d.Minutes()) % 60 s := int(math.Floor(d.Seconds())) % 60 if h <= 96 { return strings.Replace(fmt.Sprintf("%d:%2d:%2d", h, m, s), " ", "0", -1) } else { return fmt.Sprintf("%.1f days", d.Hours()/24) } }