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
)
{
_CORE_mutex_Destroy( &the_mutex->Mutex );
_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];
}
/**
* @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)
*

View File

@@ -18,14 +18,7 @@
#include "config.h"
#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/priorityimpl.h>
/*
* 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
)
{
register POSIX_Mutex_Control *the_mutex;
Objects_Locations location;
POSIX_Mutex_Control *the_mutex;
ISR_lock_Context lock_context;
int eno;
_Objects_Allocator_lock();
the_mutex = _POSIX_Mutex_Get( mutex, &location );
switch ( location ) {
case OBJECTS_LOCAL:
/*
* XXX: There is an error for the mutex being locked
* or being in use by a condition variable.
*/
the_mutex = _POSIX_Mutex_Get_interrupt_disable( mutex, &lock_context );
if ( _CORE_mutex_Is_locked( &the_mutex->Mutex ) ) {
_Objects_Put( &the_mutex->Object );
_Objects_Allocator_unlock();
return EBUSY;
}
if ( the_mutex != NULL ) {
_CORE_mutex_Acquire_critical( &the_mutex->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 ) ) {
_Objects_Close( &_POSIX_Mutex_Information, &the_mutex->Object );
_CORE_mutex_Flush( &the_mutex->Mutex, EINVAL, NULL, 0 );
_Objects_Put( &the_mutex->Object );
_CORE_mutex_Release( &the_mutex->Mutex, &lock_context );
_CORE_mutex_Destroy( &the_mutex->Mutex );
_POSIX_Mutex_Free( the_mutex );
_Objects_Allocator_unlock();
return 0;
#if defined(RTEMS_MULTIPROCESSING)
case OBJECTS_REMOTE:
#endif
case OBJECTS_ERROR:
break;
eno = 0;
} else {
_CORE_mutex_Release( &the_mutex->Mutex, &lock_context );
eno = EBUSY;
}
} else {
eno = EINVAL;
}
_Objects_Allocator_unlock();
return EINVAL;
return eno;
}

View File

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

View File

@@ -18,12 +18,6 @@
#include "config.h"
#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/priorityimpl.h>
@@ -36,28 +30,26 @@ int pthread_mutex_getprioceiling(
int *prioceiling
)
{
register POSIX_Mutex_Control *the_mutex;
Objects_Locations location;
POSIX_Mutex_Control *the_mutex;
ISR_lock_Context lock_context;
if ( !prioceiling )
if ( prioceiling == NULL ) {
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"
#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/priorityimpl.h>

View File

@@ -19,6 +19,7 @@
#endif
#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

View File

@@ -49,6 +49,50 @@ void print_schedparam(
#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 *argument
)
@@ -65,6 +109,8 @@ void *POSIX_Init(
TEST_BEGIN();
test_destroy_locked_mutex();
/* set the time of day, and print our buffer in multiple ways */
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 gets locked at the ceiling level
+ 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_MAXIMUM_POSIX_THREADS 1
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
#define CONFIGURE_MAXIMUM_POSIX_KEYS 10
#define CONFIGURE_MAXIMUM_POSIX_MUTEXES 10