forked from Imagelibrary/rtems
score: Replace _Thread_Delay_ended()
Use _Thread_Timeout() instead. Use pseudo thread queue for nanosleep() to deal with signals. Close #2130.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user