Skip to content

Commit

Permalink
Saving boot time during ProcessesWithContext call (linux).
Browse files Browse the repository at this point in the history
On Linux, the system boot time is used when calculating process creation times
(expressed as number of seconds since the epoch). Obtaining the boot time
involves parsing the /proc/stat file, which can incur siginificant overhead
on systems with many CPU cores.

Permanently caching the boot time is not an option since it can change when the
system clock is updated (e.g. ntpd).

In this changeset we will save the boot time during one invocation of the
ProcessesWithContext function (listing all running processes).
  • Loading branch information
bjandras committed Aug 7, 2023
1 parent 78feb45 commit 51102f8
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion process/process_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const prioProcess = 0 // linux/resource.h

var clockTicks = 100 // default value

const bootTimeContextKey = "host_boot_time"

func init() {
clkTck, err := sysconf.Sysconf(sysconf.SC_CLK_TCK)
// ignore errors
Expand Down Expand Up @@ -1072,7 +1074,13 @@ func (p *Process) fillFromTIDStatWithContext(ctx context.Context, tid int32) (ui
Iowait: iotime / float64(clockTicks),
}

bootTime, _ := common.BootTimeWithContext(ctx)
var bootTime uint64
if bt, ok := ctx.Value(bootTimeContextKey).(uint64); ok {
bootTime = bt
} else {
bootTime, _ = common.BootTimeWithContext(ctx)
}

t, err := strconv.ParseUint(fields[22], 10, 64)
if err != nil {
return 0, 0, nil, 0, 0, 0, nil, err
Expand Down Expand Up @@ -1138,6 +1146,12 @@ func ProcessesWithContext(ctx context.Context) ([]*Process, error) {
return out, err
}

if bootTime, err := common.BootTimeWithContext(ctx); err == nil {
// Save the current value of boot time in the context -- to be used in
// fillFromTIDStatWithContext for each PID.
ctx = context.WithValue(ctx, bootTimeContextKey, bootTime)

Check warning on line 1152 in process/process_linux.go

View workflow job for this annotation

GitHub Actions / lint

context-keys-type: should not use basic type untyped string as key in context.WithValue (revive)
}

for _, pid := range pids {
p, err := NewProcessWithContext(ctx, pid)
if err != nil {
Expand Down

0 comments on commit 51102f8

Please sign in to comment.