Author: dchagin
Date: Mon May  1 06:42:39 2017
New Revision: 317637
URL: https://svnweb.freebsd.org/changeset/base/317637

Log:
  MFC r316426:
  
  Use the kern_clock_nanosleep() to implement Linux clock_nanosleep() with
  the proper handling of the TIMER_ABSTIME flag.

Modified:
  stable/11/sys/compat/linux/linux_time.c
  stable/11/sys/compat/linux/linux_timer.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linux/linux_time.c
==============================================================================
--- stable/11/sys/compat/linux/linux_time.c     Mon May  1 06:05:04 2017        
(r317636)
+++ stable/11/sys/compat/linux/linux_time.c     Mon May  1 06:42:39 2017        
(r317637)
@@ -231,6 +231,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;
@@ -543,24 +555,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));
@@ -583,9 +597,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: stable/11/sys/compat/linux/linux_timer.h
==============================================================================
--- stable/11/sys/compat/linux/linux_timer.h    Mon May  1 06:05:04 2017        
(r317636)
+++ stable/11/sys/compat/linux/linux_timer.h    Mon May  1 06:42:39 2017        
(r317637)
@@ -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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to