posix: Avoid Giant lock for mutexes

Delete _POSIX_Mutex_Get().  Use _POSIX_Mutex_Get_interrupt_disable()
instead.

Update #2555.
This commit is contained in:
Sebastian Huber
2016-04-19 06:28:03 +02:00
parent bbe654af8f
commit 48b04fc388
9 changed files with 91 additions and 103 deletions

View File

@@ -66,7 +66,6 @@ RTEMS_INLINE_ROUTINE void _POSIX_Mutex_Free(
POSIX_Mutex_Control *the_mutex POSIX_Mutex_Control *the_mutex
) )
{ {
_CORE_mutex_Destroy( &the_mutex->Mutex );
_Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object ); _Objects_Free( &_POSIX_Mutex_Information, &the_mutex->Object );
} }
@@ -119,19 +118,6 @@ RTEMS_INLINE_ROUTINE int _POSIX_Mutex_Translate_core_mutex_return_code(
return _POSIX_Mutex_Return_codes[the_mutex_status]; return _POSIX_Mutex_Return_codes[the_mutex_status];
} }
/**
* @brief POSIX Mutex Get (Thread Dispatch Disable)
*
* A support routine which translates the mutex id into a local pointer.
* As a side-effect, it may create the mutex.
*
* @note This version of the method uses a dispatching critical section.
*/
POSIX_Mutex_Control *_POSIX_Mutex_Get (
pthread_mutex_t *mutex,
Objects_Locations *location
);
/** /**
* @brief POSIX Mutex Get (Interrupt Disable) * @brief POSIX Mutex Get (Interrupt Disable)
* *

View File

@@ -18,14 +18,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <errno.h>
#include <pthread.h>
#include <rtems/system.h>
#include <rtems/score/coremuteximpl.h>
#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h> #include <rtems/posix/muteximpl.h>
#include <rtems/posix/priorityimpl.h>
/* /*
* 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87 * 11.3.2 Initializing and Destroying a Mutex, P1003.1c/Draft 10, p. 87
@@ -35,41 +28,36 @@ int pthread_mutex_destroy(
pthread_mutex_t *mutex pthread_mutex_t *mutex
) )
{ {
register POSIX_Mutex_Control *the_mutex; POSIX_Mutex_Control *the_mutex;
Objects_Locations location; ISR_lock_Context lock_context;
int eno;
_Objects_Allocator_lock(); _Objects_Allocator_lock();
the_mutex = _POSIX_Mutex_Get( mutex, &location );
switch ( location ) {
case OBJECTS_LOCAL: the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex, &lock_context );
/*
* XXX: There is an error for the mutex being locked
* or being in use by a condition variable.
*/
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) { if ( the_mutex != NULL ) {
_Objects_Put( &the_mutex->Object ); _CORE_mutex_Acquire_critical( &the_mutex->Mutex, &lock_context );
_Objects_Allocator_unlock();
return EBUSY;
}
/*
* XXX: There is an error for the mutex being locked
* or being in use by a condition variable.
*/
if ( !_CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object ); _Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
_CORE_mutex_Flush( &the_mutex->Mutex, EINVAL, NULL, 0 ); _CORE_mutex_Release( &the_mutex->Mutex, &lock_context );
_Objects_Put( &the_mutex->Object ); _CORE_mutex_Destroy( &the_mutex->Mutex );
_POSIX_Mutex_Free( the_mutex ); _POSIX_Mutex_Free( the_mutex );
_Objects_Allocator_unlock(); eno = 0;
} else {
return 0; _CORE_mutex_Release( &the_mutex->Mutex, &lock_context );
eno = EBUSY;
#if defined(RTEMS_MULTIPROCESSING) }
case OBJECTS_REMOTE: } else {
#endif eno = EINVAL;
case OBJECTS_ERROR:
break;
} }
_Objects_Allocator_unlock(); _Objects_Allocator_unlock();
return eno;
return EINVAL;
} }

View File

@@ -21,14 +21,9 @@
#include <rtems/posix/muteximpl.h> #include <rtems/posix/muteximpl.h>
#include <rtems/score/apimutex.h> #include <rtems/score/apimutex.h>
static bool _POSIX_Mutex_Check_id_and_auto_init( static bool _POSIX_Mutex_Check_id_and_auto_init( pthread_mutex_t *mutex )
pthread_mutex_t *mutex,
Objects_Locations *location
)
{ {
if ( mutex == NULL ) { if ( mutex == NULL ) {
*location = OBJECTS_ERROR;
return false; return false;
} }
@@ -46,8 +41,6 @@ static bool _POSIX_Mutex_Check_id_and_auto_init(
_Once_Unlock(); _Once_Unlock();
if ( eno != 0 ) { if ( eno != 0 ) {
*location = OBJECTS_ERROR;
return false; return false;
} }
} }
@@ -55,19 +48,6 @@ static bool _POSIX_Mutex_Check_id_and_auto_init(
return true; return true;
} }
POSIX_Mutex_Control *_POSIX_Mutex_Get (
pthread_mutex_t *mutex,
Objects_Locations *location
)
{
if ( !_POSIX_Mutex_Check_id_and_auto_init( mutex, location ) ) {
return NULL;
}
return (POSIX_Mutex_Control *)
_Objects_Get( &_POSIX_Mutex_Information, (Objects_Id) *mutex, location );
}
POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable( POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable(
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
@@ -75,7 +55,7 @@ POSIX_Mutex_Control *_POSIX_Mutex_Get_interrupt_disable(
{ {
Objects_Locations location; Objects_Locations location;
if ( !_POSIX_Mutex_Check_id_and_auto_init( mutex, &location ) ) { if ( !_POSIX_Mutex_Check_id_and_auto_init( mutex ) ) {
return NULL; return NULL;
} }

View File

@@ -18,12 +18,6 @@
#include "config.h" #include "config.h"
#endif #endif
#include <errno.h>
#include <pthread.h>
#include <rtems/system.h>
#include <rtems/score/coremuteximpl.h>
#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h> #include <rtems/posix/muteximpl.h>
#include <rtems/posix/priorityimpl.h> #include <rtems/posix/priorityimpl.h>
@@ -36,28 +30,26 @@ int pthread_mutex_getprioceiling(
int *prioceiling int *prioceiling
) )
{ {
register POSIX_Mutex_Control *the_mutex; POSIX_Mutex_Control *the_mutex;
Objects_Locations location; ISR_lock_Context lock_context;
if ( !prioceiling ) if ( prioceiling == NULL ) {
return EINVAL; return EINVAL;
the_mutex = _POSIX_Mutex_Get( mutex, &location );
switch ( location ) {
case OBJECTS_LOCAL:
*prioceiling = _POSIX_Priority_From_core(
the_mutex->Mutex.Attributes.priority_ceiling
);
_Objects_Put( &the_mutex->Object );
return 0;
#if defined(RTEMS_MULTIPROCESSING)
case OBJECTS_REMOTE:
#endif
case OBJECTS_ERROR:
break;
} }
return EINVAL; the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex, &lock_context );
if ( the_mutex == NULL ) {
return EINVAL;
}
_CORE_mutex_Acquire_critical( &the_mutex->Mutex, &lock_context );
*prioceiling = _POSIX_Priority_From_core(
the_mutex->Mutex.Attributes.priority_ceiling
);
_CORE_mutex_Release( &the_mutex->Mutex, &lock_context );
return 0;
} }

View File

@@ -18,12 +18,6 @@
#include "config.h" #include "config.h"
#endif #endif
#include <errno.h>
#include <pthread.h>
#include <rtems/system.h>
#include <rtems/score/coremuteximpl.h>
#include <rtems/score/watchdog.h>
#include <rtems/posix/muteximpl.h> #include <rtems/posix/muteximpl.h>
#include <rtems/posix/priorityimpl.h> #include <rtems/posix/priorityimpl.h>

View File

@@ -19,6 +19,7 @@
#endif #endif
#include <rtems/posix/muteximpl.h> #include <rtems/posix/muteximpl.h>
#include <rtems/posix/priorityimpl.h>
/* /*
* 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131 * 13.6.2 Change the Priority Ceiling of a Mutex, P1003.1c/Draft 10, p. 131

View File

@@ -49,6 +49,50 @@ void print_schedparam(
#endif #endif
} }
static void *mutex_lock_task(void *arg)
{
pthread_mutex_t *mtx;
int eno;
mtx = arg;
eno = pthread_mutex_lock( mtx );
rtems_test_assert( eno == 0 );
sched_yield();
eno = pthread_mutex_unlock( mtx );
rtems_test_assert( eno == 0 );
return NULL;
}
static void test_destroy_locked_mutex(void)
{
pthread_mutex_t mtx;
pthread_t th;
int eno;
eno = pthread_mutex_init( &mtx, NULL );
rtems_test_assert( eno == 0 );
eno = pthread_create( &th, NULL, mutex_lock_task, &mtx );
rtems_test_assert( eno == 0 );
sched_yield();
eno = pthread_mutex_destroy( &mtx );
rtems_test_assert( eno == EBUSY );
sched_yield();
eno = pthread_mutex_destroy( &mtx );
rtems_test_assert( eno == 0 );
eno = pthread_join( th, NULL );
rtems_test_assert( eno == 0 );
}
void *POSIX_Init( void *POSIX_Init(
void *argument void *argument
) )
@@ -65,6 +109,8 @@ void *POSIX_Init(
TEST_BEGIN(); TEST_BEGIN();
test_destroy_locked_mutex();
/* set the time of day, and print our buffer in multiple ways */ /* set the time of day, and print our buffer in multiple ways */
set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 ); set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );

View File

@@ -23,3 +23,4 @@ concepts:
+ thread priority no longer gets adjusted after obtaining mutex + thread priority no longer gets adjusted after obtaining mutex
+ thread priority gets locked at the ceiling level + thread priority gets locked at the ceiling level
+ unlocks mutex and thread priority is set to low priority successfully + unlocks mutex and thread priority is set to low priority successfully
+ lock returns proper status if deleted during lock operation

View File

@@ -34,7 +34,7 @@ void *Task_2(
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
#define CONFIGURE_MAXIMUM_POSIX_THREADS 1 #define CONFIGURE_MAXIMUM_POSIX_THREADS 2
#define CONFIGURE_MAXIMUM_POSIX_KEYS 10 #define CONFIGURE_MAXIMUM_POSIX_KEYS 10
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 10 #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 10