svn commit: r316426 - head/sys/compat/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun Apr 2 18:16:01 UTC 2017
Author: dchagin
Date: Sun Apr 2 18:16:00 2017
New Revision: 316426
URL: https://svnweb.freebsd.org/changeset/base/316426
Log:
Use the kern_clock_nanosleep() to implement Linux clock_nanosleep() with
the proper handling of the TIMER_ABSTIME flag.
XMFC after: r315526
MFC after: 1 month
Modified:
head/sys/compat/linux/linux_time.c
head/sys/compat/linux/linux_timer.h
Modified: head/sys/compat/linux/linux_time.c
==============================================================================
--- head/sys/compat/linux/linux_time.c Sun Apr 2 17:34:45 2017 (r316425)
+++ head/sys/compat/linux/linux_time.c Sun Apr 2 18:16:00 2017 (r316426)
@@ -229,6 +229,18 @@ linux_to_native_clockid(clockid_t *n, cl
}
int
+linux_to_native_timerflags(int *nflags, int flags)
+{
+
+ if (flags & ~LINUX_TIMER_ABSTIME)
+ return (EINVAL);
+ *nflags = 0;
+ if (flags & LINUX_TIMER_ABSTIME)
+ *nflags |= TIMER_ABSTIME;
+ return (0);
+}
+
+int
linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
{
struct l_timespec lts;
@@ -541,24 +553,26 @@ linux_clock_nanosleep(struct thread *td,
struct timespec *rmtp;
struct l_timespec lrqts, lrmts;
struct timespec rqts, rmts;
- int error, error2;
+ int error, error2, flags;
+ clockid_t clockid;
LIN_SDT_PROBE4(time, linux_clock_nanosleep, entry, args->which,
args->flags, args->rqtp, args->rmtp);
- if (args->flags != 0) {
- /* XXX deal with TIMER_ABSTIME */
+ error = linux_to_native_timerflags(&flags, args->flags);
+ if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_flags,
args->flags);
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
- return (EINVAL); /* XXX deal with TIMER_ABSTIME */
+ LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
+ return (error);
}
- if (args->which != LINUX_CLOCK_REALTIME) {
+ error = linux_to_native_clockid(&clockid, args->which);
+ if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_nanosleep, unsupported_clockid,
args->which);
- LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, EINVAL);
- return (EINVAL);
+ LIN_SDT_PROBE1(time, linux_clock_settime, return, error);
+ return (error);
}
error = copyin(args->rqtp, &lrqts, sizeof(lrqts));
@@ -581,9 +595,9 @@ linux_clock_nanosleep(struct thread *td,
LIN_SDT_PROBE1(time, linux_clock_nanosleep, return, error);
return (error);
}
- error = kern_nanosleep(td, &rqts, rmtp);
- if (error == EINTR && args->rmtp != NULL) {
- /* XXX. Not for TIMER_ABSTIME */
+ error = kern_clock_nanosleep(td, clockid, flags, &rqts, rmtp);
+ if (error == EINTR && (flags & TIMER_ABSTIME) == 0 &&
+ args->rmtp != NULL) {
error2 = native_to_linux_timespec(&lrmts, rmtp);
if (error2 != 0)
return (error2);
Modified: head/sys/compat/linux/linux_timer.h
==============================================================================
--- head/sys/compat/linux/linux_timer.h Sun Apr 2 17:34:45 2017 (r316425)
+++ head/sys/compat/linux/linux_timer.h Sun Apr 2 18:16:00 2017 (r316426)
@@ -72,6 +72,7 @@
#define LINUX_CPUCLOCK_PERTHREAD(clock) \
(((clock) & (clockid_t) LINUX_CPUCLOCK_PERTHREAD_MASK) != 0)
+#define LINUX_TIMER_ABSTIME 0x01
#define L_SIGEV_SIGNAL 0
#define L_SIGEV_NONE 1
@@ -120,5 +121,6 @@ int native_to_linux_itimerspec(struct l_
struct itimerspec *);
int linux_to_native_itimerspec(struct itimerspec *,
struct l_itimerspec *);
+int linux_to_native_timerflags(int *, int);
#endif /* _LINUX_TIMER_H */
More information about the svn-src-all
mailing list