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