blob: ea2b7a0090fa8c765ae04994e6ccdbc5ad2293ee [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.
// Darwin-specific bits of the system clock implementation.
package vclock
import (
// Darwin provides a "kern.boottime" syscall that returns a Timeval32 object
// with the system's boot time, computed as current time minus the system's
// elapsed time since boot. Thus, subtracting the returned boot time from the
// current time yields the system's elapsed time since boot.
// TODO(sadovsky): Technically, we should make sure the system clock doesn't
// change between the syscall and time.Since(), since both consult the system
// clock.
func (*realSystemClock) 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]))
bbuf := bytes.NewBuffer([]byte(val))
return binary.Read(bbuf, binary.LittleEndian, data)