Author: bdrewery
Date: Sun Mar  4 23:31:25 2018
New Revision: 330422
URL: https://svnweb.freebsd.org/changeset/base/330422

Log:
  MFC r329271:
  
    nanosleep(2): Fix bogus incrementing of rmtp by tc_tick_sbt on [EINTR].

Modified:
  stable/10/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
  stable/10/sys/kern/kern_time.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
==============================================================================
--- stable/10/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c   Sun Mar  4 
23:28:42 2018        (r330421)
+++ stable/10/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c   Sun Mar  4 
23:31:25 2018        (r330422)
@@ -50,6 +50,15 @@ handler(int signo __unused)
        /* Nothing. */
 }
 
+static int got_info;
+static void
+info_handler(int signo __unused)
+{
+
+       got_info = 1;
+}
+
+
 ATF_TC(nanosleep_basic);
 ATF_TC_HEAD(nanosleep_basic, tc)
 {
@@ -176,12 +185,84 @@ ATF_TC_BODY(nanosleep_sig, tc)
                atf_tc_fail("signal did not interrupt nanosleep(2)");
 }
 
+ATF_TC(nanosleep_eintr);
+ATF_TC_HEAD(nanosleep_eintr, tc)
+{
+       atf_tc_set_md_var(tc, "descr", "Test [EINTR] for nanosleep(2)");
+       atf_tc_set_md_var(tc, "timeout", "7");
+}
+
+ATF_TC_BODY(nanosleep_eintr, tc)
+{
+       struct sigaction act;
+       struct timespec tso, ts;
+       pid_t pid;
+       int sta;
+
+       /*
+        * Test that [EINTR] properly handles rmtp for nanosleep(2).
+        */
+       pid = fork();
+
+       ATF_REQUIRE(pid >= 0);
+
+       got_info = 0;
+
+       if (pid == 0) {
+               act.sa_handler = info_handler;
+               sigemptyset(&act.sa_mask);
+               act.sa_flags = 0; /* Don't allow restart. */
+               ATF_REQUIRE(sigaction(SIGINFO, &act, NULL) == 0);
+
+               tso.tv_sec = 5;
+               tso.tv_nsec = 0;
+
+               ts.tv_sec = tso.tv_sec;
+               ts.tv_nsec = tso.tv_nsec;
+
+               errno = 0;
+               while (nanosleep(&ts, &ts) != 0) {
+                       ATF_REQUIRE_MSG(timespeccmp(&ts, &tso, <=),
+                           "errno=%d ts=%0.9f should be <= last tso=%0.9f\n",
+                           errno,
+                           ts.tv_sec + ts.tv_nsec / 1e9,
+                           tso.tv_sec + tso.tv_nsec / 1e9);
+                       if (errno == EINTR && got_info == 1) {
+                               got_info = 0;
+                               errno = 0;
+                               tso.tv_sec = ts.tv_sec;
+                               tso.tv_nsec = ts.tv_nsec;
+                               continue;
+                       }
+                       _exit(EXIT_FAILURE);
+               }
+
+               if (errno != 0)
+                       _exit(EXIT_FAILURE);
+
+               _exit(EXIT_SUCCESS);
+       }
+
+       /* Flood the process with SIGINFO until it exits. */
+       do {
+               for (int i = 0; i < 10; i++)
+                       ATF_REQUIRE(kill(pid, SIGINFO) == 0);
+               ATF_REQUIRE(usleep(10000) == 0);
+       } while (waitpid(pid, &sta, WNOHANG) == 0);
+
+       ATF_REQUIRE(WIFEXITED(sta) == 1);
+
+       if (WEXITSTATUS(sta) != EXIT_SUCCESS)
+               atf_tc_fail("nanosleep(2) handled rtmp incorrectly");
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
        ATF_TP_ADD_TC(tp, nanosleep_basic);
        ATF_TP_ADD_TC(tp, nanosleep_err);
        ATF_TP_ADD_TC(tp, nanosleep_sig);
+       ATF_TP_ADD_TC(tp, nanosleep_eintr);
 
        return atf_no_error();
 }

Modified: stable/10/sys/kern/kern_time.c
==============================================================================
--- stable/10/sys/kern/kern_time.c      Sun Mar  4 23:28:42 2018        
(r330421)
+++ stable/10/sys/kern/kern_time.c      Sun Mar  4 23:31:25 2018        
(r330422)
@@ -510,7 +510,8 @@ kern_nanosleep(struct thread *td, struct timespec *rqt
        if (error != EWOULDBLOCK) {
                if (error == ERESTART)
                        error = EINTR;
-               TIMESEL(&sbtt, tmp);
+               if (TIMESEL(&sbtt, tmp))
+                       sbtt += tc_tick_sbt;
                if (rmt != NULL) {
                        ts = sbttots(sbt - sbtt);
                        ts.tv_sec += over;
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to