From aa05cfbb3d6309ec45b69f34d0870465fe30b74c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 11 May 2015 14:56:49 +0200 Subject: score: Replace _Thread_Delay_ended() 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 39ae84d3e4..46697ae8fc 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -23,9 +23,13 @@ #include #include +#include #include #include +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 3b310a90b7..200e9e714b 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 6f0322723a..b7f328f5bc 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 a1fc15f047..cf0b303cd3 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 714bd6663b..b6b7c9fa74 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 95dae7d0fa..0000000000 --- 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 - -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 - ); -} -- cgit v1.2.3