diff options
Diffstat (limited to 'cpukit/score')
-rw-r--r-- | cpukit/score/ChangeLog | 13 | ||||
-rw-r--r-- | cpukit/score/inline/rtems/score/coremutex.inl | 7 | ||||
-rw-r--r-- | cpukit/score/src/coremutex.c | 4 | ||||
-rw-r--r-- | cpukit/score/src/coremutexseize.c | 78 | ||||
-rw-r--r-- | cpukit/score/src/coremutexsurrender.c | 26 |
5 files changed, 76 insertions, 52 deletions
diff --git a/cpukit/score/ChangeLog b/cpukit/score/ChangeLog index 08d486a6d6..f12205258e 100644 --- a/cpukit/score/ChangeLog +++ b/cpukit/score/ChangeLog @@ -1,6 +1,19 @@ 2001-08-30 Joel Sherrill <joel@OARcorp.com> + * src/coremutex.c, src/coremutexseize.c, src/coremutexsurrender.c, + inline/rtems/score/coremutex.inl: The per thread field resource_count + should only be manipulated when a mutex is priority ceiling or + priority inherit. This was reported by Chris Johns <ccj@acm.org> + who also noticed that the use of switches for all disciplines + generated less efficient code than using explicit tests for the one + or two cases we were really interested in. Further review of his + modifications made it apparent that the "isa" methods to test mutex + discipline were not being used so this modification was swept into + the code as well. + +2001-08-30 Joel Sherrill <joel@OARcorp.com> + * src/coremutexseize.c: Add missing code for proper handling of nesting acquisitions. This only impacts building with inlines disabled on the source with the "fast mutex" optimizations. diff --git a/cpukit/score/inline/rtems/score/coremutex.inl b/cpukit/score/inline/rtems/score/coremutex.inl index fe783b3d91..b57b2ef2f4 100644 --- a/cpukit/score/inline/rtems/score/coremutex.inl +++ b/cpukit/score/inline/rtems/score/coremutex.inl @@ -134,9 +134,10 @@ RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock( the_mutex->holder = executing; the_mutex->holder_id = executing->Object.id; the_mutex->nest_count = 1; - executing->resource_count++; - if ( the_mutex->Attributes.discipline != - CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING ) { + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) + executing->resource_count++; + if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { _ISR_Enable( level ); return 0; } diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c index ef2c21adc6..8edb80fcfb 100644 --- a/cpukit/score/src/coremutex.c +++ b/cpukit/score/src/coremutex.c @@ -73,7 +73,9 @@ void _CORE_mutex_Initialize( the_mutex->nest_count = 1; the_mutex->holder = _Thread_Executing; the_mutex->holder_id = _Thread_Executing->Object.id; - _Thread_Executing->resource_count++; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) + _Thread_Executing->resource_count++; } else { the_mutex->nest_count = 0; the_mutex->holder = NULL; diff --git a/cpukit/score/src/coremutexseize.c b/cpukit/score/src/coremutexseize.c index a4aadb7410..2fb2fc27e9 100644 --- a/cpukit/score/src/coremutexseize.c +++ b/cpukit/score/src/coremutexseize.c @@ -43,41 +43,33 @@ void _CORE_mutex_Seize_interrupt_blocking( Thread_Control *executing; executing = _Thread_Executing; - switch ( the_mutex->Attributes.discipline ) { - case CORE_MUTEX_DISCIPLINES_FIFO: - case CORE_MUTEX_DISCIPLINES_PRIORITY: - case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: - break; - case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: - if ( the_mutex->holder->current_priority > executing->current_priority ) { - _Thread_Change_priority( - the_mutex->holder, - executing->current_priority, - FALSE - ); - } - break; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) { + if ( the_mutex->holder->current_priority > executing->current_priority ) { + _Thread_Change_priority( + the_mutex->holder, + executing->current_priority, + FALSE + ); + } } the_mutex->blocked_count++; _Thread_queue_Enqueue( &the_mutex->Wait_queue, timeout ); if ( _Thread_Executing->Wait.return_code == CORE_MUTEX_STATUS_SUCCESSFUL ) { - switch ( the_mutex->Attributes.discipline ) { - case CORE_MUTEX_DISCIPLINES_FIFO: - case CORE_MUTEX_DISCIPLINES_PRIORITY: - case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: - break; - case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: - if ( the_mutex->Attributes.priority_ceiling < - executing->current_priority ) { - _Thread_Change_priority( - executing, - the_mutex->Attributes.priority_ceiling, - FALSE - ); - }; - break; + /* + * if CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT then nothing to do + * because this task is already the highest priority. + */ + + if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { + if (the_mutex->Attributes.priority_ceiling < executing->current_priority){ + _Thread_Change_priority( + executing, + the_mutex->Attributes.priority_ceiling, + FALSE + ); + } } } _Thread_Enable_dispatch(); @@ -101,11 +93,13 @@ int _CORE_mutex_Seize_interrupt_trylock( the_mutex->holder = executing; the_mutex->holder_id = executing->Object.id; the_mutex->nest_count = 1; - executing->resource_count++; - if ( the_mutex->Attributes.discipline != - CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING ) { - _ISR_Enable( level ); - return 0; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) + executing->resource_count++; + + if ( !_CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { + _ISR_Enable( level ); + return 0; } /* else must be CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING */ { @@ -139,6 +133,22 @@ int _CORE_mutex_Seize_interrupt_trylock( } return 0; } + + if ( _Thread_Is_executing( the_mutex->holder ) ) { + switch ( the_mutex->Attributes.lock_nesting_behavior ) { + case CORE_MUTEX_NESTING_ACQUIRES: + the_mutex->nest_count++; + _ISR_Enable( level ); + return 0; + case CORE_MUTEX_NESTING_IS_ERROR: + executing->Wait.return_code = CORE_MUTEX_STATUS_NESTING_NOT_ALLOWED; + _ISR_Enable( level ); + return 0; + case CORE_MUTEX_NESTING_BLOCKS: + break; + } + } + return 1; } #endif diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index f60faba558..bd9cc5bf65 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -86,7 +86,9 @@ CORE_mutex_Status _CORE_mutex_Surrender( } } - holder->resource_count--; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) + holder->resource_count--; the_mutex->holder = NULL; the_mutex->holder_id = 0; @@ -96,20 +98,14 @@ CORE_mutex_Status _CORE_mutex_Surrender( * mutex (i.e. resource) this task has. */ - switch ( the_mutex->Attributes.discipline ) { - case CORE_MUTEX_DISCIPLINES_FIFO: - case CORE_MUTEX_DISCIPLINES_PRIORITY: - break; - case CORE_MUTEX_DISCIPLINES_PRIORITY_CEILING: - case CORE_MUTEX_DISCIPLINES_PRIORITY_INHERIT: - if ( holder->resource_count == 0 && - holder->real_priority != holder->current_priority ) { - _Thread_Change_priority( holder, holder->real_priority, TRUE ); - } - break; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { + if ( holder->resource_count == 0 && + holder->real_priority != holder->current_priority ) { + _Thread_Change_priority( holder, holder->real_priority, TRUE ); + } } - if ( ( the_thread = _Thread_queue_Dequeue( &the_mutex->Wait_queue ) ) ) { #if defined(RTEMS_MULTIPROCESSING) @@ -127,7 +123,9 @@ CORE_mutex_Status _CORE_mutex_Surrender( the_mutex->holder = the_thread; the_mutex->holder_id = the_thread->Object.id; - the_thread->resource_count++; + if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) + the_thread->resource_count++; the_mutex->nest_count = 1; /* |