[PATCH 36/45] score: Replace _Thread_Delay_ended()

Sebastian Huber sebastian.huber at embedded-brains.de
Fri May 15 11:41:36 UTC 2015


Use _Thread_Timeout() instead.  Use pseudo thread queue for nanosleep()
to deal with signals.

Close #2130.
---
 cpukit/posix/src/nanosleep.c            | 35 +++++++++++++++---------------
 cpukit/posix/src/psignalunblockthread.c | 11 +---------
 cpukit/rtems/src/taskwakeafter.c        | 10 +++++----
 cpukit/rtems/src/taskwakewhen.c         |  8 ++++---
 cpukit/score/Makefile.am                |  2 +-
 cpukit/score/src/threaddelayended.c     | 38 ---------------------------------
 6 files changed, 30 insertions(+), 74 deletions(-)
 delete mode 100644 cpukit/score/src/threaddelayended.c

diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c
index 39ae84d..46697ae 100644
--- a/cpukit/posix/src/nanosleep.c
+++ b/cpukit/posix/src/nanosleep.c
@@ -23,9 +23,13 @@
 
 #include <rtems/seterr.h>
 #include <rtems/score/threadimpl.h>
+#include <rtems/score/threadqimpl.h>
 #include <rtems/score/timespec.h>
 #include <rtems/score/watchdogimpl.h>
 
+static Thread_queue_Control _Nanosleep_Pseudo_queue =
+  THREAD_QUEUE_FIFO_INITIALIZER( _Nanosleep_Pseudo_queue, "Nanosleep" );
+
 /*
  *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
  */
@@ -38,7 +42,8 @@ int nanosleep(
    * It is critical to obtain the executing thread after thread dispatching is
    * disabled on SMP configurations.
    */
-  Thread_Control *executing;
+  Thread_Control  *executing;
+  Per_CPU_Control *cpu_self;
 
   Watchdog_Interval  ticks;
   Watchdog_Interval  elapsed;
@@ -58,16 +63,17 @@ int nanosleep(
    */
   ticks = _Timespec_To_ticks( rqtp );
 
+  executing = _Thread_Get_executing();
+
   /*
    *  A nanosleep for zero time is implemented as a yield.
    *  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;
+    cpu_self = _Thread_Dispatch_disable();
       _Thread_Yield( executing );
-    _Thread_Enable_dispatch();
+    _Thread_Dispatch_enable( cpu_self );
     if ( rmtp ) {
        rmtp->tv_sec = 0;
        rmtp->tv_nsec = 0;
@@ -78,20 +84,13 @@ int nanosleep(
   /*
    *  Block for the desired amount of time
    */
-  _Thread_Disable_dispatch();
-    executing = _Thread_Executing;
-    _Thread_Set_state(
-      executing,
-      STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
-    );
-    _Watchdog_Initialize(
-      &executing->Timer,
-      _Thread_Delay_ended,
-      0,
-      executing
-    );
-    _Watchdog_Insert_ticks( &executing->Timer, ticks );
-  _Thread_Enable_dispatch();
+  _Thread_queue_Enqueue(
+    &_Nanosleep_Pseudo_queue,
+    executing,
+    STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL,
+    ticks,
+    0
+  );
 
   /*
    * Calculate the time that passed while we were sleeping and how
diff --git a/cpukit/posix/src/psignalunblockthread.c b/cpukit/posix/src/psignalunblockthread.c
index 3b310a9..200e9e7 100644
--- a/cpukit/posix/src/psignalunblockthread.c
+++ b/cpukit/posix/src/psignalunblockthread.c
@@ -110,16 +110,7 @@ bool _POSIX_signals_Unblock_thread(
 
     if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) {
       the_thread->Wait.return_code = EINTR;
-      /*
-       *  In pthread_cond_wait, a thread will be blocking on a thread
-       *  queue, but is also interruptible by a POSIX signal.
-       */
-       if ( _States_Is_delaying(the_thread->current_state) ) {
-          _Watchdog_Remove_ticks( &the_thread->Timer );
-          _Thread_Unblock( the_thread );
-       } else {
-         _Thread_queue_Extract_with_proxy( the_thread );
-       }
+      _Thread_queue_Extract_with_proxy( the_thread );
     }
   }
   return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c
index 6f03227..b7f328f 100644
--- a/cpukit/rtems/src/taskwakeafter.c
+++ b/cpukit/rtems/src/taskwakeafter.c
@@ -30,23 +30,25 @@ rtems_status_code rtems_task_wake_after(
    * It is critical to obtain the executing thread after thread dispatching is
    * disabled on SMP configurations.
    */
-  Thread_Control *executing;
+  Thread_Control  *executing;
+  Per_CPU_Control *cpu_self;
 
-  _Thread_Disable_dispatch();
+  cpu_self = _Thread_Dispatch_disable();
     executing = _Thread_Executing;
 
     if ( ticks == 0 ) {
       _Thread_Yield( executing );
     } else {
       _Thread_Set_state( executing, STATES_DELAYING );
+      _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
       _Watchdog_Initialize(
         &executing->Timer,
-        _Thread_Delay_ended,
+        _Thread_Timeout,
         0,
         executing
       );
       _Watchdog_Insert_ticks( &executing->Timer, ticks );
     }
-  _Thread_Enable_dispatch();
+  _Thread_Dispatch_enable( cpu_self );
   return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c
index a1fc15f..cf0b303 100644
--- a/cpukit/rtems/src/taskwakewhen.c
+++ b/cpukit/rtems/src/taskwakewhen.c
@@ -30,6 +30,7 @@ rtems_status_code rtems_task_wake_when(
 {
   Watchdog_Interval   seconds;
   Thread_Control     *executing;
+  Per_CPU_Control    *cpu_self;
 
   if ( !_TOD_Is_set() )
     return RTEMS_NOT_DEFINED;
@@ -47,12 +48,13 @@ rtems_status_code rtems_task_wake_when(
   if ( seconds <= _TOD_Seconds_since_epoch() )
     return RTEMS_INVALID_CLOCK;
 
-  _Thread_Disable_dispatch();
+  cpu_self = _Thread_Dispatch_disable();
     executing = _Thread_Executing;
     _Thread_Set_state( executing, STATES_WAITING_FOR_TIME );
+    _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
     _Watchdog_Initialize(
       &executing->Timer,
-      _Thread_Delay_ended,
+      _Thread_Timeout,
       0,
       executing
     );
@@ -60,6 +62,6 @@ rtems_status_code rtems_task_wake_when(
       &executing->Timer,
       seconds - _TOD_Seconds_since_epoch()
     );
-  _Thread_Enable_dispatch();
+  _Thread_Dispatch_enable( cpu_self );
   return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index 714bd66..b6b7c9f 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -280,7 +280,7 @@ libscore_a_SOURCES += src/rbtree.c \
 ## THREAD_C_FILES
 libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
     src/threadclearstate.c src/threadcreateidle.c \
-    src/threaddelayended.c src/threaddispatch.c \
+    src/threaddispatch.c \
     src/threadenabledispatch.c src/threaddisabledispatch.c \
     src/threadget.c src/threadhandler.c src/threadinitialize.c \
     src/threadloadenv.c \
diff --git a/cpukit/score/src/threaddelayended.c b/cpukit/score/src/threaddelayended.c
deleted file mode 100644
index 95dae7d..0000000
--- a/cpukit/score/src/threaddelayended.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file
- * 
- * @brief End the Delay of a Thread
- * @ingroup ScoreThread
- */
-
-/*
- *  COPYRIGHT (c) 1989-2007.
- *  On-Line Applications Research Corporation (OAR).
- *
- *  The license and distribution terms for this file may be
- *  found in the file LICENSE in this distribution or at
- *  http://www.rtems.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems/score/threadimpl.h>
-
-void _Thread_Delay_ended(
-  Objects_Id  id,
-  void       *arg
-)
-{
-  Thread_Control *the_thread = arg;
-
-  (void) id;
-
-  _Thread_Clear_state(
-    the_thread,
-    STATES_DELAYING
-      | STATES_WAITING_FOR_TIME
-      | STATES_INTERRUPTIBLE_BY_SIGNAL
-  );
-}
-- 
1.8.4.5




More information about the devel mailing list