I don't see what i'm doing wrong here with this error, both are of type syscall.Timeval Usec
Thanks
package common
import (
"syscall"
)
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
for now.Sec > oldTime.Sec {
result += 1000000
now.Sec--
}
return result + (now.Usec - oldTime.Usec)
}
./common.go:15: invalid operation: result + (now.Usec - oldTime.Usec) (mismatched types uint64 and int32)
Timeval.Usec
is defined as int32
. Maybe result
should be also int32
? Alternatively if you want to use uint64
you can cast it by uint64(now.Usec - oldTime.Usec)
.
Use a signed return value (int64
), like Timeval.Sec
and Timeval.Usec
. Use TimevalToNsec
for portability across operating systems. For example, Timeval
fields may be int32
or int64
. For a correct result, use,
package main
import (
"fmt"
"syscall"
"time"
)
func getUsecSince(old syscall.Timeval) int64 {
var now syscall.Timeval
syscall.Gettimeofday(&now)
nsecs := syscall.TimevalToNsec(now) - syscall.TimevalToNsec(old)
return nsecs / int64(time.Microsecond)
}
func main() {
old := syscall.Timeval{}
syscall.Gettimeofday(&old)
time.Sleep(2*time.Second + 42*time.Microsecond)
fmt.Println(getUsecSince(old))
}
Output:
2000377
The simplest solution to this is:
func getUsecSince(oldTime syscall.Timeval) (result uint64) {
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
// Automatically ignore cases like 12.5 - 11.8
result = uint64((now.Sec - oldTime.Sec) * 1000000 + int64(now.Usec - oldTime.Usec))
return result
}
By converting to the smallest unit you can ignore the boundary conditions easily as long as there is no overflow during conversion.
Note that if you purposely test the above by using an oldTime
in the future, the function will fail. You will need to do a check (with both times converted to Usec
) if you want to cover such cases.
result is uint64. The other operands are int32 Running this
now := syscall.Timeval{}
syscall.Gettimeofday(&now)
typeUsec := reflect.TypeOf(now.Usec)
fmt.Printf("type %s, value %d
", typeUsec, now.Usec)
will print
type int32, value 238376
Strangely, the go documents have the following
type Timeval struct {
Sec int64
Usec int64
}