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();
+}