Module Name:    src
Committed By:   christos
Date:           Fri Dec  8 01:19:30 UTC 2017

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/include: lwp.h
        src/lib/libc/sys: _lwp_park.2
        src/sys/kern: subr_time.c sys_lwp.c syscalls.master
        src/sys/sys: timevar.h
        src/tests/kernel: Makefile
Added Files:
        src/tests/kernel: t_timeleft.c

Log Message:
make _lwp_park return the remaining time to sleep in the "ts" argument
if it is a relative timestamp, as discussed in tech-kern.
XXX: pullup-8


To generate a diff of this commit:
cvs rdiff -u -r1.769 -r1.770 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.12 -r1.13 src/include/lwp.h
cvs rdiff -u -r1.9 -r1.10 src/lib/libc/sys/_lwp_park.2
cvs rdiff -u -r1.19 -r1.20 src/sys/kern/subr_time.c
cvs rdiff -u -r1.61 -r1.62 src/sys/kern/sys_lwp.c
cvs rdiff -u -r1.286 -r1.287 src/sys/kern/syscalls.master
cvs rdiff -u -r1.36 -r1.37 src/sys/sys/timevar.h
cvs rdiff -u -r1.48 -r1.49 src/tests/kernel/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/kernel/t_timeleft.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.769 src/distrib/sets/lists/tests/mi:1.770
--- src/distrib/sets/lists/tests/mi:1.769	Thu Dec  7 14:48:12 2017
+++ src/distrib/sets/lists/tests/mi	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.769 2017/12/07 19:48:12 christos Exp $
+# $NetBSD: mi,v 1.770 2017/12/08 01:19:29 christos Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -2179,6 +2179,7 @@
 ./usr/tests/kernel/t_ptrace_waitpid		tests-obsolete		obsolete
 ./usr/tests/kernel/t_pty			tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/t_rnd			tests-kernel-tests	atf,rump
+./usr/tests/kernel/t_timeleft			tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/t_trapsignal			tests-kernel-tests	compattestfile,atf
 ./usr/tests/kernel/t_sigaction			tests-obsolete		obsolete
 ./usr/tests/kernel/t_subr_prf			tests-kernel-tests	compattestfile,atf

Index: src/include/lwp.h
diff -u src/include/lwp.h:1.12 src/include/lwp.h:1.13
--- src/include/lwp.h:1.12	Fri Jan 31 15:44:17 2014
+++ src/include/lwp.h	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: lwp.h,v 1.12 2014/01/31 20:44:17 christos Exp $	*/
+/*	$NetBSD: lwp.h,v 1.13 2017/12/08 01:19:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -54,7 +54,7 @@ void	_lwp_setprivate(void *);
 int	_lwp_kill(lwpid_t, int);
 int	_lwp_detach(lwpid_t);
 #ifndef __LIBC12_SOURCE__
-int	_lwp_park(clockid_t, int, const struct timespec *, lwpid_t,
+int	_lwp_park(clockid_t, int, struct timespec *, lwpid_t,
     const void *, const void *) __RENAME(___lwp_park60);
 #endif
 int	_lwp_unpark(lwpid_t, const void *);

Index: src/lib/libc/sys/_lwp_park.2
diff -u src/lib/libc/sys/_lwp_park.2:1.9 src/lib/libc/sys/_lwp_park.2:1.10
--- src/lib/libc/sys/_lwp_park.2:1.9	Fri Jan 31 16:11:05 2014
+++ src/lib/libc/sys/_lwp_park.2	Thu Dec  7 20:19:29 2017
@@ -1,6 +1,6 @@
-.\"	$NetBSD: _lwp_park.2,v 1.9 2014/01/31 21:11:05 wiz Exp $
+.\"	$NetBSD: _lwp_park.2,v 1.10 2017/12/08 01:19:29 christos Exp $
 .\"
-.\" Copyright (c) 2003, 2007 The NetBSD Foundation, Inc.
+.\" Copyright (c) 2003, 2007, 2017 The NetBSD Foundation, Inc.
 .\" All rights reserved.
 .\"
 .\" This code is derived from software contributed to The NetBSD Foundation
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd March 28, 2013
+.Dd December 7, 2017
 .Dt _LWP_PARK 2
 .Os
 .Sh NAME
@@ -38,7 +38,7 @@
 .Sh SYNOPSIS
 .In lwp.h
 .Ft int
-.Fn _lwp_park "clockid_t clock_id" "int flags" "const struct timespec *ts" "lwpid_t unpark" "const void *hint" "const void *unparkhint"
+.Fn _lwp_park "clockid_t clock_id" "int flags" "struct timespec *ts" "lwpid_t unpark" "const void *hint" "const void *unparkhint"
 .Sh DESCRIPTION
 .Fn _lwp_park
 can be used to synchronize access to resources among multiple light-weight
@@ -58,14 +58,13 @@ time can be an relative interval to wait
 .Ar flags
 argument does not contain
 .Dv TIMER_ABSTIME
-or it can be an absolute time compared to
+or it can be an absolute time.
+The
+.Fa clock_id 
+argument contains the clock to be used; it can be:
 .Dv CLOCK_REALTIME
 or
-.Dv CLOCK_MONOTONIC
-depending on the value
-of the
-.Ar clock_id
-argument.
+.Dv CLOCK_MONOTONIC .
 .It
 The LWP receives a directed signal posted using
 .Fn _lwp_kill ,
@@ -82,6 +81,13 @@ or
 .Fn _lwp_unpark_all .
 .El
 .Pp
+If the
+.Fa ts
+argument contains a relative time interval, it will be modified to contain
+the remaining time to sleep when
+.Fn _lwp_park
+returns.
+.Pp
 The preferred method to awaken an LWP sleeping as a result of a call
 to
 .Fn _lwp_park

Index: src/sys/kern/subr_time.c
diff -u src/sys/kern/subr_time.c:1.19 src/sys/kern/subr_time.c:1.20
--- src/sys/kern/subr_time.c:1.19	Thu Jan  5 18:29:14 2017
+++ src/sys/kern/subr_time.c	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: subr_time.c,v 1.19 2017/01/05 23:29:14 pgoyette Exp $	*/
+/*	$NetBSD: subr_time.c,v 1.20 2017/12/08 01:19:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.19 2017/01/05 23:29:14 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.20 2017/12/08 01:19:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -227,6 +227,17 @@ gettimeleft(struct timespec *ts, struct 
 	return tstohz(ts);
 }
 
+void
+clock_timeleft(clockid_t clockid, struct timespec *ts, struct timespec *sleepts)
+{
+	struct timespec sleptts;
+
+	clock_gettime1(clockid, &sleptts);
+	timespecadd(ts, sleepts, ts);
+	timespecsub(ts, &sleptts, ts);
+	*sleepts = sleptts;
+}
+
 static void
 ticks2ts(uint64_t ticks, struct timespec *ts)
 {

Index: src/sys/kern/sys_lwp.c
diff -u src/sys/kern/sys_lwp.c:1.61 src/sys/kern/sys_lwp.c:1.62
--- src/sys/kern/sys_lwp.c:1.61	Wed May 31 22:45:13 2017
+++ src/sys/kern/sys_lwp.c	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys_lwp.c,v 1.61 2017/06/01 02:45:13 chs Exp $	*/
+/*	$NetBSD: sys_lwp.c,v 1.62 2017/12/08 01:19:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.61 2017/06/01 02:45:13 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_lwp.c,v 1.62 2017/12/08 01:19:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -542,10 +542,13 @@ lwp_park(clockid_t clock_id, int flags, 
 	kmutex_t *mp;
 	wchan_t wchan;
 	int timo, error;
+	struct timespec start;
 	lwp_t *l;
+	bool timeremain = !(flags & TIMER_ABSTIME) && ts;
 
 	if (ts != NULL) {
-		if ((error = ts2timo(clock_id, flags, ts, &timo, NULL)) != 0)
+		if ((error = ts2timo(clock_id, flags, ts, &timo, 
+		    timeremain ? &start : NULL)) != 0)
 			return error;
 		KASSERT(timo != 0);
 	} else {
@@ -575,12 +578,15 @@ lwp_park(clockid_t clock_id, int flags, 
 	switch (error) {
 	case EWOULDBLOCK:
 		error = ETIMEDOUT;
+		if (timeremain)
+			memset(ts, 0, sizeof(*ts));
 		break;
 	case ERESTART:
 		error = EINTR;
-		break;
+		/*FALLTHROUGH*/
 	default:
-		/* nothing */
+		if (timeremain)
+			clock_timeleft(clock_id, ts, &start);
 		break;
 	}
 	return error;
@@ -598,7 +604,7 @@ sys____lwp_park60(struct lwp *l, const s
 	/* {
 		syscallarg(clockid_t)			clock_id;
 		syscallarg(int)				flags;
-		syscallarg(const struct timespec *)	ts;
+		syscallarg(struct timespec *)		ts;
 		syscallarg(lwpid_t)			unpark;
 		syscallarg(const void *)		hint;
 		syscallarg(const void *)		unparkhint;
@@ -621,8 +627,11 @@ sys____lwp_park60(struct lwp *l, const s
 			return error;
 	}
 
-	return lwp_park(SCARG(uap, clock_id), SCARG(uap, flags), tsp,
+	error = lwp_park(SCARG(uap, clock_id), SCARG(uap, flags), tsp,
 	    SCARG(uap, hint));
+	if (SCARG(uap, ts) != NULL && (SCARG(uap, flags) & TIMER_ABSTIME) == 0)
+		(void)copyout(tsp, SCARG(uap, ts), sizeof(*tsp));
+	return error;
 }
 
 int

Index: src/sys/kern/syscalls.master
diff -u src/sys/kern/syscalls.master:1.286 src/sys/kern/syscalls.master:1.287
--- src/sys/kern/syscalls.master:1.286	Tue Nov  1 20:11:59 2016
+++ src/sys/kern/syscalls.master	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-	$NetBSD: syscalls.master,v 1.286 2016/11/02 00:11:59 pgoyette Exp $
+	$NetBSD: syscalls.master,v 1.287 2017/12/08 01:19:29 christos Exp $
 
 ;	@(#)syscalls.master	8.2 (Berkeley) 1/13/94
 
@@ -975,7 +975,7 @@
 			    int flags, const struct timespec *rqtp, \
 			    struct timespec *rmtp); }
 478	STD 		{ int|sys|60|_lwp_park(clockid_t clock_id, int flags, \
-			    const struct timespec *ts, lwpid_t unpark, \
+			    struct timespec *ts, lwpid_t unpark, \
 			    const void *hint, const void *unparkhint); }
 479	NOERR	RUMP	{ int|sys||posix_fallocate(int fd, int PAD, off_t pos, \
 			    off_t len); }

Index: src/sys/sys/timevar.h
diff -u src/sys/sys/timevar.h:1.36 src/sys/sys/timevar.h:1.37
--- src/sys/sys/timevar.h:1.36	Tue Mar  8 00:02:55 2016
+++ src/sys/sys/timevar.h	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: timevar.h,v 1.36 2016/03/08 05:02:55 christos Exp $	*/
+/*	$NetBSD: timevar.h,v 1.37 2017/12/08 01:19:29 christos Exp $	*/
 
 /*
  *  Copyright (c) 2005, 2008 The NetBSD Foundation.
@@ -151,6 +151,7 @@ void	adjtime1(const struct timeval *, st
 int	clock_getres1(clockid_t, struct timespec *);
 int	clock_gettime1(clockid_t, struct timespec *);
 int	clock_settime1(struct proc *, clockid_t, const struct timespec *, bool);
+void	clock_timeleft(clockid_t, struct timespec *, struct timespec *);
 int	dogetitimer(struct proc *, int, struct itimerval *);
 int	dosetitimer(struct proc *, int, struct itimerval *);
 int	dotimer_gettime(int, struct proc *, struct itimerspec *);

Index: src/tests/kernel/Makefile
diff -u src/tests/kernel/Makefile:1.48 src/tests/kernel/Makefile:1.49
--- src/tests/kernel/Makefile:1.48	Thu Dec  7 14:46:40 2017
+++ src/tests/kernel/Makefile	Thu Dec  7 20:19:29 2017
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.48 2017/12/07 19:46:40 christos Exp $
+# $NetBSD: Makefile,v 1.49 2017/12/08 01:19:29 christos Exp $
 
 NOMAN=		# defined
 
@@ -15,6 +15,7 @@ TESTS_C+=	t_sysv
 TESTS_C+=	t_subr_prf
 TESTS_C+=	t_kauth_pr_47598
 TESTS_C+=	t_sysctl
+TESTS_C+=	t_timeleft
 
 TESTS_SH=	t_umount
 TESTS_SH+=	t_umountstress
@@ -41,6 +42,7 @@ LDADD.t_extattrctl+= -lrump -lpthread
 LDADD.t_filedesc+=  ${LDADD.t_rnd}
 LDADD.t_rnd+=  -lrumpvfs -lrumpdev_rnd -lrumpdev -lrump -lrumpuser
 LDADD.t_rnd+=  -lrump -lpthread
+LDADD.t_timeleft+=	-lpthread
 
 .endif
 

Added files:

Index: src/tests/kernel/t_timeleft.c
diff -u /dev/null src/tests/kernel/t_timeleft.c:1.1
--- /dev/null	Thu Dec  7 20:19:30 2017
+++ src/tests/kernel/t_timeleft.c	Thu Dec  7 20:19:29 2017
@@ -0,0 +1,136 @@
+/* $NetBSD: t_timeleft.c,v 1.1 2017/12/08 01:19:29 christos Exp $ */
+
+/*-
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_timeleft.c,v 1.1 2017/12/08 01:19:29 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/select.h>
+
+#include <atf-c.h>
+#include <time.h>
+#include <errno.h>
+#include <lwp.h>
+#include <signal.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+
+static void
+sighandler(int signo __unused)
+{
+}
+
+struct info {
+	void (*fun)(struct timespec *);
+	struct timespec ts;
+};
+
+static void
+timeleft__lwp_park(struct timespec *ts)
+{
+	ATF_REQUIRE_ERRNO(EINTR, _lwp_park(CLOCK_MONOTONIC, TIMER_RELTIME,
+	    ts, 0, ts, NULL) == -1);
+}
+
+#if 0
+static void
+timeleft_pselect(struct timespec *ts)
+{
+	ATF_REQUIRE_ERRNO(EINTR, pselect(1, NULL, NULL, NULL, ts, NULL));
+}
+#endif
+
+static void *
+runner(void *arg)
+{
+	struct info *i = arg;
+	(*i->fun)(&i->ts);
+	return NULL;
+}
+
+static void
+tester(void (*fun)(struct timespec *))
+{
+	const struct timespec ts = { 5, 0 };
+	const struct timespec sts = { 0, 1000000 };
+	struct info i = { fun, ts };
+	pthread_t thr;
+
+	ATF_REQUIRE(signal(SIGINT, sighandler) == 0);
+	ATF_REQUIRE(pthread_create(&thr, NULL, runner, &i) == 0);
+
+	nanosleep(&sts, NULL);
+	pthread_kill(thr, SIGINT);
+	printf("Orig time %ju.%lu\n", (intmax_t)ts.tv_sec, ts.tv_nsec);
+	printf("Time left %ju.%lu\n", (intmax_t)i.ts.tv_sec, i.ts.tv_nsec);
+	ATF_REQUIRE(timespeccmp(&i.ts, &ts, <));
+}
+
+ATF_TC(timeleft__lwp_park);
+ATF_TC_HEAD(timeleft__lwp_park, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Checks that _lwp_park(2) returns "
+	    "the time left to sleep after interrupted");
+}
+
+ATF_TC_BODY(timeleft__lwp_park, tc)
+{
+	tester(timeleft__lwp_park);
+}
+
+#if 0
+ATF_TC(timeleft_pselect);
+ATF_TC_HEAD(timeleft_pselect, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Checks that pselect(2) returns "
+	    "the time left to sleep after interrupted");
+}
+
+ATF_TC_BODY(timeleft_pselect, tc)
+{
+	tester(timeleft_pselect);
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+	ATF_TP_ADD_TC(tp, timeleft__lwp_park);
+#if 0
+	ATF_TP_ADD_TC(tp, timeleft_pselect);
+#endif
+
+	return atf_no_error();
+}

Reply via email to