driver: fix build on solaris

Solaris has syscall.Rusage but not syscall.Getrusage.

So use golang.org/x/sys/unix for Getrusage instead, which requires
using the unix.Rusage type more. But we still need to use the syscall
type in one place too, which requires converting from the std to unix
type. Little gross, but works.

Change-Id: I7176062f1325cbb808e5f0ef481be966d94c1ac0
Reviewed-on: https://go-review.googlesource.com/c/benchmarks/+/170785
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
diff --git a/driver/driver_bsd.go b/driver/driver_stub.go
similarity index 90%
rename from driver/driver_bsd.go
rename to driver/driver_stub.go
index 51020f5..d964039 100644
--- a/driver/driver_bsd.go
+++ b/driver/driver_stub.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//+build dragonfly freebsd netbsd openbsd
+//+build dragonfly freebsd netbsd openbsd solaris
 
 package driver
 
diff --git a/driver/driver_unix.go b/driver/driver_unix.go
index 797e5d7..76c5463 100644
--- a/driver/driver_unix.go
+++ b/driver/driver_unix.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin dragonfly freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package driver
 
@@ -12,16 +12,18 @@
 	"os/exec"
 	"syscall"
 	"time"
+
+	"golang.org/x/sys/unix"
 )
 
 type sysStats struct {
 	N      uint64
-	Rusage syscall.Rusage
+	Rusage unix.Rusage
 }
 
 func InitSysStats(N uint64) sysStats {
 	ss := sysStats{N: N}
-	if err := syscall.Getrusage(0, &ss.Rusage); err != nil {
+	if err := unix.Getrusage(0, &ss.Rusage); err != nil {
 		log.Printf("Getrusage failed: %v", err)
 		ss.N = 0
 		// Deliberately ignore the error.
@@ -36,8 +38,8 @@
 	if vm := getVMPeak(); vm != 0 {
 		res.Metrics["peak-VM-bytes"] = vm
 	}
-	usage := new(syscall.Rusage)
-	if err := syscall.Getrusage(0, usage); err != nil {
+	usage := new(unix.Rusage)
+	if err := unix.Getrusage(0, usage); err != nil {
 		log.Printf("Getrusage failed: %v", err)
 		// Deliberately ignore the error.
 		return
@@ -55,7 +57,7 @@
 		return out.String(), err
 	}
 	t1 := time.Now()
-	usage := cmd.ProcessState.SysUsage().(*syscall.Rusage)
+	usage := fromStdUsage(cmd.ProcessState.SysUsage().(*syscall.Rusage))
 	res.RunTime = uint64(t1.Sub(t0)) / N
 	res.Metrics[prefix+"ns/op"] = res.RunTime
 	res.Metrics[prefix+"user+sys-ns/op"] = cpuTime(usage) / N
@@ -63,7 +65,28 @@
 	return out.String(), nil
 }
 
-func cpuTime(usage *syscall.Rusage) uint64 {
+func cpuTime(usage *unix.Rusage) uint64 {
 	return uint64(usage.Utime.Sec)*1e9 + uint64(usage.Utime.Usec*1e3) +
 		uint64(usage.Stime.Sec)*1e9 + uint64(usage.Stime.Usec)*1e3
 }
+
+func fromStdUsage(su *syscall.Rusage) *unix.Rusage {
+	return &unix.Rusage{
+		Utime:    unix.Timeval{Sec: su.Utime.Sec, Usec: su.Utime.Usec},
+		Stime:    unix.Timeval{Sec: su.Stime.Sec, Usec: su.Stime.Usec},
+		Maxrss:   su.Maxrss,
+		Ixrss:    su.Ixrss,
+		Idrss:    su.Idrss,
+		Isrss:    su.Isrss,
+		Minflt:   su.Minflt,
+		Majflt:   su.Majflt,
+		Nswap:    su.Nswap,
+		Inblock:  su.Inblock,
+		Oublock:  su.Oublock,
+		Msgsnd:   su.Msgsnd,
+		Msgrcv:   su.Msgrcv,
+		Nsignals: su.Nsignals,
+		Nvcsw:    su.Nvcsw,
+		Nivcsw:   su.Nivcsw,
+	}
+}