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