diff options
Diffstat (limited to 'cpukit/score/include')
-rw-r--r-- | cpukit/score/include/rtems/score/coresemimpl.h | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/interr.h | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadimpl.h | 11 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadq.h | 32 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 45 |
5 files changed, 72 insertions, 20 deletions
diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index 44e1672570..d097b3d76c 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -184,7 +184,7 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize( return STATUS_UNSATISFIED; } - _Thread_queue_Context_set_expected_level( queue_context, 1 ); + _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue_critical( &the_semaphore->Wait_queue.Queue, operations, diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h index 4e499d8198..33c000049a 100644 --- a/cpukit/score/include/rtems/score/interr.h +++ b/cpukit/score/include/rtems/score/interr.h @@ -154,7 +154,7 @@ typedef enum { INTERNAL_ERROR_BAD_ATTRIBUTES, INTERNAL_ERROR_IMPLEMENTATION_KEY_CREATE_INCONSISTENCY, OBSOLETE_INTERNAL_ERROR_IMPLEMENTATION_BLOCKING_OPERATION_CANCEL, - INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_FROM_BAD_STATE, + OBSOLETE_INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_FROM_BAD_STATE, INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0, OBSOLETE_INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP, INTERNAL_ERROR_GXX_KEY_ADD_FAILED, diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 61694461b4..a38b23c2b6 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -245,6 +245,11 @@ void _Thread_Cancel( void *exit_value ); +typedef struct { + Thread_queue_Context Base; + Thread_Control *cancel; +} Thread_Close_context; + /** * @brief Closes the thread. * @@ -252,7 +257,11 @@ void _Thread_Cancel( * case the executing thread is not terminated, then this function waits until * the terminating thread reached the zombie state. */ -void _Thread_Close( Thread_Control *the_thread, Thread_Control *executing ); +void _Thread_Close( + Thread_Control *the_thread, + Thread_Control *executing, + Thread_Close_context *context +); RTEMS_INLINE_ROUTINE bool _Thread_Is_ready( const Thread_Control *the_thread ) { diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 084161cc4d..df03cfb96a 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -45,11 +45,28 @@ struct Scheduler_Node; typedef struct _Thread_Control Thread_Control; +typedef struct Thread_queue_Context Thread_queue_Context; + typedef struct Thread_queue_Queue Thread_queue_Queue; typedef struct Thread_queue_Operations Thread_queue_Operations; /** + * @brief Thread queue enqueue callout. + * + * @param[in] queue The actual thread queue. + * @param[in] the_thread The thread to enqueue. + * @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 +); + +/** * @brief Thread queue deadlock callout. * * @param the_thread The thread that detected the deadlock. @@ -168,7 +185,7 @@ typedef struct { * * @see _Thread_queue_Context_initialize(). */ -typedef struct { +struct Thread_queue_Context { /** * @brief The lock context for the thread queue acquire and release * operations. @@ -176,13 +193,14 @@ typedef struct { Thread_queue_Lock_context Lock_context; /** - * @brief The expected thread dispatch disable level for - * _Thread_queue_Enqueue_critical(). + * @brief The enqueue callout for _Thread_queue_Enqueue_critical(). + * + * The callout is invoked after the release of the thread queue lock with + * thread dispatching disabled. Afterwards the thread is blocked. * - * In case the actual thread dispatch disable level is not equal to the - * expected level, then a fatal error occurs. + * @see _Thread_queue_Enqueue_do_nothing(). */ - uint32_t expected_thread_dispatch_disable_level; + Thread_queue_Enqueue_callout enqueue_callout; /** * @brief The clock discipline for the interval timeout. @@ -274,7 +292,7 @@ typedef struct { */ Thread_queue_MP_callout mp_callout; #endif -} Thread_queue_Context; +}; /** * @brief Thread priority queue. diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 45f552a103..232e9601ac 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -61,6 +61,12 @@ typedef struct { Thread_queue_Queue Queue; } Thread_queue_Syslock_queue; +void _Thread_queue_Enqueue_do_nothing( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Thread_queue_Context *queue_context +); + /** * @brief Sets the thread wait return code to STATUS_DEADLOCK. */ @@ -82,7 +88,7 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize( { #if defined(RTEMS_DEBUG) memset( queue_context, 0, sizeof( *queue_context ) ); - queue_context->expected_thread_dispatch_disable_level = 0xdeadbeef; + queue_context->enqueue_callout = _Thread_queue_Enqueue_do_nothing; queue_context->deadlock_callout = _Thread_queue_Deadlock_fatal; #else (void) queue_context; @@ -90,21 +96,35 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize( } /** - * @brief Sets the expected thread dispatch disable level in the thread queue - * context. + * @brief Sets the enqueue callout in the thread queue context. * * @param queue_context The thread queue context. - * @param expected_level The expected thread dispatch disable level. + * @param enqueue_callout The enqueue callout. * * @see _Thread_queue_Enqueue_critical(). */ RTEMS_INLINE_ROUTINE void -_Thread_queue_Context_set_expected_level( - Thread_queue_Context *queue_context, - uint32_t expected_level +_Thread_queue_Context_set_enqueue_callout( + Thread_queue_Context *queue_context, + Thread_queue_Enqueue_callout enqueue_callout +) +{ + queue_context->enqueue_callout = enqueue_callout; +} + +/** + * @brief Sets the do nothing enqueue callout in the thread queue context. + * + * @param queue_context The thread queue context. + * + * @see _Thread_queue_Enqueue_critical(). + */ +RTEMS_INLINE_ROUTINE void +_Thread_queue_Context_set_do_nothing_enqueue_callout( + Thread_queue_Context *queue_context ) { - queue_context->expected_thread_dispatch_disable_level = expected_level; + queue_context->enqueue_callout = _Thread_queue_Enqueue_do_nothing; } /** @@ -562,7 +582,7 @@ Thread_Control *_Thread_queue_Do_dequeue( * mutex->owner = executing; * _Thread_queue_Release( &mutex->Queue, queue_context ); * } else { - * _Thread_queue_Context_set_expected_level( &queue_context, 1 ); + * _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); * _Thread_queue_Enqueue_critical( * &mutex->Queue.Queue, * MUTEX_TQ_OPERATIONS, @@ -638,12 +658,17 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue( _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Acquire( the_thread_queue, &queue_context ); - _Thread_queue_Context_set_expected_level( &queue_context, expected_level ); + _Thread_queue_Context_set_enqueue_callout( + &queue_context, + _Thread_queue_Enqueue_do_nothing + ); + if ( discipline == WATCHDOG_ABSOLUTE ) { _Thread_queue_Context_set_absolute_timeout( &queue_context, timeout ); } else { _Thread_queue_Context_set_relative_timeout( &queue_context, timeout ); } + _Thread_queue_Enqueue_critical( &the_thread_queue->Queue, operations, |