92 lines
3.0 KiB
Go
92 lines
3.0 KiB
Go
package main
|
|
|
|
// helper to debug memory blow-up
|
|
|
|
import (
|
|
"sync"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
// Go-ized http://man7.org/linux/man-pages/man2/sysinfo.2.html
|
|
type SI struct {
|
|
Uptime time.Duration // time since boot
|
|
Loads [3]float64 // 1, 5, and 15 minute load averages, see e.g. UPTIME(1)
|
|
Procs uint64 // number of current processes
|
|
TotalRam uint64 // total usable main memory size [kB]
|
|
FreeRam uint64 // available memory size [kB]
|
|
SharedRam uint64 // amount of shared memory [kB]
|
|
BufferRam uint64 // memory used by buffers [kB]
|
|
TotalSwap uint64 // total swap space size [kB]
|
|
FreeSwap uint64 // swap space still available [kB]
|
|
TotalHighRam uint64 // total high memory size [kB]
|
|
FreeHighRam uint64 // available high memory size [kB]
|
|
mu sync.Mutex // ensures atomic writes; protects the following fields
|
|
}
|
|
|
|
var sis = &SI{}
|
|
|
|
// Get the linux sysinfo data structure.
|
|
//
|
|
// Useful links in the wild web:
|
|
// http://man7.org/linux/man-pages/man2/sysinfo.2.html
|
|
// http://man7.org/linux/man-pages/man1/uptime.1.html
|
|
// https://github.com/capnm/golang/blob/go1.1.1/src/pkg/syscall/zsyscall_linux_amd64.go#L1050
|
|
// https://github.com/capnm/golang/blob/go1.1.1/src/pkg/syscall/ztypes_linux_amd64.go#L528
|
|
// https://github.com/capnm/golang/blob/go1.1.1/src/pkg/syscall/ztypes_linux_arm.go#L502
|
|
func CPUInfo() *SI {
|
|
|
|
/*
|
|
// Note: uint64 is uint32 on 32 bit CPUs
|
|
type Sysinfo_t struct {
|
|
Uptime int64 // Seconds since boot
|
|
Loads [3]uint64 // 1, 5, and 15 minute load averages
|
|
Totalram uint64 // Total usable main memory size
|
|
Freeram uint64 // Available memory size
|
|
Sharedram uint64 // Amount of shared memory
|
|
Bufferram uint64 // Memory used by buffers
|
|
Totalswap uint64 // Total swap space size
|
|
Freeswap uint64 // swap space still available
|
|
Procs uint16 // Number of current processes
|
|
Pad uint16
|
|
Pad_cgo_0 [4]byte
|
|
Totalhigh uint64 // Total high memory size
|
|
Freehigh uint64 // Available high memory size
|
|
Unit uint32 // Memory unit size in bytes
|
|
X_f [0]byte
|
|
Pad_cgo_1 [4]byte // Padding to 64 bytes
|
|
}
|
|
*/
|
|
|
|
// ~1kB garbage
|
|
si := &syscall.Sysinfo_t{}
|
|
|
|
// XXX is a raw syscall thread safe?
|
|
err := syscall.Sysinfo(si)
|
|
if err != nil {
|
|
panic("Commander, we have a problem. syscall.Sysinfo:" + err.Error())
|
|
}
|
|
scale := 65536.0 // magic
|
|
|
|
defer sis.mu.Unlock()
|
|
sis.mu.Lock()
|
|
|
|
unit := uint64(si.Unit) * 1024 // kB
|
|
|
|
sis.Uptime = time.Duration(si.Uptime) * time.Second
|
|
sis.Loads[0] = float64(si.Loads[0]) / scale
|
|
sis.Loads[1] = float64(si.Loads[1]) / scale
|
|
sis.Loads[2] = float64(si.Loads[2]) / scale
|
|
sis.Procs = uint64(si.Procs)
|
|
|
|
sis.TotalRam = uint64(si.Totalram) / unit
|
|
sis.FreeRam = uint64(si.Freeram) / unit
|
|
sis.BufferRam = uint64(si.Bufferram) / unit
|
|
sis.TotalSwap = uint64(si.Totalswap) / unit
|
|
sis.FreeSwap = uint64(si.Freeswap) / unit
|
|
sis.TotalHighRam = uint64(si.Totalhigh) / unit
|
|
sis.FreeHighRam = uint64(si.Freehigh) / unit
|
|
|
|
return sis
|
|
}
|