mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-03 23:57:32 -04:00
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:
committed by
Tobias Klauser
parent
593003d681
commit
1f56873058
@@ -46,6 +46,7 @@ package unix
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
#include <sys/timex.h>
|
#include <sys/timex.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
@@ -410,6 +411,8 @@ type Timeval C.struct_timeval
|
|||||||
|
|
||||||
type Timex C.struct_timex
|
type Timex C.struct_timex
|
||||||
|
|
||||||
|
type ItimerSpec C.struct_itimerspec
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TIME_OK = C.TIME_OK
|
TIME_OK = C.TIME_OK
|
||||||
TIME_INS = C.TIME_INS
|
TIME_INS = C.TIME_INS
|
||||||
|
|||||||
+2
-1
@@ -187,6 +187,7 @@ struct ltchars {
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/signalfd.h>
|
#include <sys/signalfd.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/timerfd.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
#include <linux/bpf.h>
|
#include <linux/bpf.h>
|
||||||
@@ -480,7 +481,7 @@ ccflags="$@"
|
|||||||
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
$2 ~ /^(MS|MNT|UMOUNT)_/ ||
|
||||||
$2 ~ /^NS_GET_/ ||
|
$2 ~ /^NS_GET_/ ||
|
||||||
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
|
||||||
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT)_/ ||
|
$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT|TFD)_/ ||
|
||||||
$2 ~ /^KEXEC_/ ||
|
$2 ~ /^KEXEC_/ ||
|
||||||
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
$2 ~ /^LINUX_REBOOT_CMD_/ ||
|
||||||
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
$2 ~ /^LINUX_REBOOT_MAGIC[12]$/ ||
|
||||||
|
|||||||
@@ -1757,6 +1757,9 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
|
|||||||
//sys Syncfs(fd int) (err error)
|
//sys Syncfs(fd int) (err error)
|
||||||
//sysnb Sysinfo(info *Sysinfo_t) (err error)
|
//sysnb Sysinfo(info *Sysinfo_t) (err error)
|
||||||
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
|
//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
|
||||||
|
//sysnb TimerfdCreate(clockid int, flags int) (fd int, err error)
|
||||||
|
//sysnb TimerfdGettime(fd int, currValue *ItimerSpec) (err error)
|
||||||
|
//sysnb TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error)
|
||||||
//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
|
//sysnb Tgkill(tgid int, tid int, sig syscall.Signal) (err error)
|
||||||
//sysnb Times(tms *Tms) (ticks uintptr, err error)
|
//sysnb Times(tms *Tms) (ticks uintptr, err error)
|
||||||
//sysnb Umask(mask int) (oldmask int)
|
//sysnb Umask(mask int) (oldmask int)
|
||||||
@@ -2178,7 +2181,6 @@ func Klogset(typ int, arg int) (err error) {
|
|||||||
// TimerGetoverrun
|
// TimerGetoverrun
|
||||||
// TimerGettime
|
// TimerGettime
|
||||||
// TimerSettime
|
// TimerSettime
|
||||||
// Timerfd
|
|
||||||
// Tkill (obsolete)
|
// Tkill (obsolete)
|
||||||
// Tuxcall
|
// Tuxcall
|
||||||
// Umount2
|
// Umount2
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"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)
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2165,6 +2165,8 @@ const (
|
|||||||
TCP_USER_TIMEOUT = 0x12
|
TCP_USER_TIMEOUT = 0x12
|
||||||
TCP_WINDOW_CLAMP = 0xa
|
TCP_WINDOW_CLAMP = 0xa
|
||||||
TCP_ZEROCOPY_RECEIVE = 0x23
|
TCP_ZEROCOPY_RECEIVE = 0x23
|
||||||
|
TFD_TIMER_ABSTIME = 0x1
|
||||||
|
TFD_TIMER_CANCEL_ON_SET = 0x2
|
||||||
TIMER_ABSTIME = 0x1
|
TIMER_ABSTIME = 0x1
|
||||||
TIOCM_DTR = 0x2
|
TIOCM_DTR = 0x2
|
||||||
TIOCM_LE = 0x1
|
TIOCM_LE = 0x1
|
||||||
|
|||||||
@@ -342,6 +342,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -343,6 +343,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -349,6 +349,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -336,6 +336,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ const (
|
|||||||
TCSETSW = 0x540f
|
TCSETSW = 0x540f
|
||||||
TCSETSW2 = 0x8030542c
|
TCSETSW2 = 0x8030542c
|
||||||
TCXONC = 0x5406
|
TCXONC = 0x5406
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x80
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x80047478
|
TIOCCONS = 0x80047478
|
||||||
TIOCEXCL = 0x740d
|
TIOCEXCL = 0x740d
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ const (
|
|||||||
TCSETSW = 0x540f
|
TCSETSW = 0x540f
|
||||||
TCSETSW2 = 0x8030542c
|
TCSETSW2 = 0x8030542c
|
||||||
TCXONC = 0x5406
|
TCXONC = 0x5406
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x80
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x80047478
|
TIOCCONS = 0x80047478
|
||||||
TIOCEXCL = 0x740d
|
TIOCEXCL = 0x740d
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ const (
|
|||||||
TCSETSW = 0x540f
|
TCSETSW = 0x540f
|
||||||
TCSETSW2 = 0x8030542c
|
TCSETSW2 = 0x8030542c
|
||||||
TCXONC = 0x5406
|
TCXONC = 0x5406
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x80
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x80047478
|
TIOCCONS = 0x80047478
|
||||||
TIOCEXCL = 0x740d
|
TIOCEXCL = 0x740d
|
||||||
|
|||||||
@@ -339,6 +339,8 @@ const (
|
|||||||
TCSETSW = 0x540f
|
TCSETSW = 0x540f
|
||||||
TCSETSW2 = 0x8030542c
|
TCSETSW2 = 0x8030542c
|
||||||
TCXONC = 0x5406
|
TCXONC = 0x5406
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x80
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x80047478
|
TIOCCONS = 0x80047478
|
||||||
TIOCEXCL = 0x740d
|
TIOCEXCL = 0x740d
|
||||||
|
|||||||
@@ -393,6 +393,8 @@ const (
|
|||||||
TCSETSF = 0x802c7416
|
TCSETSF = 0x802c7416
|
||||||
TCSETSW = 0x802c7415
|
TCSETSW = 0x802c7415
|
||||||
TCXONC = 0x2000741e
|
TCXONC = 0x2000741e
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -393,6 +393,8 @@ const (
|
|||||||
TCSETSF = 0x802c7416
|
TCSETSF = 0x802c7416
|
||||||
TCSETSW = 0x802c7415
|
TCSETSW = 0x802c7415
|
||||||
TCXONC = 0x2000741e
|
TCXONC = 0x2000741e
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -330,6 +330,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -403,6 +403,8 @@ const (
|
|||||||
TCSETXF = 0x5434
|
TCSETXF = 0x5434
|
||||||
TCSETXW = 0x5435
|
TCSETXW = 0x5435
|
||||||
TCXONC = 0x540a
|
TCXONC = 0x540a
|
||||||
|
TFD_CLOEXEC = 0x80000
|
||||||
|
TFD_NONBLOCK = 0x800
|
||||||
TIOCCBRK = 0x5428
|
TIOCCBRK = 0x5428
|
||||||
TIOCCONS = 0x541d
|
TIOCCONS = 0x541d
|
||||||
TIOCEXCL = 0x540c
|
TIOCEXCL = 0x540c
|
||||||
|
|||||||
@@ -392,6 +392,8 @@ const (
|
|||||||
TCSETSW = 0x8024540a
|
TCSETSW = 0x8024540a
|
||||||
TCSETSW2 = 0x802c540e
|
TCSETSW2 = 0x802c540e
|
||||||
TCXONC = 0x20005406
|
TCXONC = 0x20005406
|
||||||
|
TFD_CLOEXEC = 0x400000
|
||||||
|
TFD_NONBLOCK = 0x4000
|
||||||
TIOCCBRK = 0x2000747a
|
TIOCCBRK = 0x2000747a
|
||||||
TIOCCONS = 0x20007424
|
TIOCCONS = 0x20007424
|
||||||
TIOCEXCL = 0x2000740d
|
TIOCEXCL = 0x2000740d
|
||||||
|
|||||||
@@ -1450,6 +1450,37 @@ func Sysinfo(info *Sysinfo_t) (err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func TimerfdCreate(clockid int, flags int) (fd int, err error) {
|
||||||
|
r0, _, e1 := RawSyscall(SYS_TIMERFD_CREATE, uintptr(clockid), uintptr(flags), 0)
|
||||||
|
fd = int(r0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func TimerfdGettime(fd int, currValue *ItimerSpec) (err error) {
|
||||||
|
_, _, e1 := RawSyscall(SYS_TIMERFD_GETTIME, uintptr(fd), uintptr(unsafe.Pointer(currValue)), 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func TimerfdSettime(fd int, flags int, newValue *ItimerSpec, oldValue *ItimerSpec) (err error) {
|
||||||
|
_, _, e1 := RawSyscall6(SYS_TIMERFD_SETTIME, uintptr(fd), uintptr(flags), uintptr(unsafe.Pointer(newValue)), uintptr(unsafe.Pointer(oldValue)), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) {
|
func Tgkill(tgid int, tid int, sig syscall.Signal) (err error) {
|
||||||
_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
|
_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ type (
|
|||||||
_C_long_long int64
|
_C_long_long int64
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ItimerSpec struct {
|
||||||
|
Interval Timespec
|
||||||
|
Value Timespec
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TIME_OK = 0x0
|
TIME_OK = 0x0
|
||||||
TIME_INS = 0x1
|
TIME_INS = 0x1
|
||||||
|
|||||||
Reference in New Issue
Block a user