From c31058947491ca319c901040219be39e4f8155b6 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 19 Oct 2017 13:47:57 +0200 Subject: score: Move thread queue timeout handling Update #3117. Update #3182. --- cpukit/score/src/apimutexlock.c | 2 +- cpukit/score/src/condition.c | 88 ++++++++--------- cpukit/score/src/corebarrierwait.c | 1 - cpukit/score/src/coremsgseize.c | 1 - cpukit/score/src/coremsgsubmit.c | 1 - cpukit/score/src/coremutexseize.c | 1 - cpukit/score/src/corerwlockobtainread.c | 1 - cpukit/score/src/corerwlockobtainwrite.c | 1 - cpukit/score/src/coretodabsolutetimeout.c | 82 ---------------- cpukit/score/src/futex.c | 1 - cpukit/score/src/mutex.c | 43 ++------- cpukit/score/src/semaphore.c | 1 - cpukit/score/src/threadqenqueue.c | 54 ++++------- cpukit/score/src/threadqtimeout.c | 154 ++++++++++++++++++++++++++++++ cpukit/score/src/threadrestart.c | 2 +- 15 files changed, 227 insertions(+), 206 deletions(-) delete mode 100644 cpukit/score/src/coretodabsolutetimeout.c create mode 100644 cpukit/score/src/threadqtimeout.c (limited to 'cpukit/score/src') diff --git a/cpukit/score/src/apimutexlock.c b/cpukit/score/src/apimutexlock.c index 879562d9f0..312dcc2993 100644 --- a/cpukit/score/src/apimutexlock.c +++ b/cpukit/score/src/apimutexlock.c @@ -33,7 +33,7 @@ void _API_Mutex_Lock( API_Mutex_Control *the_mutex ) _Thread_queue_Context_initialize( &queue_context ); _ISR_lock_ISR_disable( &queue_context.Lock_context.Lock_context ); - _Thread_queue_Context_set_no_timeout( &queue_context ); + _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); _CORE_recursive_mutex_Seize( &the_mutex->Mutex, CORE_MUTEX_TQ_PRIORITY_INHERIT_OPERATIONS, diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c index bbbeb901db..9913d86d34 100644 --- a/cpukit/score/src/condition.c +++ b/cpukit/score/src/condition.c @@ -84,16 +84,38 @@ typedef struct { struct _Mutex_Control *mutex; } Condition_Enqueue_context; -static void _Condition_Enqueue_callout( +static void _Condition_Mutex_release( Thread_queue_Context *queue_context ) +{ + Condition_Enqueue_context *context; + + context = (Condition_Enqueue_context *) queue_context; + _Mutex_Release( context->mutex ); +} + +static void _Condition_Enqueue_no_timeout( Thread_queue_Queue *queue, Thread_Control *the_thread, + Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context ) { - Condition_Enqueue_context *context; + _Condition_Mutex_release( queue_context ); +} - context = (Condition_Enqueue_context *) queue_context; - _Mutex_Release( context->mutex ); +static void _Condition_Enqueue_with_timeout( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + _Thread_queue_Add_timeout_realtime_timespec( + queue, + the_thread, + cpu_self, + queue_context + ); + _Condition_Mutex_release( queue_context ); } static Thread_Control *_Condition_Do_wait( @@ -107,15 +129,12 @@ static Thread_Control *_Condition_Do_wait( context->mutex = _mutex; condition = _Condition_Get( _condition ); + _ISR_lock_ISR_disable( &context->Base.Lock_context.Lock_context ); executing = _Condition_Queue_acquire_critical( condition, &context->Base ); _Thread_queue_Context_set_thread_state( &context->Base, STATES_WAITING_FOR_CONDITION_VARIABLE ); - _Thread_queue_Context_set_enqueue_callout( - &context->Base, - _Condition_Enqueue_callout - ); _Thread_queue_Enqueue( &condition->Queue.Queue, CONDITION_TQ_OPERATIONS, @@ -134,8 +153,10 @@ void _Condition_Wait( Condition_Enqueue_context context; _Thread_queue_Context_initialize( &context.Base ); - _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context ); - _Thread_queue_Context_set_no_timeout( &context.Base ); + _Thread_queue_Context_set_enqueue_callout( + &context.Base, + _Condition_Enqueue_no_timeout + ); _Condition_Do_wait( _condition, _mutex, &context ); _Mutex_Acquire( _mutex ); } @@ -149,24 +170,13 @@ int _Condition_Wait_timed( Condition_Enqueue_context context; Thread_Control *executing; int eno; - Watchdog_Interval ticks; _Thread_queue_Context_initialize( &context.Base ); - _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context ); - - switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { - case TOD_ABSOLUTE_TIMEOUT_INVALID: - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); - return EINVAL; - case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: - case TOD_ABSOLUTE_TIMEOUT_IS_NOW: - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); - return ETIMEDOUT; - default: - break; - } - - _Thread_queue_Context_set_relative_timeout( &context.Base, ticks ); + _Thread_queue_Context_set_enqueue_callout( + &context.Base, + _Condition_Enqueue_with_timeout + ); + _Thread_queue_Context_set_timeout_argument( &context.Base, abstime ); executing = _Condition_Do_wait( _condition, _mutex, &context ); eno = STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) ); _Mutex_Acquire( _mutex ); @@ -195,8 +205,10 @@ void _Condition_Wait_recursive( unsigned int nest_level; _Thread_queue_Context_initialize( &context.Base ); - _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context ); - _Thread_queue_Context_set_no_timeout( &context.Base ); + _Thread_queue_Context_set_enqueue_callout( + &context.Base, + _Condition_Enqueue_no_timeout + ); nest_level = _Condition_Unnest_mutex( _mutex ); _Condition_Do_wait( _condition, &_mutex->_Mutex, &context ); _Mutex_recursive_Acquire( _mutex ); @@ -213,23 +225,13 @@ int _Condition_Wait_recursive_timed( Thread_Control *executing; int eno; unsigned int nest_level; - Watchdog_Interval ticks; _Thread_queue_Context_initialize( &context.Base ); - _ISR_lock_ISR_disable( &context.Base.Lock_context.Lock_context ); - - switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { - case TOD_ABSOLUTE_TIMEOUT_INVALID: - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); - return EINVAL; - case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: - case TOD_ABSOLUTE_TIMEOUT_IS_NOW: - _ISR_lock_ISR_enable( &context.Base.Lock_context.Lock_context ); - return ETIMEDOUT; - default: - break; - } - _Thread_queue_Context_set_relative_timeout( &context.Base, ticks ); + _Thread_queue_Context_set_enqueue_callout( + &context.Base, + _Condition_Enqueue_with_timeout + ); + _Thread_queue_Context_set_timeout_argument( &context.Base, abstime ); nest_level = _Condition_Unnest_mutex( _mutex ); executing = _Condition_Do_wait( _condition, &_mutex->_Mutex, &context ); eno = STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) ); diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c index 5093e02bc0..08acce9d86 100644 --- a/cpukit/score/src/corebarrierwait.c +++ b/cpukit/score/src/corebarrierwait.c @@ -48,7 +48,6 @@ Status_Control _CORE_barrier_Seize( queue_context, STATES_WAITING_FOR_BARRIER ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_barrier->Wait_queue.Queue, CORE_BARRIER_TQ_OPERATIONS, diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c index 5d0b95b9e5..e3d8842831 100644 --- a/cpukit/score/src/coremsgseize.c +++ b/cpukit/score/src/coremsgseize.c @@ -117,7 +117,6 @@ Status_Control _CORE_message_queue_Seize( queue_context, STATES_WAITING_FOR_MESSAGE ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_message_queue->Wait_queue.Queue, the_message_queue->operations, diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c index 6040f76eb3..49c90256cd 100644 --- a/cpukit/score/src/coremsgsubmit.c +++ b/cpukit/score/src/coremsgsubmit.c @@ -135,7 +135,6 @@ Status_Control _CORE_message_queue_Submit( queue_context, STATES_WAITING_FOR_MESSAGE ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_message_queue->Wait_queue.Queue, the_message_queue->operations, diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index 173c495d3c..e07458573d 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -36,7 +36,6 @@ Status_Control _CORE_mutex_Seize_slow( queue_context, STATES_WAITING_FOR_MUTEX ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Context_set_deadlock_callout( queue_context, _Thread_queue_Deadlock_status diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c index 88853ebfb3..6969486f28 100644 --- a/cpukit/score/src/corerwlockobtainread.c +++ b/cpukit/score/src/corerwlockobtainread.c @@ -77,7 +77,6 @@ Status_Control _CORE_RWLock_Seize_for_reading( queue_context, STATES_WAITING_FOR_RWLOCK ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_rwlock->Queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, diff --git a/cpukit/score/src/corerwlockobtainwrite.c b/cpukit/score/src/corerwlockobtainwrite.c index 6145fc3c4c..7b296169d9 100644 --- a/cpukit/score/src/corerwlockobtainwrite.c +++ b/cpukit/score/src/corerwlockobtainwrite.c @@ -71,7 +71,6 @@ Status_Control _CORE_RWLock_Seize_for_writing( queue_context, STATES_WAITING_FOR_RWLOCK ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_rwlock->Queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, diff --git a/cpukit/score/src/coretodabsolutetimeout.c b/cpukit/score/src/coretodabsolutetimeout.c deleted file mode 100644 index d67b7c33c7..0000000000 --- a/cpukit/score/src/coretodabsolutetimeout.c +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file - * - * @brief Convert Absolute Timeout to Ticks - * @ingroup ScoreTOD - */ - -/* - * COPYRIGHT (c) 1989-2008. - * 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 - -/* - * The abstime is a walltime. We turn it into an interval. - */ -TOD_Absolute_timeout_conversion_results _TOD_Absolute_timeout_to_ticks( - const struct timespec *abstime, - clockid_t clock, - Watchdog_Interval *ticks_out -) -{ - struct timespec current_time; - struct timespec difference; - - /* - * Make sure there is always a value returned. - */ - *ticks_out = 0; - - /* - * Is the absolute time even valid? - */ - if ( !_Timespec_Is_valid(abstime) ) - return TOD_ABSOLUTE_TIMEOUT_INVALID; - - /* - * Is the absolute time in the past? - */ - if ( clock == CLOCK_REALTIME ) { - _TOD_Get( ¤t_time ); - } else { - _Assert( clock == CLOCK_MONOTONIC ); - _TOD_Get_zero_based_uptime_as_timespec( ¤t_time ); - } - - if ( _Timespec_Less_than( abstime, ¤t_time ) ) - return TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST; - - /* - * How long until the requested absolute time? - */ - _Timespec_Subtract( ¤t_time, abstime, &difference ); - - /* - * Internally the SuperCore uses ticks, so convert to them. - */ - *ticks_out = _Timespec_To_ticks( &difference ); - - /* - * If the difference was 0, then the future is now. It is so bright - * we better wear shades. - */ - if ( !*ticks_out ) - return TOD_ABSOLUTE_TIMEOUT_IS_NOW; - - /* - * This is the case we were expecting and it took this long to - * get here. - */ - return TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE; -} - diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c index c5b4f197c3..6487882819 100644 --- a/cpukit/score/src/futex.c +++ b/cpukit/score/src/futex.c @@ -95,7 +95,6 @@ int _Futex_Wait( struct _Futex_Control *_futex, int *uaddr, int val ) STATES_WAITING_FOR_FUTEX ); _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); - _Thread_queue_Context_set_no_timeout( &queue_context ); _Thread_queue_Context_set_ISR_level( &queue_context, level ); _Thread_queue_Enqueue( &futex->Queue.Queue, diff --git a/cpukit/score/src/mutex.c b/cpukit/score/src/mutex.c index 1c793ad633..e2f5bb52fc 100644 --- a/cpukit/score/src/mutex.c +++ b/cpukit/score/src/mutex.c @@ -102,7 +102,6 @@ static void _Mutex_Acquire_slow( queue_context, STATES_WAITING_FOR_MUTEX ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Context_set_deadlock_callout( queue_context, _Thread_queue_Deadlock_fatal @@ -163,7 +162,7 @@ void _Mutex_Acquire( struct _Mutex_Control *_mutex ) _Thread_Resource_count_increment( executing ); _Mutex_Queue_release( mutex, level, &queue_context ); } else { - _Thread_queue_Context_set_no_timeout( &queue_context ); + _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); _Mutex_Acquire_slow( mutex, owner, executing, level, &queue_context ); } } @@ -193,21 +192,10 @@ int _Mutex_Acquire_timed( return 0; } else { - Watchdog_Interval ticks; - - switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { - case TOD_ABSOLUTE_TIMEOUT_INVALID: - _Mutex_Queue_release( mutex, level, &queue_context ); - return EINVAL; - case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: - case TOD_ABSOLUTE_TIMEOUT_IS_NOW: - _Mutex_Queue_release( mutex, level, &queue_context ); - return ETIMEDOUT; - default: - break; - } - - _Thread_queue_Context_set_relative_timeout( &queue_context, ticks ); + _Thread_queue_Context_set_enqueue_timeout_realtime_timespec( + &queue_context, + abstime + ); _Mutex_Acquire_slow( mutex, owner, executing, level, &queue_context ); return STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) ); @@ -290,7 +278,7 @@ void _Mutex_recursive_Acquire( struct _Mutex_recursive_Control *_mutex ) ++mutex->nest_level; _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); } else { - _Thread_queue_Context_set_no_timeout( &queue_context ); + _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context ); } } @@ -325,21 +313,10 @@ int _Mutex_recursive_Acquire_timed( return 0; } else { - Watchdog_Interval ticks; - - switch ( _TOD_Absolute_timeout_to_ticks( abstime, CLOCK_REALTIME, &ticks ) ) { - case TOD_ABSOLUTE_TIMEOUT_INVALID: - _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); - return EINVAL; - case TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST: - case TOD_ABSOLUTE_TIMEOUT_IS_NOW: - _Mutex_Queue_release( &mutex->Mutex, level, &queue_context ); - return ETIMEDOUT; - default: - break; - } - - _Thread_queue_Context_set_relative_timeout( &queue_context, ticks ); + _Thread_queue_Context_set_enqueue_timeout_realtime_timespec( + &queue_context, + abstime + ); _Mutex_Acquire_slow( &mutex->Mutex, owner, executing, level, &queue_context ); return STATUS_GET_POSIX( _Thread_Wait_get_status( executing ) ); diff --git a/cpukit/score/src/semaphore.c b/cpukit/score/src/semaphore.c index a912fbc4d2..4edd25a387 100644 --- a/cpukit/score/src/semaphore.c +++ b/cpukit/score/src/semaphore.c @@ -61,7 +61,6 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem ) STATES_WAITING_FOR_SEMAPHORE ); _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); - _Thread_queue_Context_set_no_timeout( &queue_context ); _Thread_queue_Context_set_ISR_level( &queue_context, level ); _Thread_queue_Enqueue( &sem->Queue.Queue, diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 40fb69bbd3..62d3671222 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -359,6 +359,7 @@ bool _Thread_queue_Path_acquire_critical( void _Thread_queue_Enqueue_do_nothing_extra( Thread_queue_Queue *queue, Thread_Control *the_thread, + Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context ) { @@ -375,36 +376,6 @@ void _Thread_queue_Deadlock_fatal( Thread_Control *the_thread ) _Internal_error( INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK ); } -static void _Thread_queue_Timeout( - Thread_Control *the_thread, - Per_CPU_Control *cpu_self, - Thread_queue_Context *queue_context -) -{ - switch ( queue_context->timeout_discipline ) { - case WATCHDOG_RELATIVE: - /* A relative timeout of 0 is a special case indefinite (no) timeout */ - if ( queue_context->timeout != 0 ) { - _Thread_Add_timeout_ticks( - the_thread, - cpu_self, - (Watchdog_Interval) queue_context->timeout - ); - } - break; - case WATCHDOG_ABSOLUTE: - _Thread_Timer_insert_realtime( - the_thread, - cpu_self, - _Thread_Timeout, - queue_context->timeout - ); - break; - default: - break; - } -} - void _Thread_queue_Enqueue( Thread_queue_Queue *queue, const Thread_queue_Operations *operations, @@ -416,7 +387,6 @@ void _Thread_queue_Enqueue( bool success; _Assert( queue_context->enqueue_callout != NULL ); - _Assert( (uint8_t) queue_context->timeout_discipline != 0x7f ); #if defined(RTEMS_MULTIPROCESSING) if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) { @@ -447,18 +417,18 @@ void _Thread_queue_Enqueue( cpu_self = _Thread_queue_Dispatch_disable( queue_context ); _Thread_queue_Queue_release( queue, &queue_context->Lock_context.Lock_context ); - ( *queue_context->enqueue_callout )( queue, the_thread, queue_context ); + ( *queue_context->enqueue_callout )( + queue, + the_thread, + cpu_self, + queue_context + ); /* * Set the blocking state for this thread queue in the thread. */ _Thread_Set_state( the_thread, queue_context->thread_state ); - /* - * If the thread wants to timeout, then schedule its timer. - */ - _Thread_queue_Timeout( the_thread, cpu_self, queue_context ); - /* * At this point thread dispatching is disabled, however, we already released * the thread queue lock. Thus, interrupts or threads on other processors @@ -491,6 +461,8 @@ Status_Control _Thread_queue_Enqueue_sticky( { Per_CPU_Control *cpu_self; + _Assert( queue_context->enqueue_callout != NULL ); + _Thread_Wait_claim( the_thread, queue ); if ( !_Thread_queue_Path_acquire_critical( queue, the_thread, queue_context ) ) { @@ -519,7 +491,13 @@ Status_Control _Thread_queue_Enqueue_sticky( ); } - _Thread_queue_Timeout( the_thread, cpu_self, queue_context ); + ( *queue_context->enqueue_callout )( + queue, + the_thread, + cpu_self, + queue_context + ); + _Thread_Priority_update( queue_context ); _Thread_Priority_and_sticky_update( the_thread, 1 ); _Thread_Dispatch_enable( cpu_self ); diff --git a/cpukit/score/src/threadqtimeout.c b/cpukit/score/src/threadqtimeout.c new file mode 100644 index 0000000000..3f052fcf6f --- /dev/null +++ b/cpukit/score/src/threadqtimeout.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016, 2017 embedded brains GmbH + * + * 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 +#include +#include + +void _Thread_queue_Add_timeout_ticks( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + Watchdog_Interval ticks; + + ticks = queue_context->Timeout.ticks; + + if ( ticks != WATCHDOG_NO_TIMEOUT ) { + _Thread_Add_timeout_ticks( + the_thread, + cpu_self, + queue_context->Timeout.ticks + ); + } +} + +static bool _Thread_queue_Lazy_insert_monotonic_timespec( + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + const struct timespec *abstime +) +{ + uint64_t expire; + ISR_lock_Context lock_context; + bool insert; + + if ( abstime->tv_sec < 0 ) { + expire = 0; + } else if ( _Watchdog_Is_far_future_monotonic_timespec( abstime ) ) { + expire = WATCHDOG_MAXIMUM_TICKS; + } else { + expire = _Watchdog_Monotonic_from_timespec( abstime ); + } + + _ISR_lock_ISR_disable_and_acquire( + &the_thread->Timer.Lock, + &lock_context + ); + + the_thread->Timer.header = + &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + the_thread->Timer.Watchdog.routine = _Thread_Timeout; + insert = _Watchdog_Per_CPU_lazy_insert_monotonic( + &the_thread->Timer.Watchdog, + cpu_self, + expire + ); + + _ISR_lock_Release_and_ISR_enable( + &the_thread->Timer.Lock, + &lock_context + ); + return insert; +} + +void _Thread_queue_Add_timeout_monotonic_timespec( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + const struct timespec *abstime; + + abstime = queue_context->Timeout.arg; + + if ( _Watchdog_Is_valid_timespec( abstime ) ) { + if ( + !_Thread_queue_Lazy_insert_monotonic_timespec( + the_thread, + cpu_self, + abstime + ) + ) { + _Thread_Continue( the_thread, STATUS_TIMEOUT ); + } + } else { + _Thread_Continue( the_thread, STATUS_INVALID_NUMBER ); + } +} + +void _Thread_queue_Add_timeout_realtime_timespec( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + const struct timespec *abstime; + + abstime = queue_context->Timeout.arg; + + if ( _Watchdog_Is_valid_timespec( abstime ) ) { + uint64_t expire; + struct timespec now; + + if ( abstime->tv_sec < 0 ) { + expire = 0; + } else if ( _Watchdog_Is_far_future_realtime_timespec( abstime ) ) { + expire = WATCHDOG_MAXIMUM_TICKS; + } else { + expire = _Watchdog_Realtime_from_timespec( abstime ); + } + + _Timecounter_Getnanotime( &now ); + + if ( expire > _Watchdog_Realtime_from_timespec( &now ) ) { + ISR_lock_Context lock_context; + + _ISR_lock_ISR_disable_and_acquire( + &the_thread->Timer.Lock, + &lock_context + ); + + the_thread->Timer.header = + &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + the_thread->Timer.Watchdog.routine = _Thread_Timeout; + _Watchdog_Per_CPU_insert_realtime( + &the_thread->Timer.Watchdog, + cpu_self, + expire + ); + + _ISR_lock_Release_and_ISR_enable( + &the_thread->Timer.Lock, + &lock_context + ); + } else { + _Thread_Continue( the_thread, STATUS_TIMEOUT ); + } + } else { + _Thread_Continue( the_thread, STATUS_INVALID_NUMBER ); + } +} diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index 7ee1f880c4..0430ca0407 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -514,6 +514,7 @@ void _Thread_Cancel( static void _Thread_Close_enqueue_callout( Thread_queue_Queue *queue, Thread_Control *the_thread, + Per_CPU_Control *cpu_self, Thread_queue_Context *queue_context ) { @@ -534,7 +535,6 @@ void _Thread_Close( &context->Base, _Thread_Close_enqueue_callout ); - _Thread_queue_Context_set_no_timeout( &context->Base ); _Thread_State_acquire_critical( the_thread, &context->Base.Lock_context.Lock_context -- cgit v1.2.3