Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
liming6
dcu-process-montor
Commits
3e5adb86
Commit
3e5adb86
authored
Nov 25, 2025
by
liming6
Browse files
feature 添加进程选择功能
parent
c915d1bd
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
381 additions
and
83 deletions
+381
-83
cmd/hytop/backend/dcu.go
cmd/hytop/backend/dcu.go
+11
-1
cmd/hytop/main.go
cmd/hytop/main.go
+1
-1
cmd/hytop/tui/dcuinfo.go
cmd/hytop/tui/dcuinfo.go
+130
-51
cmd/hytop/tui/main.go
cmd/hytop/tui/main.go
+160
-0
cmd/hytop/tui/process.go
cmd/hytop/tui/process.go
+57
-25
cmd/hytop/tui/sysload.go
cmd/hytop/tui/sysload.go
+10
-4
cmd/hytop/tui/timechart.go
cmd/hytop/tui/timechart.go
+12
-0
gpu/hy-smi.go
gpu/hy-smi.go
+0
-1
No files found.
cmd/hytop/backend/dcu.go
View file @
3e5adb86
...
...
@@ -8,6 +8,7 @@ import (
"get-container/utils"
"math"
"os"
"sort"
"strconv"
"strings"
"sync"
...
...
@@ -364,7 +365,8 @@ func (m *DCUInfoMap) GetDCUProcessInfo2() map[int][]DCUProcessInfo {
pids
=
append
(
pids
,
int32
(
v
.
Pid
))
}
pinfo
:=
getProcessInfo
(
pids
)
for
_
,
v
:=
range
info
{
for
_
,
v
:=
range
info
{
// 按照进程遍历
// 获取进程使用的所有dcu的索引
index
:=
make
([]
int
,
0
)
for
_
,
i
:=
range
v
.
HCUIndex
{
ii
,
err
:=
strconv
.
Atoi
(
i
)
...
...
@@ -384,9 +386,17 @@ func (m *DCUInfoMap) GetDCUProcessInfo2() map[int][]DCUProcessInfo {
item
.
DCUMem
=
v
.
VRamUsed
.
HumanReadStr
(
1
)
item
.
SDMA
=
v
.
SDMAUsed
l
=
append
(
l
,
item
)
result
[
i
]
=
l
}
}
// 每个切片对pid排序
for
k
,
v
:=
range
result
{
sort
.
SliceStable
(
v
,
func
(
i
,
j
int
)
bool
{
return
v
[
i
]
.
Info
.
Pid
<
v
[
j
]
.
Info
.
Pid
})
result
[
k
]
=
v
}
return
result
}
...
...
cmd/hytop/main.go
View file @
3e5adb86
...
...
@@ -21,7 +21,7 @@ func main() {
log
.
Fatalf
(
"error init data backend: %v"
,
err
)
}
model
:=
tui
.
NewModelMain
(
w
,
h
)
if
_
,
err
:=
tea
.
NewProgram
(
&
model
)
.
Run
();
err
!=
nil
{
if
_
,
err
:=
tea
.
NewProgram
(
&
model
,
tea
.
WithAltScreen
()
)
.
Run
();
err
!=
nil
{
log
.
Fatalf
(
"error create program; %v"
,
err
)
}
backend
.
Shutdown
()
...
...
cmd/hytop/tui/dcuinfo.go
View file @
3e5adb86
...
...
@@ -10,14 +10,18 @@ import (
"github.com/charmbracelet/bubbles/progress"
tea
"github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/lucasb-eyer/go-colorful"
"github.com/muesli/gamut"
"github.com/muesli/termenv"
)
type
ModelDCUInfo
struct
{
pro
progress
.
Model
// 进度条
proLowLeight
progress
.
Model
// 低亮度进度条
proWidth
int
// 进度条宽度
modMsg
*
ModelMsg
width
,
height
int
actionMsg
*
ActionMsg
}
const
(
...
...
@@ -46,7 +50,10 @@ func (m *ModelDCUInfo) Init() tea.Cmd {
if
m
.
width
>
StaticWidth
+
ProgressMinWidth
+
OtherWidth
{
m
.
proWidth
=
m
.
width
-
OtherWidth
-
StaticWidth
}
m
.
pro
=
progress
.
New
(
progress
.
WithColorProfile
(
termenv
.
TrueColor
),
progress
.
WithGradient
(
"#0000ffff"
,
"#ff0000ff"
),
progress
.
WithWidth
(
m
.
proWidth
))
m
.
pro
=
progress
.
New
(
progress
.
WithColorProfile
(
termenv
.
TrueColor
),
progress
.
WithGradient
(
"#0000ffff"
,
"#ff0000ff"
),
progress
.
WithWidth
(
m
.
proWidth
-
5
),
progress
.
WithoutPercentage
())
c1
,
_
:=
colorful
.
MakeColor
(
gamut
.
Darker
(
lipgloss
.
Color
(
"#0000ffff"
),
0.8
))
c2
,
_
:=
colorful
.
MakeColor
(
gamut
.
Darker
(
lipgloss
.
Color
(
"#ff0000ff"
),
0.8
))
m
.
proLowLeight
=
progress
.
New
(
progress
.
WithColorProfile
(
termenv
.
TrueColor
),
progress
.
WithGradient
(
c1
.
Hex
(),
c2
.
Hex
()),
progress
.
WithWidth
(
m
.
proWidth
-
5
),
progress
.
WithoutPercentage
())
return
nil
}
...
...
@@ -59,6 +66,9 @@ func (m *ModelDCUInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
m
.
height
=
msg
.
Height
m
.
width
=
msg
.
Width
return
m
,
nil
case
*
ActionMsg
:
m
.
actionMsg
=
msg
return
m
,
nil
}
return
m
,
nil
}
...
...
@@ -72,77 +82,146 @@ func (m *ModelDCUInfo) View() string {
smap
,
slock
:=
m
.
modMsg
.
DCUInfo
.
GetSlowInfo
()
defer
slock
.
Unlock
()
defer
qlock
.
Unlock
()
conTime
:=
0
strBuilder
:=
strings
.
Builder
{}
strCache
:=
strings
.
Builder
{}
var
targetDCU
int
=
-
1
if
m
.
actionMsg
!=
nil
&&
m
.
actionMsg
.
TargetDCUIndex
!=
nil
{
targetDCU
=
*
m
.
actionMsg
.
TargetDCUIndex
}
infos
:=
make
([]
string
,
0
)
for
i
:=
range
128
{
for
i
:=
range
64
{
qinfo
,
haveq
:=
qmap
[
i
]
sinfo
,
haves
:=
smap
[
i
]
if
!
(
haveq
||
haves
)
{
conTime
++
if
conTime
>
8
{
break
}
continue
}
isLowStyle
:=
(
targetDCU
!=
qinfo
.
Id
&&
targetDCU
!=
-
1
)
strBuilder
.
WriteString
(
myBorder
.
Left
)
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
strconv
.
Itoa
(
qinfo
.
Id
),
4
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
ReDCUName
.
FindString
(
qinfo
.
Name
),
8
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
qinfo
.
PerformanceLevel
,
15
,
lipgloss
.
Right
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
myBorder
.
Left
)
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
qinfo
.
BusId
,
13
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
"Off"
,
6
,
lipgloss
.
Right
))
strBuilder
.
WriteByte
(
' '
)
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
strconv
.
Itoa
(
qinfo
.
Id
),
4
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
ReDCUName
.
FindString
(
qinfo
.
Name
),
8
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
qinfo
.
PerformanceLevel
,
15
,
lipgloss
.
Right
))
strCache
.
WriteByte
(
' '
)
if
isLowStyle
{
str
:=
strCache
.
String
()
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
str
))
}
else
{
strBuilder
.
WriteString
(
strCache
.
String
())
}
strCache
.
Reset
()
strBuilder
.
WriteString
(
myBorder
.
Left
)
strBuilder
.
WriteByte
(
' '
)
if
sinfo
.
Mig
.
Load
()
{
strBuilder
.
WriteString
(
FormatStr
(
"On"
,
16
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
qinfo
.
BusId
,
13
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
"Off"
,
6
,
lipgloss
.
Right
))
strCache
.
WriteByte
(
' '
)
if
isLowStyle
{
str
:=
strCache
.
String
()
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
str
))
}
else
{
strBuilder
.
WriteString
(
FormatStr
(
"Off"
,
16
,
lipgloss
.
Left
))
strBuilder
.
WriteString
(
strCache
.
String
(
))
}
strBuilder
.
WriteByte
(
' '
)
strCache
.
Reset
()
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
"Off"
,
16
,
lipgloss
.
Left
))
strBuilder
.
WriteString
(
myBorder
.
Left
)
strCache
.
WriteByte
(
' '
)
if
sinfo
.
Ecc
.
Load
()
{
str
Builder
.
WriteString
(
FormatStr
(
"On"
,
3
,
lipgloss
.
Right
))
str
Cache
.
WriteString
(
FormatStr
(
"On"
,
3
,
lipgloss
.
Right
))
}
else
{
str
Builder
.
WriteString
(
FormatStr
(
"Off"
,
3
,
lipgloss
.
Right
))
str
Cache
.
WriteString
(
FormatStr
(
"Off"
,
3
,
lipgloss
.
Right
))
}
strBuilder
.
WriteByte
(
' '
)
strCache
.
WriteByte
(
' '
)
if
isLowStyle
{
str
:=
strCache
.
String
()
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
str
))
}
else
{
strBuilder
.
WriteString
(
strCache
.
String
())
}
strCache
.
Reset
()
strBuilder
.
WriteString
(
myBorder
.
Left
)
if
isLowStyle
{
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
" DCU: "
))
strBuilder
.
WriteString
(
m
.
proLowLeight
.
ViewAs
(
float64
(
qinfo
.
DCUUTil
/
100
)))
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
fmt
.
Sprintf
(
" %3d%% "
,
int
(
qinfo
.
DCUUTil
))))
}
else
{
strBuilder
.
WriteString
(
" DCU: "
)
strBuilder
.
WriteString
(
m
.
pro
.
ViewAs
(
float64
(
qinfo
.
DCUUTil
/
100
)))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
fmt
.
Sprintf
(
" %3d%% "
,
int
(
qinfo
.
DCUUTil
)))
}
strBuilder
.
WriteString
(
myBorder
.
Left
)
strBuilder
.
WriteByte
(
'\n'
)
strBuilder
.
WriteString
(
myBorder
.
Left
)
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
qinfo
.
Fan
,
4
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1fC"
,
qinfo
.
Temp
),
6
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
// 18
strBuilder
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1fW / %.1fW"
,
qinfo
.
PwrAvg
,
qinfo
.
PwrCap
),
17
,
lipgloss
.
Right
))
strBuilder
.
WriteByte
(
' '
)
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
qinfo
.
Fan
,
4
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1fC"
,
qinfo
.
Temp
),
6
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1fW / %.1fW"
,
qinfo
.
PwrAvg
,
qinfo
.
PwrCap
),
17
,
lipgloss
.
Right
))
strCache
.
WriteByte
(
' '
)
if
isLowStyle
{
str
:=
strCache
.
String
()
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
str
))
}
else
{
strBuilder
.
WriteString
(
strCache
.
String
())
}
strCache
.
Reset
()
strBuilder
.
WriteString
(
myBorder
.
Left
)
if
isLowStyle
{
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%dMiB / %dMiB"
,
qinfo
.
MemUsed
/
uint64
(
utils
.
MiB
),
qinfo
.
MemTotal
/
uint64
(
utils
.
MiB
)),
20
,
lipgloss
.
Right
))
strCache
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
strCache
.
String
()))
strCache
.
Reset
()
}
else
{
strBuilder
.
WriteByte
(
' '
)
// 20
strBuilder
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%dMiB / %dMiB"
,
qinfo
.
MemUsed
/
uint64
(
utils
.
MiB
),
qinfo
.
MemTotal
/
uint64
(
utils
.
MiB
)),
20
,
lipgloss
.
Right
))
strBuilder
.
WriteByte
(
' '
)
}
strBuilder
.
WriteString
(
myBorder
.
Left
)
if
isLowStyle
{
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f%%"
,
qinfo
.
DCUUTil
),
6
,
lipgloss
.
Left
))
strCache
.
WriteByte
(
' '
)
strCache
.
WriteString
(
FormatStr
(
sinfo
.
PwrMode
.
Load
()
.
(
string
),
13
,
lipgloss
.
Right
))
strCache
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
strCache
.
String
()))
strCache
.
Reset
()
}
else
{
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f%%"
,
qinfo
.
DCUUTil
),
6
,
lipgloss
.
Left
))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
FormatStr
(
sinfo
.
PwrMode
.
Load
()
.
(
string
),
13
,
lipgloss
.
Right
))
strBuilder
.
WriteByte
(
' '
)
}
strBuilder
.
WriteString
(
myBorder
.
Left
)
if
isLowStyle
{
strCache
.
WriteString
(
" Mem: "
)
strCache
.
WriteString
(
m
.
proLowLeight
.
ViewAs
(
float64
(
qinfo
.
MemUsed
)
/
float64
(
qinfo
.
MemTotal
)))
strCache
.
WriteString
(
LowLeightStyle
.
Render
(
fmt
.
Sprintf
(
" %3d%% "
,
int
(
100
*
float64
(
qinfo
.
MemUsed
)
/
float64
(
qinfo
.
MemTotal
)))))
strBuilder
.
WriteString
(
LowLeightStyle
.
Render
(
strCache
.
String
()))
strCache
.
Reset
()
}
else
{
strBuilder
.
WriteString
(
" Mem: "
)
strBuilder
.
WriteString
(
m
.
pro
.
ViewAs
(
float64
(
qinfo
.
MemUsed
)
/
float64
(
qinfo
.
MemTotal
)))
strBuilder
.
WriteByte
(
' '
)
strBuilder
.
WriteString
(
fmt
.
Sprintf
(
"%3d%%"
,
int
(
100
*
float64
(
qinfo
.
MemUsed
)
/
float64
(
qinfo
.
MemTotal
))))
strBuilder
.
WriteByte
(
' '
)
}
strBuilder
.
WriteString
(
myBorder
.
Left
)
infos
=
append
(
infos
,
strBuilder
.
String
())
strBuilder
.
Reset
()
...
...
cmd/hytop/tui/main.go
View file @
3e5adb86
...
...
@@ -4,6 +4,7 @@ import (
"get-container/cmd/hytop/backend"
"get-container/gpu"
"get-container/utils"
"syscall"
"time"
tea
"github.com/charmbracelet/bubbletea"
...
...
@@ -14,6 +15,15 @@ const (
DCUTopVersion
=
"1.0.0"
)
var
(
HeightLightStyle
=
lipgloss
.
NewStyle
()
.
Background
(
lipgloss
.
Color
(
"#00fffb7a"
))
// 高亮风格
SelectedStyle
=
lipgloss
.
NewStyle
()
.
Foreground
(
lipgloss
.
Color
(
"#ffb81fe3"
))
// 被选中的风格
HeightSelectedStyle
=
lipgloss
.
NewStyle
()
.
Background
(
lipgloss
.
Color
(
"#ffb81fe3"
))
// 既被选中,又高亮的风格
LowLeightStyle
=
lipgloss
.
NewStyle
()
.
Foreground
(
lipgloss
.
Color
(
"#442d2d"
))
NormalStyle
=
lipgloss
.
NewStyle
()
.
Foreground
(
lipgloss
.
Color
(
"#e6e6e6eb"
))
)
// ModelMsg 模型信息,在父组件和各个子组件间共享信息
type
ModelMsg
struct
{
t
time
.
Time
// 当前时间
...
...
@@ -26,6 +36,17 @@ type ModelMsg struct {
type
TickMsg
time
.
Time
// ActionMsg 动作消息
type
ActionMsg
struct
{
SelectPids
map
[
int32
]
bool
// 选择的pid进程
Action
*
syscall
.
Signal
// 对选择的pid的动作
PidView
*
int32
// 进程视图指标的pid号,为null表示没有进入进程指标视图
PointPid
*
int32
// 指针指向的pid,为null表示没有选择进程
PidEnvView
*
int32
// 进程环境变量视图的pid号,为null表示不进入进程环境变量视图
PidTreeView
*
int32
// 进入pstree视图的pid号,为null表示不进入pstree视图
TargetDCUIndex
*
int
// PointPid使用的dcu index
}
// ModelMain tui主模型类
type
ModelMain
struct
{
width
,
height
int
// 终端尺寸
...
...
@@ -34,6 +55,7 @@ type ModelMain struct {
SysLoad
*
ModelSysLoad
ProcessInfo
*
ModelProcessInfo
modelMsg
*
ModelMsg
actionMsg
*
ActionMsg
}
func
NewModelMain
(
width
,
height
int
)
ModelMain
{
...
...
@@ -44,6 +66,7 @@ func NewModelMain(width, height int) ModelMain {
result
.
DCUInfo
=
NewModelDCUInfo
(
width
,
height
)
result
.
SysLoad
=
NewModelSysLoad
(
width
)
result
.
ProcessInfo
=
NewModelProcessInfo
(
width
)
result
.
actionMsg
=
&
ActionMsg
{}
return
result
}
...
...
@@ -90,6 +113,24 @@ func (m *ModelMain) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
switch
msg
.
String
()
{
case
"ctrl+c"
,
"q"
:
return
m
,
tea
.
Quit
case
"up"
:
cmd
:=
m
.
handleKeyUp
()
return
m
,
cmd
case
"down"
:
cmd
:=
m
.
handleKeyDown
()
return
m
,
cmd
case
"enter"
:
return
m
,
tea
.
Quit
case
"h"
:
return
m
,
tea
.
Quit
case
"k"
:
return
m
,
tea
.
Quit
case
"esc"
:
cmd
:=
m
.
handleKeyEsc
()
return
m
,
cmd
case
" "
:
cmd
:=
m
.
handleKeySpace
()
return
m
,
cmd
}
case
TickMsg
:
// 定时事件
updateModelInfo
(
m
.
modelMsg
,
time
.
Time
(
msg
))
...
...
@@ -127,6 +168,28 @@ func (m *ModelMain) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
return
m
,
nil
}
func
(
m
*
ModelMain
)
handleKeyEsc
()
tea
.
Cmd
{
return
nil
}
func
(
m
*
ModelMain
)
handleKeySpace
()
tea
.
Cmd
{
if
m
.
actionMsg
==
nil
||
m
.
actionMsg
.
PointPid
==
nil
{
return
nil
}
if
m
.
actionMsg
.
SelectPids
==
nil
{
m
.
actionMsg
.
SelectPids
=
make
(
map
[
int32
]
bool
)
}
_
,
have
:=
m
.
actionMsg
.
SelectPids
[
*
m
.
actionMsg
.
PointPid
]
if
have
{
delete
(
m
.
actionMsg
.
SelectPids
,
*
m
.
actionMsg
.
PointPid
)
}
else
{
m
.
actionMsg
.
SelectPids
[
*
m
.
actionMsg
.
PointPid
]
=
true
}
m1
,
cmd1
:=
m
.
ProcessInfo
.
Update
(
m
.
actionMsg
)
m
.
ProcessInfo
=
m1
.
(
*
ModelProcessInfo
)
return
cmd1
}
func
(
m
*
ModelMain
)
View
()
string
{
return
m
.
Header
.
View
()
+
m
.
DCUInfo
.
View
()
+
m
.
SysLoad
.
View
()
+
m
.
ProcessInfo
.
View
()
+
"
\n
"
}
...
...
@@ -185,3 +248,100 @@ func updateModelInfo(modelMsg *ModelMsg, t time.Time) error {
}
return
nil
}
func
(
m
*
ModelMain
)
handleKeyUp
()
tea
.
Cmd
{
if
m
.
actionMsg
==
nil
{
m
.
actionMsg
=
&
ActionMsg
{}
}
if
m
.
modelMsg
.
DCUPidInfo
==
nil
{
return
nil
}
processes
:=
make
([]
backend
.
DCUProcessInfo
,
0
)
for
index
:=
range
64
{
p
,
have
:=
m
.
modelMsg
.
DCUPidInfo
[
index
]
if
have
&&
len
(
p
)
>
0
{
processes
=
append
(
processes
,
p
...
)
}
}
processNum
:=
len
(
processes
)
if
processNum
==
0
{
return
nil
}
index
:=
0
if
m
.
actionMsg
.
PointPid
==
nil
{
// 获取列表中的最后一个进程的pid
index
=
processNum
-
1
}
else
{
var
targetIndex
=
-
1
for
l
:=
processNum
-
1
;
l
>=
0
;
l
--
{
if
processes
[
l
]
.
Info
.
Pid
==
*
m
.
actionMsg
.
PointPid
{
targetIndex
=
l
-
1
break
}
}
if
targetIndex
==
-
1
{
index
=
processNum
-
1
}
else
{
index
=
targetIndex
}
}
pid
:=
processes
[
index
]
.
Info
.
Pid
m
.
actionMsg
.
PointPid
=
&
pid
idx
:=
processes
[
index
]
.
DCU
m
.
actionMsg
.
TargetDCUIndex
=
&
idx
m1
,
cmd1
:=
m
.
ProcessInfo
.
Update
(
m
.
actionMsg
)
m2
,
cmd2
:=
m
.
DCUInfo
.
Update
(
m
.
actionMsg
)
m
.
ProcessInfo
=
m1
.
(
*
ModelProcessInfo
)
m
.
DCUInfo
=
m2
.
(
*
ModelDCUInfo
)
return
tea
.
Batch
(
cmd1
,
cmd2
)
}
func
(
m
*
ModelMain
)
handleKeyDown
()
tea
.
Cmd
{
if
m
.
actionMsg
==
nil
{
m
.
actionMsg
=
&
ActionMsg
{}
}
if
m
.
modelMsg
.
DCUPidInfo
==
nil
{
return
nil
}
processes
:=
make
([]
backend
.
DCUProcessInfo
,
0
)
for
index
:=
range
64
{
p
,
have
:=
m
.
modelMsg
.
DCUPidInfo
[
index
]
if
have
&&
len
(
p
)
>
0
{
processes
=
append
(
processes
,
p
...
)
}
}
processNum
:=
len
(
processes
)
if
processNum
==
0
{
return
nil
}
index
:=
0
if
m
.
actionMsg
.
PointPid
==
nil
{
index
=
0
}
else
{
var
targetIndex
=
-
1
for
l
:=
0
;
l
<
processNum
-
1
;
l
++
{
if
processes
[
l
]
.
Info
.
Pid
==
*
m
.
actionMsg
.
PointPid
{
targetIndex
=
l
+
1
if
targetIndex
>=
processNum
{
targetIndex
=
0
}
break
}
}
if
targetIndex
==
-
1
{
index
=
0
}
else
{
index
=
targetIndex
}
}
pid
:=
processes
[
index
]
.
Info
.
Pid
m
.
actionMsg
.
PointPid
=
&
pid
idx
:=
processes
[
index
]
.
DCU
m
.
actionMsg
.
TargetDCUIndex
=
&
idx
m1
,
cmd1
:=
m
.
ProcessInfo
.
Update
(
m
.
actionMsg
)
m2
,
cmd2
:=
m
.
DCUInfo
.
Update
(
m
.
actionMsg
)
m
.
ProcessInfo
=
m1
.
(
*
ModelProcessInfo
)
m
.
DCUInfo
=
m2
.
(
*
ModelDCUInfo
)
return
tea
.
Batch
(
cmd1
,
cmd2
)
}
cmd/hytop/tui/process.go
View file @
3e5adb86
...
...
@@ -20,6 +20,7 @@ type ModelProcessInfo struct {
width
int
style
lipgloss
.
Style
modMsg
*
ModelMsg
actionMsg
*
ActionMsg
}
const
(
...
...
@@ -61,8 +62,13 @@ func (m *ModelProcessInfo) Init() tea.Cmd {
func
(
m
*
ModelProcessInfo
)
View
()
string
{
haveProcess
:=
false
var
heightLightPid
int32
=
0
if
m
.
actionMsg
!=
nil
&&
m
.
actionMsg
.
PointPid
!=
nil
{
heightLightPid
=
*
m
.
actionMsg
.
PointPid
}
lines
:=
make
([]
string
,
0
)
sb
:=
strings
.
Builder
{}
sbInner
:=
strings
.
Builder
{}
for
index
:=
range
64
{
processes
,
have
:=
m
.
Cache
[
index
]
if
!
have
{
...
...
@@ -71,38 +77,61 @@ func (m *ModelProcessInfo) View() string {
for
_
,
process
:=
range
processes
{
haveProcess
=
true
sb
.
WriteString
(
myBorder
.
Left
)
sb
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
DCU
),
4
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
Info
.
Pid
),
7
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
process
.
Info
.
User
,
8
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
process
.
DCUMem
,
8
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
SDMA
),
4
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f"
,
process
.
Info
.
CPU
),
5
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f"
,
process
.
Info
.
Mem
),
5
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sb
.
WriteString
(
FormatStr
(
process
.
Info
.
Time
,
9
,
lipgloss
.
Right
))
sb
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
DCU
),
4
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
Info
.
Pid
),
7
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
process
.
Info
.
User
,
8
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
process
.
DCUMem
,
8
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%d"
,
process
.
SDMA
),
4
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f"
,
process
.
Info
.
CPU
),
5
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
fmt
.
Sprintf
(
"%.1f"
,
process
.
Info
.
Mem
),
5
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
sbInner
.
WriteString
(
FormatStr
(
process
.
Info
.
Time
,
9
,
lipgloss
.
Right
))
sbInner
.
WriteByte
(
' '
)
if
process
.
Info
.
ContInfo
!=
nil
{
sb
.
WriteString
(
FormatStr
(
process
.
Info
.
ContInfo
.
Name
,
20
,
lipgloss
.
Left
))
sb
Inner
.
WriteString
(
FormatStr
(
process
.
Info
.
ContInfo
.
Name
,
20
,
lipgloss
.
Left
))
}
else
{
sb
.
WriteString
(
FormatStr
(
" - "
,
20
,
lipgloss
.
Right
))
sb
Inner
.
WriteString
(
FormatStr
(
" - "
,
20
,
lipgloss
.
Right
))
}
sb
.
WriteByte
(
' '
)
w
:=
m
.
width
-
lipgloss
.
Width
(
sb
.
String
())
-
2
sb
Inner
.
WriteByte
(
' '
)
w
:=
m
.
width
-
lipgloss
.
Width
(
sb
Inner
.
String
())
-
3
tw
:=
lipgloss
.
Width
(
process
.
Info
.
Cmd
)
if
w
>=
tw
{
sb
.
WriteString
(
process
.
Info
.
Cmd
)
sb
.
WriteString
(
strings
.
Repeat
(
" "
,
w
-
tw
))
sbInner
.
WriteString
(
process
.
Info
.
Cmd
)
sbInner
.
WriteString
(
strings
.
Repeat
(
" "
,
w
-
tw
))
}
else
{
sbInner
.
WriteString
(
FormatStr
(
process
.
Info
.
Cmd
,
w
-
1
,
lipgloss
.
Left
))
sbInner
.
WriteString
(
".."
)
}
sbInner
.
WriteByte
(
' '
)
selected
:=
false
if
m
.
actionMsg
!=
nil
&&
m
.
actionMsg
.
SelectPids
!=
nil
{
b
,
have
:=
m
.
actionMsg
.
SelectPids
[
process
.
Info
.
Pid
]
if
have
&&
b
{
selected
=
true
}
}
if
heightLightPid
==
process
.
Info
.
Pid
{
if
selected
{
sb
.
WriteString
(
HeightSelectedStyle
.
Render
(
sbInner
.
String
()))
}
else
{
sb
.
WriteString
(
FormatStr
(
process
.
Info
.
Cmd
,
w
-
2
,
lipgloss
.
Left
))
sb
.
WriteString
(
".."
)
sb
.
WriteString
(
HeightLightStyle
.
Render
(
sbInner
.
String
()))
}
sb
.
WriteByte
(
' '
)
}
else
{
if
selected
{
sb
.
WriteString
(
SelectedStyle
.
Render
(
sbInner
.
String
()))
}
else
{
sb
.
WriteString
(
sbInner
.
String
())
}
}
sbInner
.
Reset
()
sb
.
WriteString
(
myBorder
.
Right
)
sb
.
WriteByte
(
'\n'
)
lines
=
append
(
lines
,
sb
.
String
())
...
...
@@ -131,6 +160,9 @@ func (m *ModelProcessInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
maps
.
Copy
(
m
.
Cache
,
msg
.
DCUPidInfo
)
m
.
modMsg
=
msg
return
m
,
nil
case
*
ActionMsg
:
m
.
actionMsg
=
msg
return
m
,
nil
}
return
m
,
nil
}
cmd/hytop/tui/sysload.go
View file @
3e5adb86
...
...
@@ -36,7 +36,9 @@ type ModelSysLoad struct {
bottomLine
string
style
lipgloss
.
Style
width
int
// 组件总宽度
colors
[]
color
.
Color
colors
[]
color
.
Color
// 时序图的颜色表
actionMsg
*
ActionMsg
// 动作消息
modelMsg
*
ModelMsg
// 模型周期性消息
}
type
SysLoadInfo
struct
{
...
...
@@ -145,7 +147,12 @@ func (m *ModelSysLoad) init() [6]time.Time {
func
(
m
*
ModelSysLoad
)
Update
(
inputMsg
tea
.
Msg
)
(
tea
.
Model
,
tea
.
Cmd
)
{
switch
msg
:=
inputMsg
.
(
type
)
{
case
*
ModelMsg
:
m
.
modelMsg
=
msg
m
.
updateInfo
(
msg
)
return
m
,
nil
case
*
ActionMsg
:
m
.
actionMsg
=
msg
return
m
,
nil
}
return
m
,
nil
...
...
@@ -196,8 +203,6 @@ func (m *ModelSysLoad) updateInfo(t *ModelMsg) {
s
.
DCUMemUsageAvg
,
s
.
DCUUsageAvg
=
0
,
0
qinfo
,
lock
:=
t
.
DCUInfo
.
GetQuitInfo
()
defer
lock
.
Unlock
()
for
k
,
v
:=
range
qinfo
{
s
.
DCUMemUsageAvg
+=
v
.
MemUsedPerent
s
.
DCUMemUsage
[
k
]
=
v
.
MemUsedPerent
...
...
@@ -205,6 +210,7 @@ func (m *ModelSysLoad) updateInfo(t *ModelMsg) {
s
.
DCUUsage
[
k
]
=
v
.
DCUUTil
}
l
:=
len
(
qinfo
)
lock
.
Unlock
()
s
.
DCUMemUsageAvg
/=
float32
(
l
)
s
.
DCUUsageAvg
/=
float32
(
l
)
m
.
current
=
&
s
...
...
cmd/hytop/tui/timechart.go
View file @
3e5adb86
...
...
@@ -192,6 +192,9 @@ func (m *MyTimeChart) View() string {
case
utils
.
CharFull
:
runes
[
line
][
col
]
=
utils
.
FullMW
}
if
t
,
have
:=
utils
.
MM
[
runes
[
line
][
col
]];
have
{
runes
[
line
][
col
]
=
t
}
case
utils
.
CharLeft
:
switch
utils
.
CharTypeOr
(
charStat
,
utils
.
CharLeft
)
{
case
utils
.
CharLeft
:
...
...
@@ -202,6 +205,9 @@ func (m *MyTimeChart) View() string {
runes
[
line
][
col
]
=
utils
.
FullMW
}
charStat
=
utils
.
CharTypeOr
(
charStat
,
utils
.
CharLeft
)
if
t
,
have
:=
utils
.
MM
[
runes
[
line
][
col
]];
have
{
runes
[
line
][
col
]
=
t
}
case
utils
.
CharRight
:
switch
utils
.
CharTypeOr
(
charStat
,
utils
.
CharRight
)
{
case
utils
.
CharLeft
:
...
...
@@ -212,8 +218,14 @@ func (m *MyTimeChart) View() string {
runes
[
line
][
col
]
=
utils
.
FullMW
}
charStat
=
utils
.
CharTypeOr
(
charStat
,
utils
.
CharRight
)
if
t
,
have
:=
utils
.
MM
[
runes
[
line
][
col
]];
have
{
runes
[
line
][
col
]
=
t
}
case
utils
.
CharFull
:
charStat
=
utils
.
CharFull
if
t
,
have
:=
utils
.
MM
[
runes
[
line
][
col
]];
have
{
runes
[
line
][
col
]
=
t
}
}
}
...
...
gpu/hy-smi.go
View file @
3e5adb86
...
...
@@ -462,7 +462,6 @@ type DCUPidInfo struct {
}
// GetDCUPidInfo 获取Pid相关信息
// 需要剔除PCIBus为空的项
func
GetDCUPidInfo
()
([]
DCUPidInfo
,
error
)
{
output
,
err
:=
exec
.
Command
(
DCUBinaryFile
,
"--showpids"
)
.
Output
()
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment