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/include/rtems/score/coresemimpl.h | 1 - cpukit/score/include/rtems/score/threadq.h | 33 ++++--- cpukit/score/include/rtems/score/threadqimpl.h | 110 ++++++++++++++++++------ cpukit/score/include/rtems/score/todimpl.h | 40 --------- cpukit/score/include/rtems/score/watchdog.h | 31 +------ cpukit/score/include/rtems/score/watchdogimpl.h | 5 ++ 6 files changed, 114 insertions(+), 106 deletions(-) (limited to 'cpukit/score/include') diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index aa053d7acd..00f77e61dd 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -188,7 +188,6 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize( queue_context, STATES_WAITING_FOR_SEMAPHORE ); - _Thread_queue_Context_set_enqueue_do_nothing_extra( queue_context ); _Thread_queue_Enqueue( &the_semaphore->Wait_queue.Queue, operations, diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index c4742ba05c..3e618bf5af 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -57,14 +57,16 @@ typedef struct Thread_queue_Operations Thread_queue_Operations; * * @param[in] queue The actual thread queue. * @param[in] the_thread The thread to enqueue. + * @param[in] cpu_self The current processor. * @param[in] queue_context The thread queue context of the lock acquire. * * @see _Thread_queue_Context_set_enqueue_callout(). */ typedef void ( *Thread_queue_Enqueue_callout )( - Thread_queue_Queue *queue, - Thread_Control *the_thread, - Thread_queue_Context *queue_context + Thread_queue_Queue *queue, + Thread_Control *the_thread, + struct Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context ); /** @@ -202,22 +204,31 @@ struct Thread_queue_Context { * @brief The enqueue callout for _Thread_queue_Enqueue(). * * The callout is invoked after the release of the thread queue lock with - * thread dispatching disabled. Afterwards the thread is blocked. + * thread dispatching disabled. Afterwards the thread is blocked. This + * callout must be used to install the thread watchdog for timeout handling. * * @see _Thread_queue_Enqueue_do_nothing_extra(). + * _Thread_queue_Add_timeout_ticks(), and + * _Thread_queue_Add_timeout_realtime_timespec(). */ Thread_queue_Enqueue_callout enqueue_callout; - /** - * @brief The clock discipline for the interval timeout. - * Use WATCHDOG_NO_TIMEOUT to block indefinitely. - */ - Watchdog_Discipline timeout_discipline; - /** * @brief Interval to wait. + * + * May be used by the enqueue callout to register a timeout handler. */ - uint64_t timeout; + union { + /** + * @brief The timeout in ticks. + */ + Watchdog_Interval ticks; + + /** + * @brief The timeout argument, e.g. pointer to struct timespec. + */ + const void *arg; + } Timeout; #if defined(RTEMS_SMP) /** diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index f74db96129..ecbd8fd42f 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -65,6 +65,28 @@ typedef struct { 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 +); + +void _Thread_queue_Add_timeout_ticks( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +); + +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 +); + +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 ); @@ -117,6 +139,40 @@ _Thread_queue_Context_set_thread_state( queue_context->thread_state = thread_state; } +/** + * @brief Sets the timeout ticks in the thread queue context. + * + * @param queue_context The thread queue context. + * @param ticks The timeout in ticks. + * + * @see _Thread_queue_Enqueue(). + */ +RTEMS_INLINE_ROUTINE void +_Thread_queue_Context_set_timeout_ticks( + Thread_queue_Context *queue_context, + Watchdog_Interval ticks +) +{ + queue_context->Timeout.ticks = ticks; +} + +/** + * @brief Sets the timeout argument in the thread queue context. + * + * @param queue_context The thread queue context. + * @param arg The timeout argument. + * + * @see _Thread_queue_Enqueue(). + */ +RTEMS_INLINE_ROUTINE void +_Thread_queue_Context_set_timeout_argument( + Thread_queue_Context *queue_context, + const void *arg +) +{ + queue_context->Timeout.arg = arg; +} + /** * @brief Sets the enqueue callout in the thread queue context. * @@ -150,55 +206,61 @@ _Thread_queue_Context_set_enqueue_do_nothing_extra( } /** - * @brief Sets an indefinite timeout interval in the thread queue context. + * @brief Sets the enqueue callout to add a relative monotonic timeout in + * ticks. * * @param queue_context The thread queue context. - * @param timeout The new timeout. + * @param ticks The timeout in ticks. * * @see _Thread_queue_Enqueue(). */ RTEMS_INLINE_ROUTINE void -_Thread_queue_Context_set_no_timeout( - Thread_queue_Context *queue_context +_Thread_queue_Context_set_enqueue_timeout_ticks( + Thread_queue_Context *queue_context, + Watchdog_Interval ticks ) { - queue_context->timeout_discipline = WATCHDOG_NO_TIMEOUT; + queue_context->Timeout.ticks = ticks; + queue_context->enqueue_callout = _Thread_queue_Add_timeout_ticks; } /** - * @brief Sets a relative timeout in the thread queue context. + * @brief Sets the enqueue callout to add an absolute monotonic timeout in + * timespec format. * * @param queue_context The thread queue context. - * @param discipline The clock discipline to use for the timeout. + * @param abstime The absolute monotonic timeout. * * @see _Thread_queue_Enqueue(). */ RTEMS_INLINE_ROUTINE void -_Thread_queue_Context_set_relative_timeout( - Thread_queue_Context *queue_context, - Watchdog_Interval timeout +_Thread_queue_Context_set_enqueue_timeout_monotonic_timespec( + Thread_queue_Context *queue_context, + const struct timespec *abstime ) { - queue_context->timeout_discipline = WATCHDOG_RELATIVE; - queue_context->timeout = timeout; + queue_context->Timeout.arg = abstime; + queue_context->enqueue_callout = + _Thread_queue_Add_timeout_monotonic_timespec; } /** - * @brief Sets an absolute timeout in the thread queue context. + * @brief Sets the enqueue callout to add an absolute realtime timeout in + * timespec format. * * @param queue_context The thread queue context. - * @param discipline The clock discipline to use for the timeout. + * @param abstime The absolute realtime timeout. * * @see _Thread_queue_Enqueue(). */ RTEMS_INLINE_ROUTINE void -_Thread_queue_Context_set_absolute_timeout( - Thread_queue_Context *queue_context, - uint64_t timeout +_Thread_queue_Context_set_enqueue_timeout_realtime_timespec( + Thread_queue_Context *queue_context, + const struct timespec *abstime ) { - queue_context->timeout_discipline = WATCHDOG_ABSOLUTE; - queue_context->timeout = timeout; + queue_context->Timeout.arg = abstime; + queue_context->enqueue_callout = _Thread_queue_Add_timeout_realtime_timespec; } /** @@ -615,11 +677,10 @@ Thread_Control *_Thread_queue_Do_dequeue( * - _Thread_queue_Context_set_thread_state(), * * - _Thread_queue_Context_set_enqueue_callout() or - * _Thread_queue_Context_set_enqueue_do_nothing_extra(), - * - * - _Thread_queue_Context_set_no_timeout() or - * _Thread_queue_Context_set_relative_timeout() or - * _Thread_queue_Context_set_absolute_timeout(), and + * _Thread_queue_Context_set_enqueue_do_nothing_extra() or + * _Thread_queue_Context_set_enqueue_timeout_ticks() or + * _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec() or + * _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(), * * - _Thread_queue_Context_set_deadlock_callout(). * @@ -652,7 +713,6 @@ Thread_Control *_Thread_queue_Do_dequeue( * STATES_WAITING_FOR_MUTEX * ); * _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); - * _Thread_queue_Context_set_no_timeout( &queue_context ); * _Thread_queue_Context_set_deadlock_callout( * queue_context, * _Thread_queue_Deadlock_fatal diff --git a/cpukit/score/include/rtems/score/todimpl.h b/cpukit/score/include/rtems/score/todimpl.h index de4dc93430..e3a1a8f58c 100644 --- a/cpukit/score/include/rtems/score/todimpl.h +++ b/cpukit/score/include/rtems/score/todimpl.h @@ -298,46 +298,6 @@ RTEMS_INLINE_ROUTINE bool _TOD_Is_set( void ) return _TOD.is_set; } -/** - * @brief Absolute timeout conversion results. - * - * This enumeration defines the possible results of converting - * an absolute time used for timeouts to POSIX blocking calls to - * a number of ticks for example. - */ -typedef enum { - /** The timeout is invalid. */ - TOD_ABSOLUTE_TIMEOUT_INVALID, - /** The timeout represents a time that is in the past. */ - TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST, - /** The timeout represents a time that is equal to the current time. */ - TOD_ABSOLUTE_TIMEOUT_IS_NOW, - /** The timeout represents a time that is in the future. */ - TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE, -} TOD_Absolute_timeout_conversion_results; - -/** - * @brief Convert absolute timeout to ticks. - * - * This method takes an absolute time being used as a timeout - * to a blocking directive, validates it and returns the number - * of corresponding clock ticks for use by the SuperCore. - * - * @param[in] abstime is a pointer to the timeout - * @param[in] clock is the time source to use for the timeout - * @param[out] ticks_out will contain the number of ticks - * - * @return This method returns the number of ticks in @a ticks_out - * and a status value indicating whether the absolute time - * is valid, in the past, equal to the current time or in - * the future as it should be. - */ -TOD_Absolute_timeout_conversion_results _TOD_Absolute_timeout_to_ticks( - const struct timespec *abstime, - clockid_t clock, - Watchdog_Interval *ticks_out -); - /**@}*/ #ifdef __cplusplus diff --git a/cpukit/score/include/rtems/score/watchdog.h b/cpukit/score/include/rtems/score/watchdog.h index a379bf7a23..dbb092bbef 100644 --- a/cpukit/score/include/rtems/score/watchdog.h +++ b/cpukit/score/include/rtems/score/watchdog.h @@ -53,36 +53,9 @@ typedef struct Watchdog_Control Watchdog_Control; typedef uint32_t Watchdog_Interval; /** - * @brief The clock discipline to use for the Watchdog timeout interval. + * @brief Special watchdog ticks value to indicate an infinite wait. */ -typedef enum { - - /** - * @brief Indefinite wait. - * - * This is to indicate there is no timeout and not to use a watchdog. It - * must be equal to 0, which is an illegal relative clock interval, so that - * it may be used as a Watchdog_Interval value with WATCHDOG_RELATIVE to - * express an indefinite wait. - */ - WATCHDOG_NO_TIMEOUT = 0, - - /** - * @brief Relative clock. - * - * The reference time point for the watchdog is current ticks value - * during insert. Time is measured in clock ticks. - */ - WATCHDOG_RELATIVE, - - /** - * @brief Absolute clock. - * - * The reference time point for this header is the POSIX Epoch. Time is - * measured in nanoseconds since POSIX Epoch. - */ - WATCHDOG_ABSOLUTE -} Watchdog_Discipline; +#define WATCHDOG_NO_TIMEOUT 0 /** * @brief Return type from a Watchdog Service Routine. diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h index 1fa67f3961..7866c0ce44 100644 --- a/cpukit/score/include/rtems/score/watchdogimpl.h +++ b/cpukit/score/include/rtems/score/watchdogimpl.h @@ -284,6 +284,11 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Next_first( } } +/** + * @brief The maximum watchdog ticks value for the far future. + */ +#define WATCHDOG_MAXIMUM_TICKS UINT64_MAX + #define WATCHDOG_NANOSECONDS_PER_SECOND 1000000000 /** -- cgit v1.2.3