From bba3507723041f451c9da1ecee43819bcbe57f23 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 19 Aug 2014 17:43:36 +0200 Subject: score: PR2179: Fix initially locked PI mutex --- cpukit/score/src/coremutex.c | 15 +++++++++++---- testsuites/sptests/sp51/init.c | 36 ++++++++++++++++++++++++++++++++++++ testsuites/sptests/sp51/sp51.doc | 3 +++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/cpukit/score/src/coremutex.c b/cpukit/score/src/coremutex.c index e13c7aafac..949aa703ba 100644 --- a/cpukit/score/src/coremutex.c +++ b/cpukit/score/src/coremutex.c @@ -39,10 +39,14 @@ CORE_mutex_Status _CORE_mutex_Initialize( the_mutex->Attributes = *the_mutex_attributes; if ( initially_locked ) { + bool is_priority_ceiling = + _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ); + the_mutex->nest_count = 1; the_mutex->holder = executing; - if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) || - _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) { + + if ( is_priority_ceiling || + _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) { Priority_Control ceiling = the_mutex->Attributes.priority_ceiling; /* @@ -52,7 +56,7 @@ CORE_mutex_Status _CORE_mutex_Initialize( */ _Thread_Disable_dispatch(); - if ( executing->current_priority < ceiling ) { + if ( is_priority_ceiling && executing->current_priority < ceiling ) { _Thread_Enable_dispatch(); return CORE_MUTEX_STATUS_CEILING_VIOLATED; } @@ -65,7 +69,10 @@ CORE_mutex_Status _CORE_mutex_Initialize( executing->resource_count++; - _Thread_Change_priority( executing, ceiling, false ); + if ( is_priority_ceiling ) { + _Thread_Change_priority( executing, ceiling, false ); + } + _Thread_Enable_dispatch(); } } else { diff --git a/testsuites/sptests/sp51/init.c b/testsuites/sptests/sp51/init.c index 98d362f89c..48f0146aa3 100644 --- a/testsuites/sptests/sp51/init.c +++ b/testsuites/sptests/sp51/init.c @@ -18,6 +18,40 @@ const char rtems_test_name[] = "SP 51"; /* forward declarations to avoid warnings */ rtems_task Init(rtems_task_argument argument); +static void test_create_initially_locked_prio_inherit_sema(void) +{ + rtems_status_code sc; + rtems_id id; + rtems_task_priority prio_a; + rtems_task_priority prio_b; + rtems_task_priority prio_ceiling = 0; + + sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &prio_a); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(prio_a != prio_ceiling); + + sc = rtems_semaphore_create( + rtems_build_name( 'S', 'E', 'M', 'A' ), + 0, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, + prio_ceiling, + &id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_priority(RTEMS_SELF, RTEMS_CURRENT_PRIORITY, &prio_b); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + rtems_test_assert(prio_a == prio_b); + + sc = rtems_semaphore_release(id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_delete(id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + rtems_task Init( rtems_task_argument argument ) @@ -57,6 +91,8 @@ rtems_task Init( fatal_directive_status( sc, RTEMS_NOT_OWNER_OF_RESOURCE, "rtems_semaphore_release" ); + test_create_initially_locked_prio_inherit_sema(); + TEST_END(); rtems_test_exit( 0 ); } diff --git a/testsuites/sptests/sp51/sp51.doc b/testsuites/sptests/sp51/sp51.doc index a1003dba99..fac553475e 100644 --- a/testsuites/sptests/sp51/sp51.doc +++ b/testsuites/sptests/sp51/sp51.doc @@ -23,3 +23,6 @@ concepts: + Ensure the when the binary semaphore lock fails to acquire the mutex, it is an error to release it since the lock failed. + ++ Verify that creation of an initially locked priority inheritance mutex does + not change the priority of the executing thread. -- cgit v1.2.3