summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-11 14:56:49 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-19 12:00:48 +0200
commitaa05cfbb3d6309ec45b69f34d0870465fe30b74c (patch)
treee004fe884c7018b81bf430b095af350b66f86f6f
parentscore: Add static initializers for thread queues (diff)
downloadrtems-aa05cfbb3d6309ec45b69f34d0870465fe30b74c.tar.bz2
score: Replace _Thread_Delay_ended()
Use _Thread_Timeout() instead. Use pseudo thread queue for nanosleep() to deal with signals. Close #2130.
-rw-r--r--cpukit/posix/src/nanosleep.c35
-rw-r--r--cpukit/posix/src/psignalunblockthread.c11
-rw-r--r--cpukit/rtems/src/taskwakeafter.c10
-rw-r--r--cpukit/rtems/src/taskwakewhen.c8
-rw-r--r--cpukit/score/Makefile.am2
-rw-r--r--cpukit/score/src/threaddelayended.c38
6 files changed, 30 insertions, 74 deletions
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 <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 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 <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
- );
-}