Skip to content

Commit

Permalink
Merge pull request #53 from giuseppe/nocgo
Browse files Browse the repository at this point in the history
process: read AT_CLKTCK from the auxv
  • Loading branch information
vrothberg authored Jun 26, 2019
2 parents d18db3c + 9de501b commit fbef66e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
57 changes: 49 additions & 8 deletions internal/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,71 @@ package host

import (
"bufio"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
"unsafe"
)

/*
#include <unistd.h>
*/
import "C"

var (
// cache host queries to redundant calculations
clockTicks *int64
bootTime *int64
)

func getNativeEndianness() binary.ByteOrder {
var i int32 = 0x00000001
u := unsafe.Pointer(&i)
if *((*byte)(u)) == 0x01 {
return binary.LittleEndian
}
return binary.BigEndian
}

const (
atClktck = 17
)

func getFromAuxv(what uint, whatName string) (uint, error) {
dataLen := int(unsafe.Sizeof(int(0)))
p, err := ioutil.ReadFile("/proc/self/auxv")
if err != nil {
return 0, err
}
native := getNativeEndianness()
for i := 0; i < len(p); {
var k, v uint

switch dataLen {
case 4:
k = uint(native.Uint32(p[i : i+dataLen]))
v = uint(native.Uint32(p[i+dataLen : i+dataLen*2]))
case 8:
k = uint(native.Uint64(p[i : i+dataLen]))
v = uint(native.Uint64(p[i+dataLen : i+dataLen*2]))
}
i += dataLen * 2
if k == what {
return v, nil
}
}
return 0, fmt.Errorf("cannot find %s in auxv", whatName)
}

// ClockTicks returns sysconf(SC_CLK_TCK).
func ClockTicks() int64 {
func ClockTicks() (int64, error) {
if clockTicks == nil {
ticks := int64(C.sysconf(C._SC_CLK_TCK))
ret, err := getFromAuxv(atClktck, "AT_CLKTCK")
if err != nil {
return -1, err
}
ticks := int64(ret)
clockTicks = &ticks
}
return *clockTicks
return *clockTicks, nil
}

// BootTime parses /proc/uptime returns the boot time in seconds since the
Expand Down
3 changes: 2 additions & 1 deletion internal/host/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import (

func TestClockTicks(t *testing.T) {
// no thorough test but it makes sure things are working
ticks := ClockTicks()
ticks, err := ClockTicks()
assert.Nil(t, err)
assert.True(t, ticks > 0)
}

Expand Down
12 changes: 10 additions & 2 deletions internal/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,12 @@ func (p *Process) ElapsedTime() (time.Duration, error) {
if err != nil {
return 0, err
}
clockTicks, err := host.ClockTicks()
if err != nil {
return 0, err
}

sinceBoot = sinceBoot / host.ClockTicks()
sinceBoot = sinceBoot / clockTicks

bootTime, err := host.BootTime()
if err != nil {
Expand All @@ -213,7 +217,11 @@ func (p *Process) CPUTime() (time.Duration, error) {
if err != nil {
return 0, err
}
secs := (user + system) / host.ClockTicks()
clockTicks, err := host.ClockTicks()
if err != nil {
return 0, err
}
secs := (user + system) / clockTicks
cpu := time.Unix(secs, 0)
return cpu.Sub(time.Unix(0, 0)), nil
}

0 comments on commit fbef66e

Please sign in to comment.