Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131695423
D10020.id26292.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
D10020.id26292.diff
View Options
Index: contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c
===================================================================
--- contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c
+++ contrib/netbsd-tests/lib/libc/sys/t_clock_nanosleep.c
@@ -46,7 +46,11 @@
rqtp.tv_sec = 0; rqtp.tv_nsec = 0;
rmtp.tv_sec = -1; rmtp.tv_nsec = -1;
ATF_REQUIRE(clock_nanosleep(CLOCK_REALTIME, 0, &rqtp, &rmtp) == 0);
+#ifdef __FreeBSD__
+ ATF_CHECK(rmtp.tv_sec == -1 && rmtp.tv_nsec == -1);
+#else
ATF_CHECK(rmtp.tv_sec == 0 && rmtp.tv_nsec == 0);
+#endif
ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &rqtp) == 0);
rmtp.tv_sec = -1; rmtp.tv_nsec = -1;
Index: include/time.h
===================================================================
--- include/time.h
+++ include/time.h
@@ -168,8 +168,8 @@
#if __POSIX_VISIBLE >= 199309
int clock_getres(clockid_t, struct timespec *);
int clock_gettime(clockid_t, struct timespec *);
+int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
int clock_settime(clockid_t, const struct timespec *);
-/* XXX missing: clock_nanosleep() */
int nanosleep(const struct timespec *, struct timespec *);
#endif /* __POSIX_VISIBLE >= 199309 */
Index: lib/libc/include/libc_private.h
===================================================================
--- lib/libc/include/libc_private.h
+++ lib/libc/include/libc_private.h
@@ -229,6 +229,7 @@
INTERPOS_ppoll,
INTERPOS_map_stacks_exec,
INTERPOS_fdatasync,
+ INTERPOS_clock_nanosleep,
INTERPOS_MAX
};
@@ -318,6 +319,8 @@
int __sys_accept(int, struct sockaddr *, __socklen_t *);
int __sys_accept4(int, struct sockaddr *, __socklen_t *, int);
int __sys_clock_gettime(__clockid_t, struct timespec *ts);
+int __sys_clock_nanosleep(__clockid_t, int,
+ const struct timespec *, struct timespec *);
int __sys_close(int);
int __sys_connect(int, const struct sockaddr *, __socklen_t);
int __sys_fcntl(int, int, ...);
Index: lib/libc/include/namespace.h
===================================================================
--- lib/libc/include/namespace.h
+++ lib/libc/include/namespace.h
@@ -56,6 +56,7 @@
#define bind _bind
#define __cap_get_fd ___cap_get_fd
#define __cap_set_fd ___cap_set_fd
+#define clock_nanosleep _clock_nanosleep
#define close _close
#define connect _connect
#define dup _dup
Index: lib/libc/include/un-namespace.h
===================================================================
--- lib/libc/include/un-namespace.h
+++ lib/libc/include/un-namespace.h
@@ -37,6 +37,7 @@
#undef bind
#undef __cap_get_fd
#undef __cap_set_fd
+#undef clock_nanosleep
#undef close
#undef connect
#undef dup
Index: lib/libc/sys/Makefile.inc
===================================================================
--- lib/libc/sys/Makefile.inc
+++ lib/libc/sys/Makefile.inc
@@ -45,6 +45,7 @@
accept \
accept4 \
aio_suspend \
+ clock_nanosleep \
close \
connect \
fcntl \
@@ -360,6 +361,7 @@
chown.2 lchown.2
MLINKS+=clock_gettime.2 clock_getres.2 \
clock_gettime.2 clock_settime.2
+MLINKS+=nanosleep.2 clock_nanosleep.2
MLINKS+=cpuset.2 cpuset_getid.2 \
cpuset.2 cpuset_setid.2
MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -399,6 +399,7 @@
};
FBSD_1.5 {
+ clock_nanosleep;
fdatasync;
};
@@ -511,6 +512,8 @@
__sys_clock_getres;
_clock_gettime;
__sys_clock_gettime;
+ _clock_nanosleep;
+ __sys_clock_nanosleep;
_clock_settime;
__sys_clock_settime;
_close;
Index: lib/libc/sys/interposing_table.c
===================================================================
--- lib/libc/sys/interposing_table.c
+++ lib/libc/sys/interposing_table.c
@@ -42,6 +42,7 @@
SLOT(accept, __sys_accept),
SLOT(accept4, __sys_accept4),
SLOT(aio_suspend, __sys_aio_suspend),
+ SLOT(clock_nanosleep, __sys_clock_nanosleep),
SLOT(close, __sys_close),
SLOT(connect, __sys_connect),
SLOT(fcntl, __sys_fcntl),
Index: lib/libc/sys/nanosleep.2
===================================================================
--- lib/libc/sys/nanosleep.2
+++ lib/libc/sys/nanosleep.2
@@ -1,5 +1,4 @@
-.\" $OpenBSD: nanosleep.2,v 1.1 1997/04/20 20:56:20 tholo Exp $
-.\" $NetBSD: nanosleep.2,v 1.1 1997/04/17 18:12:02 jtc Exp $
+.\" $NetBSD: nanosleep.2,v 1.23 2016/11/14 10:40:59 wiz Exp $
.\"
.\" Copyright (c) 1986, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -31,51 +30,106 @@
.\" @(#)sleep.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd April 17, 1997
+.Dd March 10, 2017
.Dt NANOSLEEP 2
.Os
.Sh NAME
.Nm nanosleep
-.Nd suspend process execution for an interval measured in nanoseconds
+.Nd high resolution sleep
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In time.h
.Ft int
+.Fn clock_nanosleep "clockid_t clock_id" "int flags" "const struct timespec *rqtp" "struct timespec *rmtp"
+.Ft int
.Fn nanosleep "const struct timespec *rqtp" "struct timespec *rmtp"
.Sh DESCRIPTION
-The
-.Fn nanosleep
-system call
-causes the calling thread to sleep until the time interval specified by
+If the
+.Dv TIMER_ABSTIME
+flag is not set in the
+.Fa flags
+argument, then
+.Fn clock_nanosleep
+suspends execution of the calling thread until either the
+time interval specified by the
+.Fa rqtp
+argument has elapsed,
+or a signal is delivered to the calling process and its
+action is to invoke a signal-catching function or to terminate the
+process.
+The clock used to measure the time is specified by the
+.Fa clock_id
+argument.
+.Pp
+If the
+.Dv TIMER_ABSTIME
+flag is set in the
+.Fa flags
+argument, then
+.Fn clock_nanosleep
+suspends execution of the calling thread until either the value
+of the clock specified by the
+.Fa clock_id
+argument reaches the absolute time specified by the
.Fa rqtp
-has elapsed.
-An unmasked signal will
-cause it to terminate the sleep early, regardless of the
+argument,
+or a signal is delivered to the calling process and its
+action is to invoke a signal-catching function or to terminate the
+process.
+If, at the time of the call, the time value specified by
+.Fa rqtp
+is less than or equal to the time value of the specified clock, then
+.Fn clock_nanosleep
+returns immediately and the calling thread is not suspended.
+.Pp
+The suspension time may be longer than requested due to the
+scheduling of other activity by the system.
+An unmasked signal will terminate the sleep early, regardless of the
.Dv SA_RESTART
value on the interrupting signal.
-.Sh RETURN VALUES
-If the
+The
+.Fa rqtp
+and
+.Fa rmtp
+arguments can point to the same object.
+Available values for
+.Fa clock_id
+are described in
+.Xr clock_gettime 2 .
+.Pp
+The
.Fn nanosleep
-system call returns because the requested time has elapsed, the value
-returned will be zero.
+function behaves like
+.Fn clock_nanosleep
+with
+.Dv CLOCK_REALTIME
+and without
+.Dv TIMER_ABSTIME .
+.Sh RETURN VALUES
+These functions return zero when the requested time has elapsed.
.Pp
-If the
+If these functions return due to the delivery of a signal, then
+.Fn clock_nanosleep
+will directly return the error number, and
.Fn nanosleep
-system call returns due to the delivery of a signal, the value returned
-will be -1, and the global variable
+will return \-1 with the global variable
.Va errno
-will be set to indicate the interruption.
-If
+set to indicate the interruption.
+If the sleep is relative and
.Fa rmtp
is
-.No non- Ns Dv NULL ,
+.Pf non- Dv NULL ,
the timespec structure it references is updated to contain the
unslept amount (the request time minus the time actually slept).
.Sh ERRORS
-The
+If any of the following conditions occur,
.Fn nanosleep
-system call fails if:
+returns \-1 with
+.Va errno
+set to the corresponding value, and
+.Fn clock_nanosleep
+directly returns the error number.
.Bl -tag -width Er
.It Bq Er EFAULT
Either
@@ -85,27 +139,21 @@
points to memory that is not a valid part of the process
address space.
.It Bq Er EINTR
-The
-.Fn nanosleep
-system call
-was interrupted by the delivery of a signal.
+The function was interrupted by the delivery of a signal.
.It Bq Er EINVAL
The
.Fa rqtp
-argument
-specified a nanosecond value less than zero
+argument specified a nanosecond value less than zero
or greater than or equal to 1000 million.
-.It Bq Er ENOSYS
-The
-.Fn nanosleep
-system call
-is not supported by this implementation.
+.It Bq Er ENOTSUP
+The clock specified in the
+.Fa clock_id
+argument is not supported.
.El
.Sh SEE ALSO
-.Xr sigsuspend 2 ,
+.Xr clock_gettime 2 ,
+.Xr sigaction 2 ,
.Xr sleep 3
.Sh STANDARDS
-The
-.Fn nanosleep
-system call conforms to
-.St -p1003.1b-93 .
+These functions conform to
+.St -p1003.1-2008 .
Index: lib/libc/sys/nanosleep.c
===================================================================
--- lib/libc/sys/nanosleep.c
+++ lib/libc/sys/nanosleep.c
@@ -1,10 +1,7 @@
/*
- * Copyright (c) 2014 The FreeBSD Foundation.
+ * Copyright (c) 2017 Eric van Gyzen
* All rights reserved.
*
- * Portions of this software were developed by Konstantin Belousov
- * under sponsorship from the FreeBSD Foundation.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -37,13 +34,16 @@
#include <time.h>
#include "libc_private.h"
-__weak_reference(__sys_nanosleep, __nanosleep);
+__weak_reference(__sys_clock_nanosleep, __clock_nanosleep);
-#pragma weak nanosleep
+#pragma weak clock_nanosleep
int
-nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
+clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
+ struct timespec *rmtp)
{
- return (((int (*)(const struct timespec *, struct timespec *))
- __libc_interposing[INTERPOS_nanosleep])(rqtp, rmtp));
+ return (((int (*)(clockid_t, int, const struct timespec *,
+ struct timespec *))
+ __libc_interposing[INTERPOS_clock_nanosleep])(clock_id, flags,
+ rqtp, rmtp));
}
Index: lib/libc/tests/sys/Makefile
===================================================================
--- lib/libc/tests/sys/Makefile
+++ lib/libc/tests/sys/Makefile
@@ -12,6 +12,7 @@
NETBSD_ATF_TESTS_C+= bind_test
NETBSD_ATF_TESTS_C+= chroot_test
NETBSD_ATF_TESTS_C+= clock_gettime_test
+NETBSD_ATF_TESTS_C+= clock_nanosleep_test
NETBSD_ATF_TESTS_C+= connect_test
NETBSD_ATF_TESTS_C+= dup_test
NETBSD_ATF_TESTS_C+= fsync_test
Index: lib/libthr/thread/thr_private.h
===================================================================
--- lib/libthr/thread/thr_private.h
+++ lib/libthr/thread/thr_private.h
@@ -865,6 +865,8 @@
/* #include <time.h> */
#ifdef _TIME_H_
+int __sys_clock_nanosleep(clockid_t, int, const struct timespec *,
+ struct timespec *);
int __sys_nanosleep(const struct timespec *, struct timespec *);
#endif
Index: lib/libthr/thread/thr_syscalls.c
===================================================================
--- lib/libthr/thread/thr_syscalls.c
+++ lib/libthr/thread/thr_syscalls.c
@@ -260,6 +260,22 @@
}
static int
+__thr_clock_nanosleep(clockid_t clock_id, int flags,
+ const struct timespec *time_to_sleep, struct timespec *time_remaining)
+{
+ struct pthread *curthread;
+ int ret;
+
+ curthread = _get_curthread();
+ _thr_cancel_enter(curthread);
+ ret = __sys_clock_nanosleep(clock_id, flags, time_to_sleep,
+ time_remaining);
+ _thr_cancel_leave(curthread, 1);
+
+ return (ret);
+}
+
+static int
__thr_nanosleep(const struct timespec *time_to_sleep,
struct timespec *time_remaining)
{
@@ -668,6 +684,7 @@
SLOT(ppoll);
SLOT(map_stacks_exec);
SLOT(fdatasync);
+ SLOT(clock_nanosleep);
#undef SLOT
*(__libc_interposing_slot(
INTERPOS__pthread_mutex_init_calloc_cb)) =
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -2226,6 +2226,20 @@
int
freebsd32_nanosleep(struct thread *td, struct freebsd32_nanosleep_args *uap)
{
+ struct freebsd32_clock_nanosleep_args cns_uap = {
+ .clock_id = CLOCK_REALTIME,
+ .flags = TIMER_RELTIME,
+ .rqtp = uap->rqtp,
+ .rmtp = uap->rmtp,
+ };
+
+ return (freebsd32_clock_nanosleep(td, &cns_uap));
+}
+
+int
+freebsd32_clock_nanosleep(struct thread *td,
+ struct freebsd32_clock_nanosleep_args *uap)
+{
struct timespec32 rmt32, rqt32;
struct timespec rmt, rqt;
int error;
Index: sys/compat/freebsd32/freebsd32_proto.h
===================================================================
--- sys/compat/freebsd32/freebsd32_proto.h
+++ sys/compat/freebsd32/freebsd32_proto.h
@@ -235,6 +235,12 @@
char rqtp_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * rqtp; char rqtp_r_[PADR_(const struct timespec32 *)];
char rmtp_l_[PADL_(struct timespec32 *)]; struct timespec32 * rmtp; char rmtp_r_[PADR_(struct timespec32 *)];
};
+struct freebsd32_clock_nanosleep_args {
+ char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char rqtp_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * rqtp; char rqtp_r_[PADR_(const struct timespec32 *)];
+ char rmtp_l_[PADL_(struct timespec32 *)]; struct timespec32 * rmtp; char rmtp_r_[PADR_(struct timespec32 *)];
+};
struct freebsd32_clock_getcpuclockid2_args {
char id1_l_[PADL_(uint32_t)]; uint32_t id1; char id1_r_[PADR_(uint32_t)];
char id2_l_[PADL_(uint32_t)]; uint32_t id2; char id2_r_[PADR_(uint32_t)];
@@ -727,6 +733,7 @@
int freebsd32_ktimer_settime(struct thread *, struct freebsd32_ktimer_settime_args *);
int freebsd32_ktimer_gettime(struct thread *, struct freebsd32_ktimer_gettime_args *);
int freebsd32_nanosleep(struct thread *, struct freebsd32_nanosleep_args *);
+int freebsd32_clock_nanosleep(struct thread *, struct freebsd32_clock_nanosleep_args *);
int freebsd32_clock_getcpuclockid2(struct thread *, struct freebsd32_clock_getcpuclockid2_args *);
int freebsd32_aio_read(struct thread *, struct freebsd32_aio_read_args *);
int freebsd32_aio_write(struct thread *, struct freebsd32_aio_write_args *);
@@ -1185,6 +1192,7 @@
#define FREEBSD32_SYS_AUE_freebsd32_ktimer_settime AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_ktimer_gettime AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_nanosleep AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_clock_nanosleep AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_clock_getcpuclockid2 AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_aio_read AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_aio_write AUE_NULL
Index: sys/compat/freebsd32/freebsd32_syscall.h
===================================================================
--- sys/compat/freebsd32/freebsd32_syscall.h
+++ sys/compat/freebsd32/freebsd32_syscall.h
@@ -214,6 +214,7 @@
#define FREEBSD32_SYS_ffclock_getcounter 241
#define FREEBSD32_SYS_ffclock_setestimate 242
#define FREEBSD32_SYS_ffclock_getestimate 243
+#define FREEBSD32_SYS_freebsd32_clock_nanosleep 244
#define FREEBSD32_SYS_freebsd32_clock_getcpuclockid2 247
#define FREEBSD32_SYS_minherit 250
#define FREEBSD32_SYS_rfork 251
Index: sys/compat/freebsd32/freebsd32_syscalls.c
===================================================================
--- sys/compat/freebsd32/freebsd32_syscalls.c
+++ sys/compat/freebsd32/freebsd32_syscalls.c
@@ -253,7 +253,7 @@
"ffclock_getcounter", /* 241 = ffclock_getcounter */
"ffclock_setestimate", /* 242 = ffclock_setestimate */
"ffclock_getestimate", /* 243 = ffclock_getestimate */
- "#244", /* 244 = nosys */
+ "freebsd32_clock_nanosleep", /* 244 = freebsd32_clock_nanosleep */
"#245", /* 245 = nosys */
"#246", /* 246 = nosys */
"freebsd32_clock_getcpuclockid2", /* 247 = freebsd32_clock_getcpuclockid2 */
Index: sys/compat/freebsd32/freebsd32_sysent.c
===================================================================
--- sys/compat/freebsd32/freebsd32_sysent.c
+++ sys/compat/freebsd32/freebsd32_sysent.c
@@ -296,7 +296,7 @@
{ AS(ffclock_getcounter_args), (sy_call_t *)sys_ffclock_getcounter, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = ffclock_getcounter */
{ AS(ffclock_setestimate_args), (sy_call_t *)sys_ffclock_setestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = ffclock_setestimate */
{ AS(ffclock_getestimate_args), (sy_call_t *)sys_ffclock_getestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = ffclock_getestimate */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 244 = nosys */
+ { AS(freebsd32_clock_nanosleep_args), (sy_call_t *)freebsd32_clock_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 244 = freebsd32_clock_nanosleep */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 245 = nosys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 246 = nosys */
{ AS(freebsd32_clock_getcpuclockid2_args), (sy_call_t *)freebsd32_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 247 = freebsd32_clock_getcpuclockid2 */
Index: sys/compat/freebsd32/freebsd32_systrace_args.c
===================================================================
--- sys/compat/freebsd32/freebsd32_systrace_args.c
+++ sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -1260,6 +1260,16 @@
*n_args = 1;
break;
}
+ /* freebsd32_clock_nanosleep */
+ case 244: {
+ struct freebsd32_clock_nanosleep_args *p = params;
+ iarg[0] = p->clock_id; /* clockid_t */
+ iarg[1] = p->flags; /* int */
+ uarg[2] = (intptr_t) p->rqtp; /* const struct timespec32 * */
+ uarg[3] = (intptr_t) p->rmtp; /* struct timespec32 * */
+ *n_args = 4;
+ break;
+ }
/* freebsd32_clock_getcpuclockid2 */
case 247: {
struct freebsd32_clock_getcpuclockid2_args *p = params;
@@ -5303,6 +5313,25 @@
break;
};
break;
+ /* freebsd32_clock_nanosleep */
+ case 244:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "userland const struct timespec32 *";
+ break;
+ case 3:
+ p = "userland struct timespec32 *";
+ break;
+ default:
+ break;
+ };
+ break;
/* freebsd32_clock_getcpuclockid2 */
case 247:
switch(ndx) {
@@ -9626,6 +9655,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* freebsd32_clock_nanosleep */
+ case 244:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* freebsd32_clock_getcpuclockid2 */
case 247:
if (ndx == 0 || ndx == 1)
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -462,7 +462,10 @@
struct ffclock_estimate *cest); }
243 AUE_NULL NOPROTO { int ffclock_getestimate( \
struct ffclock_estimate *cest); }
-244 AUE_NULL UNIMPL nosys
+244 AUE_NULL STD { int freebsd32_clock_nanosleep( \
+ clockid_t clock_id, int flags, \
+ const struct timespec32 *rqtp, \
+ struct timespec32 *rmtp); }
245 AUE_NULL UNIMPL nosys
246 AUE_NULL UNIMPL nosys
247 AUE_NULL STD { int freebsd32_clock_getcpuclockid2(\
Index: sys/kern/init_sysent.c
===================================================================
--- sys/kern/init_sysent.c
+++ sys/kern/init_sysent.c
@@ -289,7 +289,7 @@
{ AS(ffclock_getcounter_args), (sy_call_t *)sys_ffclock_getcounter, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 241 = ffclock_getcounter */
{ AS(ffclock_setestimate_args), (sy_call_t *)sys_ffclock_setestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 242 = ffclock_setestimate */
{ AS(ffclock_getestimate_args), (sy_call_t *)sys_ffclock_getestimate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 243 = ffclock_getestimate */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 244 = nosys */
+ { AS(clock_nanosleep_args), (sy_call_t *)sys_clock_nanosleep, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 244 = clock_nanosleep */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 245 = nosys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 246 = nosys */
{ AS(clock_getcpuclockid2_args), (sy_call_t *)sys_clock_getcpuclockid2, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 247 = clock_getcpuclockid2 */
Index: sys/kern/kern_time.c
===================================================================
--- sys/kern/kern_time.c
+++ sys/kern/kern_time.c
@@ -481,47 +481,92 @@
return (0);
}
+int
+kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
+{
+ return (kern_clock_nanosleep(td, CLOCK_REALTIME, TIMER_RELTIME, rqt,
+ rmt));
+}
+
static uint8_t nanowait[MAXCPU];
int
-kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt)
+kern_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags,
+ const struct timespec *rqt, struct timespec *rmt)
{
- struct timespec ts;
+ struct timespec ts, now;
sbintime_t sbt, sbtt, prec, tmp;
time_t over;
int error;
+ bool is_abs_real;
if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000)
return (EINVAL);
- if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0))
- return (0);
- ts = *rqt;
- if (ts.tv_sec > INT32_MAX / 2) {
- over = ts.tv_sec - INT32_MAX / 2;
- ts.tv_sec -= over;
- } else
- over = 0;
- tmp = tstosbt(ts);
- prec = tmp;
- prec >>= tc_precexp;
- if (TIMESEL(&sbt, tmp))
- sbt += tc_tick_sbt;
- sbt += tmp;
- error = tsleep_sbt(&nanowait[curcpu], PWAIT | PCATCH, "nanslp",
- sbt, prec, C_ABSOLUTE);
+ switch (clock_id) {
+ case CLOCK_REALTIME:
+ case CLOCK_REALTIME_PRECISE:
+ case CLOCK_REALTIME_FAST:
+ case CLOCK_SECOND:
+ is_abs_real = (flags & TIMER_ABSTIME) != 0;
+ break;
+ case CLOCK_MONOTONIC:
+ case CLOCK_MONOTONIC_PRECISE:
+ case CLOCK_MONOTONIC_FAST:
+ case CLOCK_UPTIME:
+ case CLOCK_UPTIME_PRECISE:
+ case CLOCK_UPTIME_FAST:
+ is_abs_real = false;
+ break;
+ case CLOCK_VIRTUAL:
+ case CLOCK_PROF:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ return (ENOTSUP);
+ case CLOCK_THREAD_CPUTIME_ID:
+ default:
+ return (EINVAL);
+ }
+ do {
+ ts = *rqt;
+ if (flags & TIMER_ABSTIME) {
+ if (is_abs_real)
+ td->td_rtcgen =
+ atomic_load_acq_int(&rtc_generation);
+ error = kern_clock_gettime(td, clock_id, &now);
+ KASSERT(error == 0, ("kern_clock_gettime: %d", error));
+ timespecsub(&ts, &now);
+ }
+ if (ts.tv_sec < 0 || (ts.tv_sec == 0 && ts.tv_nsec == 0)) {
+ error = EWOULDBLOCK;
+ break;
+ }
+ if (ts.tv_sec > INT32_MAX / 2) {
+ over = ts.tv_sec - INT32_MAX / 2;
+ ts.tv_sec -= over;
+ } else
+ over = 0;
+ tmp = tstosbt(ts);
+ prec = tmp;
+ prec >>= tc_precexp;
+ if (TIMESEL(&sbt, tmp))
+ sbt += tc_tick_sbt;
+ sbt += tmp;
+ error = tsleep_sbt(&nanowait[curcpu], PWAIT | PCATCH, "nanslp",
+ sbt, prec, C_ABSOLUTE);
+ } while (error == 0 && is_abs_real && td->td_rtcgen == 0);
+ td->td_rtcgen = 0;
if (error != EWOULDBLOCK) {
+ TIMESEL(&sbtt, tmp);
+ if (sbtt >= sbt)
+ return (0);
if (error == ERESTART)
error = EINTR;
- TIMESEL(&sbtt, tmp);
- if (rmt != NULL) {
+ if ((flags & TIMER_ABSTIME) == 0 && rmt != NULL) {
ts = sbttots(sbt - sbtt);
ts.tv_sec += over;
if (ts.tv_sec < 0)
timespecclear(&ts);
*rmt = ts;
}
- if (sbtt >= sbt)
- return (0);
return (error);
}
return (0);
@@ -537,17 +582,45 @@
int
sys_nanosleep(struct thread *td, struct nanosleep_args *uap)
{
+ int error;
+ struct clock_nanosleep_args cns_uap = {
+ .clock_id = CLOCK_REALTIME,
+ .flags = TIMER_RELTIME,
+ .rqtp = uap->rqtp,
+ .rmtp = uap->rmtp,
+ };
+
+ (void)sys_clock_nanosleep(td, &cns_uap);
+ error = td->td_retval[0];
+ td->td_retval[0] = 0;
+ return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
+struct clock_nanosleep_args {
+ clockid_t clock_id;
+ int flags;
+ struct timespec *rqtp;
+ struct timespec *rmtp;
+};
+#endif
+/* ARGSUSED */
+int
+sys_clock_nanosleep(struct thread *td, struct clock_nanosleep_args *uap)
+{
struct timespec rmt, rqt;
int error;
error = copyin(uap->rqtp, &rqt, sizeof(rqt));
if (error)
- return (error);
+ goto done;
- if (uap->rmtp &&
- !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE))
- return (EFAULT);
- error = kern_nanosleep(td, &rqt, &rmt);
+ if (uap->rmtp && (uap->flags & TIMER_ABSTIME) == 0 &&
+ !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) {
+ error = EFAULT;
+ goto done;
+ }
+ error = kern_clock_nanosleep(td, uap->clock_id, uap->flags, &rqt, &rmt);
if (error && uap->rmtp) {
int error2;
@@ -555,7 +628,9 @@
if (error2)
error = error2;
}
- return (error);
+done:
+ td->td_retval[0] = error;
+ return (0);
}
#ifndef _SYS_SYSPROTO_H_
Index: sys/kern/syscalls.c
===================================================================
--- sys/kern/syscalls.c
+++ sys/kern/syscalls.c
@@ -250,7 +250,7 @@
"ffclock_getcounter", /* 241 = ffclock_getcounter */
"ffclock_setestimate", /* 242 = ffclock_setestimate */
"ffclock_getestimate", /* 243 = ffclock_getestimate */
- "#244", /* 244 = nosys */
+ "clock_nanosleep", /* 244 = clock_nanosleep */
"#245", /* 245 = nosys */
"#246", /* 246 = nosys */
"clock_getcpuclockid2", /* 247 = clock_getcpuclockid2 */
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -461,7 +461,9 @@
struct ffclock_estimate *cest); }
243 AUE_NULL STD { int ffclock_getestimate( \
struct ffclock_estimate *cest); }
-244 AUE_NULL UNIMPL nosys
+244 AUE_NULL STD { int clock_nanosleep(clockid_t clock_id, \
+ int flags, const struct timespec *rqtp, \
+ struct timespec *rmtp); }
245 AUE_NULL UNIMPL nosys
246 AUE_NULL UNIMPL nosys
247 AUE_NULL STD { int clock_getcpuclockid2(id_t id,\
Index: sys/kern/systrace_args.c
===================================================================
--- sys/kern/systrace_args.c
+++ sys/kern/systrace_args.c
@@ -1290,6 +1290,16 @@
*n_args = 1;
break;
}
+ /* clock_nanosleep */
+ case 244: {
+ struct clock_nanosleep_args *p = params;
+ iarg[0] = p->clock_id; /* clockid_t */
+ iarg[1] = p->flags; /* int */
+ uarg[2] = (intptr_t) p->rqtp; /* const struct timespec * */
+ uarg[3] = (intptr_t) p->rmtp; /* struct timespec * */
+ *n_args = 4;
+ break;
+ }
/* clock_getcpuclockid2 */
case 247: {
struct clock_getcpuclockid2_args *p = params;
@@ -5365,6 +5375,25 @@
break;
};
break;
+ /* clock_nanosleep */
+ case 244:
+ switch(ndx) {
+ case 0:
+ p = "clockid_t";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "userland const struct timespec *";
+ break;
+ case 3:
+ p = "userland struct timespec *";
+ break;
+ default:
+ break;
+ };
+ break;
/* clock_getcpuclockid2 */
case 247:
switch(ndx) {
@@ -9603,6 +9632,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* clock_nanosleep */
+ case 244:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* clock_getcpuclockid2 */
case 247:
if (ndx == 0 || ndx == 1)
Index: sys/sys/syscall.h
===================================================================
--- sys/sys/syscall.h
+++ sys/sys/syscall.h
@@ -218,6 +218,7 @@
#define SYS_ffclock_getcounter 241
#define SYS_ffclock_setestimate 242
#define SYS_ffclock_getestimate 243
+#define SYS_clock_nanosleep 244
#define SYS_clock_getcpuclockid2 247
#define SYS_ntp_gettime 248
#define SYS_minherit 250
Index: sys/sys/syscall.mk
===================================================================
--- sys/sys/syscall.mk
+++ sys/sys/syscall.mk
@@ -158,6 +158,7 @@
ffclock_getcounter.o \
ffclock_setestimate.o \
ffclock_getestimate.o \
+ clock_nanosleep.o \
clock_getcpuclockid2.o \
ntp_gettime.o \
minherit.o \
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -82,6 +82,8 @@
struct timespec *ts);
int kern_clock_gettime(struct thread *td, clockid_t clock_id,
struct timespec *ats);
+int kern_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags,
+ const struct timespec *rqtp, struct timespec *rmtp);
int kern_clock_settime(struct thread *td, clockid_t clock_id,
struct timespec *ats);
int kern_close(struct thread *td, int fd);
Index: sys/sys/sysproto.h
===================================================================
--- sys/sys/sysproto.h
+++ sys/sys/sysproto.h
@@ -697,6 +697,12 @@
struct ffclock_getestimate_args {
char cest_l_[PADL_(struct ffclock_estimate *)]; struct ffclock_estimate * cest; char cest_r_[PADR_(struct ffclock_estimate *)];
};
+struct clock_nanosleep_args {
+ char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)];
+ char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
+ char rqtp_l_[PADL_(const struct timespec *)]; const struct timespec * rqtp; char rqtp_r_[PADR_(const struct timespec *)];
+ char rmtp_l_[PADL_(struct timespec *)]; struct timespec * rmtp; char rmtp_r_[PADR_(struct timespec *)];
+};
struct clock_getcpuclockid2_args {
char id_l_[PADL_(id_t)]; id_t id; char id_r_[PADR_(id_t)];
char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)];
@@ -1936,6 +1942,7 @@
int sys_ffclock_getcounter(struct thread *, struct ffclock_getcounter_args *);
int sys_ffclock_setestimate(struct thread *, struct ffclock_setestimate_args *);
int sys_ffclock_getestimate(struct thread *, struct ffclock_getestimate_args *);
+int sys_clock_nanosleep(struct thread *, struct clock_nanosleep_args *);
int sys_clock_getcpuclockid2(struct thread *, struct clock_getcpuclockid2_args *);
int sys_ntp_gettime(struct thread *, struct ntp_gettime_args *);
int sys_minherit(struct thread *, struct minherit_args *);
@@ -2706,6 +2713,7 @@
#define SYS_AUE_ffclock_getcounter AUE_NULL
#define SYS_AUE_ffclock_setestimate AUE_NULL
#define SYS_AUE_ffclock_getestimate AUE_NULL
+#define SYS_AUE_clock_nanosleep AUE_NULL
#define SYS_AUE_clock_getcpuclockid2 AUE_NULL
#define SYS_AUE_ntp_gettime AUE_NULL
#define SYS_AUE_minherit AUE_MINHERIT
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Oct 11, 10:16 AM (18 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23573044
Default Alt Text
D10020.id26292.diff (29 KB)
Attached To
Mode
D10020: Add clock_nanosleep()
Attached
Detach File
Event Timeline
Log In to Comment