[PATCH] posix/src/nanosleep.c: Address issue when delay is longer than desired

Joel Sherrill joel.sherrill at oarcorp.com
Wed Mar 11 21:20:30 UTC 2015


This resulted in the elapsed time going below 0 and an arbitrarily large
number returned as the time remaining.

closes #2296.
---
 cpukit/posix/src/nanosleep.c | 43 +++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
index 1fbeaa3..39ae84d 100644
--- a/cpukit/posix/src/nanosleep.c
+++ b/cpukit/posix/src/nanosleep.c
@@ -1,12 +1,12 @@
 /**
  * @file
  *
- * @brief Suspends Execution of calling thread until Time elaps
+ * @brief Suspends Execution of calling thread until Time elapses
  * @ingroup POSIXAPI
  */
 
 /*
- *  COPYRIGHT (c) 1989-2007.
+ *  COPYRIGHT (c) 1989-2015.
  *  On-Line Applications Research Corporation (OAR).
  *
  *  The license and distribution terms for this file may be
@@ -29,7 +29,6 @@
 /*
  *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
  */
-
 int nanosleep(
   const struct timespec  *rqtp,
   struct timespec        *rmtp
@@ -42,6 +41,7 @@ int nanosleep(
   Thread_Control *executing;
 
   Watchdog_Interval  ticks;
+  Watchdog_Interval  elapsed;
 
 
   /*
@@ -53,6 +53,9 @@ int nanosleep(
   if ( !_Timespec_Is_valid( rqtp ) )
     rtems_set_errno_and_return_minus_one( EINVAL );
 
+  /*
+   * Convert the timespec delay into the appropriate number of clock ticks.
+   */
   ticks = _Timespec_To_ticks( rqtp );
 
   /*
@@ -60,7 +63,6 @@ int nanosleep(
    *  This behavior is also beyond the POSIX specification but is
    *  consistent with the RTEMS API and yields desirable behavior.
    */
-
   if ( !ticks ) {
     _Thread_Disable_dispatch();
       executing = _Thread_Executing;
@@ -91,24 +93,33 @@ int nanosleep(
     _Watchdog_Insert_ticks( &executing->Timer, ticks );
   _Thread_Enable_dispatch();
 
-  /* calculate time remaining */
+  /*
+   * Calculate the time that passed while we were sleeping and how
+   * much remains from what we requested.
+   */
+  elapsed = executing->Timer.stop_time - executing->Timer.start_time;
+  if ( elapsed >= ticks )
+    ticks = 0;
+  else
+    ticks -= elapsed;
 
+  /*
+   * If the user wants the time remaining, do the conversion.
+   */
   if ( rmtp ) {
-    ticks -= executing->Timer.stop_time - executing->Timer.start_time;
-
     _Timespec_From_ticks( ticks, rmtp );
+  }
 
+  /*
+   *  Only when POSIX is enabled, can a sleep be interrupted.
+   */
+  #if defined(RTEMS_POSIX_API)
     /*
-     *  Only when POSIX is enabled, can a sleep be interrupted.
+     *  If there is time remaining, then we were interrupted by a signal.
      */
-    #if defined(RTEMS_POSIX_API)
-        /*
-         *  If there is time remaining, then we were interrupted by a signal.
-         */
-        if ( ticks )
-          rtems_set_errno_and_return_minus_one( EINTR );
-    #endif
-  }
+    if ( ticks )
+      rtems_set_errno_and_return_minus_one( EINTR );
+  #endif
 
   return 0;
 }
-- 
1.9.3



More information about the devel mailing list