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/seterr.h>
|
||||||
#include <rtems/score/threadimpl.h>
|
#include <rtems/score/threadimpl.h>
|
||||||
|
#include <rtems/score/threadqimpl.h>
|
||||||
#include <rtems/score/timespec.h>
|
#include <rtems/score/timespec.h>
|
||||||
#include <rtems/score/watchdogimpl.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
|
* 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
|
* It is critical to obtain the executing thread after thread dispatching is
|
||||||
* disabled on SMP configurations.
|
* disabled on SMP configurations.
|
||||||
*/
|
*/
|
||||||
Thread_Control *executing;
|
Thread_Control *executing;
|
||||||
|
Per_CPU_Control *cpu_self;
|
||||||
|
|
||||||
Watchdog_Interval ticks;
|
Watchdog_Interval ticks;
|
||||||
Watchdog_Interval elapsed;
|
Watchdog_Interval elapsed;
|
||||||
@@ -58,16 +63,17 @@ int nanosleep(
|
|||||||
*/
|
*/
|
||||||
ticks = _Timespec_To_ticks( rqtp );
|
ticks = _Timespec_To_ticks( rqtp );
|
||||||
|
|
||||||
|
executing = _Thread_Get_executing();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A nanosleep for zero time is implemented as a yield.
|
* A nanosleep for zero time is implemented as a yield.
|
||||||
* This behavior is also beyond the POSIX specification but is
|
* This behavior is also beyond the POSIX specification but is
|
||||||
* consistent with the RTEMS API and yields desirable behavior.
|
* consistent with the RTEMS API and yields desirable behavior.
|
||||||
*/
|
*/
|
||||||
if ( !ticks ) {
|
if ( !ticks ) {
|
||||||
_Thread_Disable_dispatch();
|
cpu_self = _Thread_Dispatch_disable();
|
||||||
executing = _Thread_Executing;
|
|
||||||
_Thread_Yield( executing );
|
_Thread_Yield( executing );
|
||||||
_Thread_Enable_dispatch();
|
_Thread_Dispatch_enable( cpu_self );
|
||||||
if ( rmtp ) {
|
if ( rmtp ) {
|
||||||
rmtp->tv_sec = 0;
|
rmtp->tv_sec = 0;
|
||||||
rmtp->tv_nsec = 0;
|
rmtp->tv_nsec = 0;
|
||||||
@@ -78,20 +84,13 @@ int nanosleep(
|
|||||||
/*
|
/*
|
||||||
* Block for the desired amount of time
|
* Block for the desired amount of time
|
||||||
*/
|
*/
|
||||||
_Thread_Disable_dispatch();
|
_Thread_queue_Enqueue(
|
||||||
executing = _Thread_Executing;
|
&_Nanosleep_Pseudo_queue,
|
||||||
_Thread_Set_state(
|
executing,
|
||||||
executing,
|
STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL,
|
||||||
STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL
|
ticks,
|
||||||
);
|
0
|
||||||
_Watchdog_Initialize(
|
);
|
||||||
&executing->Timer,
|
|
||||||
_Thread_Delay_ended,
|
|
||||||
0,
|
|
||||||
executing
|
|
||||||
);
|
|
||||||
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
|
||||||
_Thread_Enable_dispatch();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the time that passed while we were sleeping and how
|
* 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 ) ) {
|
if ( _States_Is_interruptible_by_signal( the_thread->current_state ) ) {
|
||||||
the_thread->Wait.return_code = EINTR;
|
the_thread->Wait.return_code = EINTR;
|
||||||
/*
|
_Thread_queue_Extract_with_proxy( the_thread );
|
||||||
* 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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _POSIX_signals_Unblock_thread_done( the_thread, api, false );
|
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
|
* It is critical to obtain the executing thread after thread dispatching is
|
||||||
* disabled on SMP configurations.
|
* 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;
|
executing = _Thread_Executing;
|
||||||
|
|
||||||
if ( ticks == 0 ) {
|
if ( ticks == 0 ) {
|
||||||
_Thread_Yield( executing );
|
_Thread_Yield( executing );
|
||||||
} else {
|
} else {
|
||||||
_Thread_Set_state( executing, STATES_DELAYING );
|
_Thread_Set_state( executing, STATES_DELAYING );
|
||||||
|
_Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
|
||||||
_Watchdog_Initialize(
|
_Watchdog_Initialize(
|
||||||
&executing->Timer,
|
&executing->Timer,
|
||||||
_Thread_Delay_ended,
|
_Thread_Timeout,
|
||||||
0,
|
0,
|
||||||
executing
|
executing
|
||||||
);
|
);
|
||||||
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
_Watchdog_Insert_ticks( &executing->Timer, ticks );
|
||||||
}
|
}
|
||||||
_Thread_Enable_dispatch();
|
_Thread_Dispatch_enable( cpu_self );
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ rtems_status_code rtems_task_wake_when(
|
|||||||
{
|
{
|
||||||
Watchdog_Interval seconds;
|
Watchdog_Interval seconds;
|
||||||
Thread_Control *executing;
|
Thread_Control *executing;
|
||||||
|
Per_CPU_Control *cpu_self;
|
||||||
|
|
||||||
if ( !_TOD_Is_set() )
|
if ( !_TOD_Is_set() )
|
||||||
return RTEMS_NOT_DEFINED;
|
return RTEMS_NOT_DEFINED;
|
||||||
@@ -47,12 +48,13 @@ rtems_status_code rtems_task_wake_when(
|
|||||||
if ( seconds <= _TOD_Seconds_since_epoch() )
|
if ( seconds <= _TOD_Seconds_since_epoch() )
|
||||||
return RTEMS_INVALID_CLOCK;
|
return RTEMS_INVALID_CLOCK;
|
||||||
|
|
||||||
_Thread_Disable_dispatch();
|
cpu_self = _Thread_Dispatch_disable();
|
||||||
executing = _Thread_Executing;
|
executing = _Thread_Executing;
|
||||||
_Thread_Set_state( executing, STATES_WAITING_FOR_TIME );
|
_Thread_Set_state( executing, STATES_WAITING_FOR_TIME );
|
||||||
|
_Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED );
|
||||||
_Watchdog_Initialize(
|
_Watchdog_Initialize(
|
||||||
&executing->Timer,
|
&executing->Timer,
|
||||||
_Thread_Delay_ended,
|
_Thread_Timeout,
|
||||||
0,
|
0,
|
||||||
executing
|
executing
|
||||||
);
|
);
|
||||||
@@ -60,6 +62,6 @@ rtems_status_code rtems_task_wake_when(
|
|||||||
&executing->Timer,
|
&executing->Timer,
|
||||||
seconds - _TOD_Seconds_since_epoch()
|
seconds - _TOD_Seconds_since_epoch()
|
||||||
);
|
);
|
||||||
_Thread_Enable_dispatch();
|
_Thread_Dispatch_enable( cpu_self );
|
||||||
return RTEMS_SUCCESSFUL;
|
return RTEMS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ libscore_a_SOURCES += src/rbtree.c \
|
|||||||
## THREAD_C_FILES
|
## THREAD_C_FILES
|
||||||
libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
|
libscore_a_SOURCES += src/thread.c src/threadchangepriority.c \
|
||||||
src/threadclearstate.c src/threadcreateidle.c \
|
src/threadclearstate.c src/threadcreateidle.c \
|
||||||
src/threaddelayended.c src/threaddispatch.c \
|
src/threaddispatch.c \
|
||||||
src/threadenabledispatch.c src/threaddisabledispatch.c \
|
src/threadenabledispatch.c src/threaddisabledispatch.c \
|
||||||
src/threadget.c src/threadhandler.c src/threadinitialize.c \
|
src/threadget.c src/threadhandler.c src/threadinitialize.c \
|
||||||
src/threadloadenv.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