unix: add support for timerfd syscalls on Linux

timerfd_create, timerfd_gettime and timerfd_settime syscalls have been added.
Fixes golang/go#38733

Change-Id: I306d68103b6efb2515c74f384646210c4b68f66e
Reviewed-on: https://go-review.googlesource.com/c/sys/+/230798
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
Maxim Pugachev
2020-04-30 08:24:07 +00:00
committed by Tobias Klauser
parent 593003d681
commit 1f56873058
20 changed files with 123 additions and 2 deletions
+51
View File
@@ -19,6 +19,7 @@ import (
"strings"
"testing"
"time"
"unsafe"
"golang.org/x/sys/unix"
)
@@ -663,3 +664,53 @@ func TestPrctlRetInt(t *testing.T) {
t.Fatalf("unexpected return from prctl; got %v, expected %v", v, 1)
}
}
func TestTimerfd(t *testing.T) {
var now unix.Timespec
if err := unix.ClockGettime(unix.CLOCK_REALTIME, &now); err != nil {
t.Fatalf("ClockGettime: %v", err)
}
tfd, err := unix.TimerfdCreate(unix.CLOCK_REALTIME, 0)
if err == unix.ENOSYS {
t.Skip("timerfd_create system call not implemented")
} else if err != nil {
t.Fatalf("TimerfdCreate: %v", err)
}
defer unix.Close(tfd)
var timeSpec unix.ItimerSpec
if err := unix.TimerfdGettime(tfd, &timeSpec); err != nil {
t.Fatalf("TimerfdGettime: %v", err)
}
if timeSpec.Value.Nsec != 0 || timeSpec.Value.Sec != 0 {
t.Fatalf("TimerfdGettime: timer is already set, but shouldn't be")
}
timeSpec = unix.ItimerSpec{
Interval: unix.NsecToTimespec(int64(time.Millisecond)),
Value: now,
}
if err := unix.TimerfdSettime(tfd, unix.TFD_TIMER_ABSTIME, &timeSpec, nil); err != nil {
t.Fatalf("TimerfdSettime: %v", err)
}
const totalTicks = 10
const bufferLength = 8
buffer := make([]byte, bufferLength)
var count uint64 = 0
for count < totalTicks {
n, err := unix.Read(tfd, buffer)
if err != nil {
t.Fatalf("Timerfd: %v", err)
} else if n != bufferLength {
t.Fatalf("Timerfd: got %d bytes from timerfd, expected %d bytes", n, bufferLength)
}
count += *(*uint64)(unsafe.Pointer(&buffer))
}
}