diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-24 06:13:11 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-11-24 08:46:20 +0100 |
commit | 620b23ece54a0bb43189bb9c0f14adf447cbafe6 (patch) | |
tree | 10aa72eb67ac01ab85f932ac25c09ba3e5d97da8 /cpukit | |
parent | score: Fix interrupt profiling (diff) | |
download | rtems-620b23ece54a0bb43189bb9c0f14adf447cbafe6.tar.bz2 |
score: Optimize _Thread_queue_Enqueue()
Move thread state for _Thread_queue_Enqueue() to the thread queue
context. This reduces the parameter count of _Thread_queue_Enqueue()
from five to four (ARM for example has only four function parameter
registers). Since the thread state is used after several function calls
inside _Thread_queue_Enqueue() this parameter was saved on the stack
previously.
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/posix/src/condwaitsupp.c | 5 | ||||
-rw-r--r-- | cpukit/posix/src/nanosleep.c | 5 | ||||
-rw-r--r-- | cpukit/posix/src/sigtimedwait.c | 5 | ||||
-rw-r--r-- | cpukit/rtems/src/regiongetsegment.c | 5 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/coresemimpl.h | 5 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadq.h | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 52 | ||||
-rw-r--r-- | cpukit/score/src/condition.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/corebarrierwait.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/coremsgseize.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/coremsgsubmit.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/coremutexseize.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/corerwlockobtainread.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/corerwlockobtainwrite.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/futex.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/mpci.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/mutex.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/semaphore.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/threadrestart.c | 2 |
20 files changed, 117 insertions, 28 deletions
diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c index 9024dbf236..589b5e2810 100644 --- a/cpukit/posix/src/condwaitsupp.c +++ b/cpukit/posix/src/condwaitsupp.c @@ -117,6 +117,10 @@ int _POSIX_Condition_variables_Wait_support( executing = _Thread_Executing; if ( !already_timedout ) { + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_CONDITION_VARIABLE + ); _Thread_queue_Context_set_enqueue_callout( &queue_context, _POSIX_Condition_variables_Enqueue_callout @@ -125,7 +129,6 @@ int _POSIX_Condition_variables_Wait_support( &the_cond->Wait_queue.Queue, POSIX_CONDITION_VARIABLES_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_CONDITION_VARIABLE, &queue_context ); error = _POSIX_Get_error_after_wait( executing ); diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c index 5deb2b8c02..10158ff44b 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -47,6 +47,10 @@ static inline int nanosleep_helper( err = 0; _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL + ); _Thread_queue_Context_set_enqueue_callout( &queue_context, _Thread_queue_Enqueue_do_nothing @@ -66,7 +70,6 @@ static inline int nanosleep_helper( &_Nanosleep_Pseudo_queue.Queue, &_Thread_queue_Operations_FIFO, _Thread_Executing, - STATES_DELAYING | STATES_INTERRUPTIBLE_BY_SIGNAL, &queue_context ); diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index 200d75fdf9..f96c32ef45 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -156,12 +156,15 @@ int sigtimedwait( executing->Wait.option = *set; executing->Wait.return_argument = the_info; + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); _Thread_queue_Enqueue( &_POSIX_signals_Wait_queue.Queue, POSIX_SIGNALS_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_SIGNAL | STATES_INTERRUPTIBLE_BY_SIGNAL, &queue_context ); diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c index 04be73bc4b..dfd476ccc0 100644 --- a/cpukit/rtems/src/regiongetsegment.c +++ b/cpukit/rtems/src/regiongetsegment.c @@ -87,6 +87,10 @@ rtems_status_code rtems_region_get_segment( executing->Wait.return_argument = segment; /* FIXME: This is a home grown condition variable */ + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_SEGMENT + ); _Thread_queue_Context_set_enqueue_callout( &queue_context, _Region_Enqueue_callout @@ -96,7 +100,6 @@ rtems_status_code rtems_region_get_segment( &the_region->Wait_queue.Queue, the_region->wait_operations, executing, - STATES_WAITING_FOR_SEGMENT, &queue_context ); return _Status_Get_after_wait( executing ); diff --git a/cpukit/score/include/rtems/score/coresemimpl.h b/cpukit/score/include/rtems/score/coresemimpl.h index 7f5b58e76b..20ca30b366 100644 --- a/cpukit/score/include/rtems/score/coresemimpl.h +++ b/cpukit/score/include/rtems/score/coresemimpl.h @@ -184,12 +184,15 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_semaphore_Seize( return STATUS_UNSATISFIED; } + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_SEMAPHORE + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_semaphore->Wait_queue.Queue, operations, executing, - STATES_WAITING_FOR_SEMAPHORE, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 61ce5fbee2..dec8e13e9e 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -24,6 +24,7 @@ #include <rtems/score/object.h> #include <rtems/score/priority.h> #include <rtems/score/rbtree.h> +#include <rtems/score/states.h> #include <rtems/score/watchdog.h> #ifdef __cplusplus @@ -193,6 +194,11 @@ struct Thread_queue_Context { Thread_queue_Lock_context Lock_context; /** + * @brief The thread state for _Thread_queue_Enqueue(). + */ + States_Control thread_state; + + /** * @brief The enqueue callout for _Thread_queue_Enqueue(). * * The callout is invoked after the release of the thread queue lock with diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 6e3c044aed..bb35b1718b 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -96,6 +96,24 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Context_initialize( } /** + * @brief Sets the thread state for the thread to enqueue in the thread queue + * context. + * + * @param queue_context The thread queue context. + * @param state The thread state. + * + * @see _Thread_queue_Enqueue(). + */ +RTEMS_INLINE_ROUTINE void +_Thread_queue_Context_set_thread_state( + Thread_queue_Context *queue_context, + States_Control thread_state +) +{ + queue_context->thread_state = thread_state; +} + +/** * @brief Sets the enqueue callout in the thread queue context. * * @param queue_context The thread queue context. @@ -557,6 +575,20 @@ Thread_Control *_Thread_queue_Do_dequeue( * to protect the state of objects embedding the thread queue and directly * enter _Thread_queue_Enqueue() in case the thread must block. * + * The thread queue context must be set up with the following functions, + * otherwise the behaviour is unpredictable + * + * - _Thread_queue_Context_set_thread_state(), + * + * - _Thread_queue_Context_set_enqueue_callout() or + * _Thread_queue_Context_set_do_nothing_enqueue_callout(), + * + * - _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_deadlock_callout(). + * * @code * #include <rtems/score/threadqimpl.h> * #include <rtems/score/statesimpl.h> @@ -564,8 +596,7 @@ Thread_Control *_Thread_queue_Do_dequeue( * #define MUTEX_TQ_OPERATIONS &_Thread_queue_Operations_priority * * typedef struct { - * Thread_queue_Control Queue; - * Thread_Control *owner; + * Thread_queue_Control Queue; * } Mutex; * * void _Mutex_Obtain( Mutex *mutex ) @@ -578,17 +609,24 @@ Thread_Control *_Thread_queue_Do_dequeue( * * executing = _Thread_Executing; * - * if ( mutex->owner == NULL ) { - * mutex->owner = executing; + * if ( mutex->Queue.owner == NULL ) { + * mutex->Queue.owner = executing; * _Thread_queue_Release( &mutex->Queue, queue_context ); * } else { + * _Thread_queue_Context_set_thread_state( + * &queue_context, + * STATES_WAITING_FOR_MUTEX + * ); * _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); + * _Thread_queue_Context_set_no_timeout( &queue_context ); + * _Thread_queue_Context_set_deadlock_callout( + * queue_context, + * _Thread_queue_Deadlock_fatal + * ); * _Thread_queue_Enqueue( * &mutex->Queue.Queue, * MUTEX_TQ_OPERATIONS, * executing, - * STATES_WAITING_FOR_MUTEX, - * 0, * &queue_context * ); * } @@ -598,14 +636,12 @@ Thread_Control *_Thread_queue_Do_dequeue( * @param[in] queue The actual thread queue. * @param[in] operations The thread queue operations. * @param[in] the_thread The thread to enqueue. - * @param[in] state The new state of the thread. * @param[in] queue_context The thread queue context of the lock acquire. */ void _Thread_queue_Enqueue( Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, - States_Control state, Thread_queue_Context *queue_context ); diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c index aaf2f4bd67..ea363169fe 100644 --- a/cpukit/score/src/condition.c +++ b/cpukit/score/src/condition.c @@ -109,6 +109,10 @@ static Thread_Control *_Condition_Do_wait( context->mutex = _mutex; condition = _Condition_Get( _condition ); executing = _Condition_Queue_acquire_critical( condition, &context->Base ); + _Thread_queue_Context_set_thread_state( + &context->Base, + STATES_WAITING_FOR_SYS_LOCK_CONDITION + ); _Thread_queue_Context_set_enqueue_callout( &context->Base, _Condition_Enqueue_callout @@ -117,7 +121,6 @@ static Thread_Control *_Condition_Do_wait( &condition->Queue.Queue, CONDITION_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_SYS_LOCK_CONDITION, &context->Base ); diff --git a/cpukit/score/src/corebarrierwait.c b/cpukit/score/src/corebarrierwait.c index 4e8709d355..f47c039e7b 100644 --- a/cpukit/score/src/corebarrierwait.c +++ b/cpukit/score/src/corebarrierwait.c @@ -44,12 +44,15 @@ Status_Control _CORE_barrier_Seize( return STATUS_BARRIER_AUTOMATICALLY_RELEASED; } else { the_barrier->number_of_waiting_threads = number_of_waiting_threads; + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_BARRIER + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_barrier->Wait_queue.Queue, CORE_BARRIER_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_BARRIER, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/coremsgseize.c b/cpukit/score/src/coremsgseize.c index a38f5adf60..b48a3f93d7 100644 --- a/cpukit/score/src/coremsgseize.c +++ b/cpukit/score/src/coremsgseize.c @@ -113,12 +113,15 @@ Status_Control _CORE_message_queue_Seize( executing->Wait.return_argument = size_p; /* Wait.count will be filled in with the message priority */ + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_MESSAGE + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_message_queue->Wait_queue.Queue, the_message_queue->operations, executing, - STATES_WAITING_FOR_MESSAGE, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/coremsgsubmit.c b/cpukit/score/src/coremsgsubmit.c index 8ea7fcf6c8..3c961014e3 100644 --- a/cpukit/score/src/coremsgsubmit.c +++ b/cpukit/score/src/coremsgsubmit.c @@ -131,12 +131,15 @@ Status_Control _CORE_message_queue_Submit( executing->Wait.option = (uint32_t) size; executing->Wait.count = submit_type; + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_MESSAGE + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_message_queue->Wait_queue.Queue, the_message_queue->operations, executing, - STATES_WAITING_FOR_MESSAGE, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index 2fef463f04..4309380627 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -32,6 +32,10 @@ Status_Control _CORE_mutex_Seize_slow( ) { if ( wait ) { + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_MUTEX + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Context_set_deadlock_callout( queue_context, @@ -41,7 +45,6 @@ Status_Control _CORE_mutex_Seize_slow( &the_mutex->Wait_queue.Queue, operations, executing, - STATES_WAITING_FOR_MUTEX, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/corerwlockobtainread.c b/cpukit/score/src/corerwlockobtainread.c index 001d259265..641945635f 100644 --- a/cpukit/score/src/corerwlockobtainread.c +++ b/cpukit/score/src/corerwlockobtainread.c @@ -78,12 +78,15 @@ Status_Control _CORE_RWLock_Seize_for_reading( executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_READ; + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_RWLOCK + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_rwlock->Wait_queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_RWLOCK, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/corerwlockobtainwrite.c b/cpukit/score/src/corerwlockobtainwrite.c index ce47f434b7..7f636daa99 100644 --- a/cpukit/score/src/corerwlockobtainwrite.c +++ b/cpukit/score/src/corerwlockobtainwrite.c @@ -66,12 +66,15 @@ Status_Control _CORE_RWLock_Seize_for_writing( executing->Wait.option = CORE_RWLOCK_THREAD_WAITING_FOR_WRITE; + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_RWLOCK + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Enqueue( &the_rwlock->Wait_queue.Queue, CORE_RWLOCK_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_RWLOCK, queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/futex.c b/cpukit/score/src/futex.c index efac831df5..f200895562 100644 --- a/cpukit/score/src/futex.c +++ b/cpukit/score/src/futex.c @@ -92,6 +92,10 @@ int _Futex_Wait( struct _Futex_Control *_futex, int *uaddr, int val ) executing = _Futex_Queue_acquire_critical( futex, &queue_context ); if ( *uaddr == val ) { + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_SYS_LOCK_FUTEX + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); _Thread_queue_Context_set_no_timeout( &queue_context ); _Thread_queue_Context_set_ISR_level( &queue_context, level ); @@ -99,7 +103,6 @@ int _Futex_Wait( struct _Futex_Control *_futex, int *uaddr, int val ) &futex->Queue.Queue, FUTEX_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_SYS_LOCK_FUTEX, &queue_context ); eno = 0; diff --git a/cpukit/score/src/mpci.c b/cpukit/score/src/mpci.c index 9981ab99ad..2f0a2ded2b 100644 --- a/cpukit/score/src/mpci.c +++ b/cpukit/score/src/mpci.c @@ -253,6 +253,10 @@ Status_Control _MPCI_Send_request_packet( the_packet->timeout = _MPCI_table->default_timeout; _Thread_queue_Context_initialize( &queue_context ); + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_RPC_REPLY | extra_state + ); _Thread_queue_Context_set_enqueue_callout( &queue_context, _MPCI_Enqueue_callout @@ -276,7 +280,6 @@ Status_Control _MPCI_Send_request_packet( &_MPCI_Remote_blocked_threads.Queue, &_Thread_queue_Operations_FIFO, executing, - STATES_WAITING_FOR_RPC_REPLY | extra_state, &queue_context ); return _Thread_Wait_get_status( executing ); diff --git a/cpukit/score/src/mutex.c b/cpukit/score/src/mutex.c index 7c2388df14..edd2e41dfd 100644 --- a/cpukit/score/src/mutex.c +++ b/cpukit/score/src/mutex.c @@ -109,6 +109,10 @@ static void _Mutex_Acquire_slow( Thread_queue_Context *queue_context ) { + _Thread_queue_Context_set_thread_state( + queue_context, + STATES_WAITING_FOR_SYS_LOCK_MUTEX + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( queue_context ); _Thread_queue_Context_set_deadlock_callout( queue_context, @@ -119,7 +123,6 @@ static void _Mutex_Acquire_slow( &mutex->Queue.Queue, MUTEX_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_SYS_LOCK_MUTEX, queue_context ); } diff --git a/cpukit/score/src/semaphore.c b/cpukit/score/src/semaphore.c index 27d3dbfc2f..df33532108 100644 --- a/cpukit/score/src/semaphore.c +++ b/cpukit/score/src/semaphore.c @@ -103,6 +103,10 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem ) sem->count = count - 1; _Semaphore_Queue_release( sem, level, &queue_context ); } else { + _Thread_queue_Context_set_thread_state( + &queue_context, + STATES_WAITING_FOR_SYS_LOCK_SEMAPHORE + ); _Thread_queue_Context_set_do_nothing_enqueue_callout( &queue_context ); _Thread_queue_Context_set_no_timeout( &queue_context ); _Thread_queue_Context_set_ISR_level( &queue_context, level ); @@ -110,7 +114,6 @@ void _Semaphore_Wait( struct _Semaphore_Control *_sem ) &sem->Queue.Queue, SEMAPHORE_TQ_OPERATIONS, executing, - STATES_WAITING_FOR_SYS_LOCK_SEMAPHORE, &queue_context ); } diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index f04f44c9c0..7ffef336b4 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -414,7 +414,6 @@ void _Thread_queue_Enqueue( Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread, - States_Control state, Thread_queue_Context *queue_context ) { @@ -423,7 +422,7 @@ void _Thread_queue_Enqueue( #if defined(RTEMS_MULTIPROCESSING) if ( _Thread_MP_Is_receive( the_thread ) && the_thread->receive_packet ) { - the_thread = _Thread_MP_Allocate_proxy( state ); + the_thread = _Thread_MP_Allocate_proxy( queue_context->thread_state ); } #endif @@ -456,7 +455,7 @@ void _Thread_queue_Enqueue( /* * Set the blocking state for this thread queue in the thread. */ - _Thread_Set_state( the_thread, state ); + _Thread_Set_state( the_thread, queue_context->thread_state ); /* * If the thread wants to timeout, then schedule its timer. diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index dd2e0b8b2d..fc934f6529 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -449,11 +449,11 @@ void _Thread_Join( executing->Wait.return_argument = NULL; #endif + _Thread_queue_Context_set_thread_state( queue_context, waiting_for_join ); _Thread_queue_Enqueue( &the_thread->Join_queue.Queue, THREAD_JOIN_TQ_OPERATIONS, executing, - waiting_for_join, queue_context ); } |