Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 35 additions & 12 deletions load/load_aix_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package load

#include <libperfstat.h>
#include <procinfo.h>
#include <sys/thread.h>
*/
import "C"

Expand All @@ -33,28 +34,50 @@ func AvgWithContext(ctx context.Context) (*AvgStat, error) {
}

func MiscWithContext(ctx context.Context) (*MiscStat, error) {
info := C.struct_procentry64{}
// Count total processes and collect PIDs for thread-state enumeration.
pinfo := C.struct_procentry64{}
cpid := C.pid_t(0)

ret := MiscStat{}
var pids []C.pid_t
for {
// getprocs first argument is a void*
num, err := C.getprocs64(unsafe.Pointer(&info), C.sizeof_struct_procentry64, nil, 0, &cpid, 1)
num, err := C.getprocs64(unsafe.Pointer(&pinfo), C.sizeof_struct_procentry64, nil, 0, &cpid, 1)
if err != nil {
return nil, err
}

ret.ProcsTotal++
switch info.pi_state {
case C.SACTIVE:
ret.ProcsRunning++
case C.SSTOP:
ret.ProcsBlocked++
}

if num == 0 {
break
}
ret.ProcsTotal++
pids = append(pids, pinfo.pi_pid)
}

// Count threads in TSRUN state (runnable/running) across all processes.
// SACTIVE at the process level means "active in memory" which includes
// sleeping processes and is not a useful proxy for ProcsRunning.
tinfo := C.struct_thrdentry64{}
for _, pid := range pids {
ctid := C.tid64_t(0)
for {
n, err := C.getthrds64(pid, unsafe.Pointer(&tinfo), C.sizeof_struct_thrdentry64, &ctid, 1)
if err != nil {
break // process may have exited
}
if n == 0 {
break
}
if tinfo.ti_state == C.TSRUN {
ret.ProcsRunning++
}
}
}

// ProcsBlocked: processes sleeping waiting for I/O, equivalent to Linux D state.
// perfstat IOWait and PhysIO are instantaneous counts, matching vmstat's b column.
var cpuStat C.perfstat_cpu_total_t
if rc := C.perfstat_cpu_total(nil, &cpuStat, C.sizeof_perfstat_cpu_total_t, 1); rc == 1 {
ret.ProcsBlocked = int(cpuStat.iowait) + int(cpuStat.physio)
}

return &ret, nil
}