blob: 4c801cb100642b256bf320e4c1acb4ff466064be [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package clock
import (
"bytes"
"encoding/binary"
"syscall"
"time"
"unsafe"
)
// This file contains darwin specific implementations of functions for clock
// package.
// ElapsedTime returns the time elapsed since last boot.
// Darwin provides a system call "kern.boottime" which returns a Timeval32
// object containing the boot time for the system. Darwin calculates this
// boottime based on the current clock and the internal tracking of elapsed
// time since boot. Hence if the clock is changed, the boot time changes along
// with it. So the difference between the current time and boot time will always
// give us the correct elapsed time since boot.
func (sc *systemClockImpl) ElapsedTime() (time.Duration, error) {
tv := syscall.Timeval32{}
if err := sysctlbyname("kern.boottime", &tv); err != nil {
return 0, err
}
return time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)), nil
}
// Generic Sysctl buffer unmarshalling.
func sysctlbyname(name string, data interface{}) (err error) {
val, err := syscall.Sysctl(name)
if err != nil {
return err
}
buf := []byte(val)
switch v := data.(type) {
case *uint64:
*v = *(*uint64)(unsafe.Pointer(&buf[0]))
return
}
bbuf := bytes.NewBuffer([]byte(val))
return binary.Read(bbuf, binary.LittleEndian, data)
}