diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-04-21 06:32:16 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-04-22 09:25:09 +0200 |
commit | 84a539885335c629100a6a12b57ead54bbbc0165 (patch) | |
tree | ff8d0acd9624e3888dc7fc6df9003a98a19b9b3d /cpukit/posix/src/prwlockdestroy.c | |
parent | score: Avoid Giant lock for barriers (diff) | |
download | rtems-84a539885335c629100a6a12b57ead54bbbc0165.tar.bz2 |
score: Avoid Giant lock for CORE rwlock
Update #2555.
Diffstat (limited to 'cpukit/posix/src/prwlockdestroy.c')
-rw-r--r-- | cpukit/posix/src/prwlockdestroy.c | 72 |
1 files changed, 23 insertions, 49 deletions
diff --git a/cpukit/posix/src/prwlockdestroy.c b/cpukit/posix/src/prwlockdestroy.c index a675b90757..6f9eec8a1d 100644 --- a/cpukit/posix/src/prwlockdestroy.c +++ b/cpukit/posix/src/prwlockdestroy.c @@ -17,68 +17,42 @@ #include "config.h" #endif -#include <pthread.h> -#include <errno.h> - #include <rtems/posix/rwlockimpl.h> -#include <rtems/score/threadqimpl.h> -/** - * This directive allows a thread to delete a rwlock specified by - * the rwlock id. The rwlock is freed back to the inactive - * rwlock chain. - * - * @param[in] rwlock is the rwlock id - * - * @return This method returns 0 if there was not an - * error. Otherwise, a status code is returned indicating the - * source of the error. - */ int pthread_rwlock_destroy( pthread_rwlock_t *rwlock ) { - POSIX_RWLock_Control *the_rwlock = NULL; - Objects_Locations location; + POSIX_RWLock_Control *the_rwlock; + ISR_lock_Context lock_context; _Objects_Allocator_lock(); - the_rwlock = _POSIX_RWLock_Get( rwlock, &location ); - switch ( location ) { + the_rwlock = _POSIX_RWLock_Get( rwlock, &lock_context ); - case OBJECTS_LOCAL: - /* - * If there is at least one thread waiting, then do not delete it. - */ - if ( - _Thread_queue_First( - &the_rwlock->RWLock.Wait_queue, - CORE_RWLOCK_TQ_OPERATIONS - ) != NULL - ) { - _Objects_Put( &the_rwlock->Object ); - _Objects_Allocator_unlock(); - return EBUSY; - } - - /* - * POSIX doesn't require behavior when it is locked. - */ + if ( the_rwlock == NULL ) { + _Objects_Allocator_unlock(); + return EINVAL; + } - _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); - _Objects_Put( &the_rwlock->Object ); - _POSIX_RWLock_Free( the_rwlock ); - _Objects_Allocator_unlock(); + _CORE_RWLock_Acquire_critical( &the_rwlock->RWLock, &lock_context ); - return 0; + /* + * If there is at least one thread waiting, then do not delete it. + */ -#if defined(RTEMS_MULTIPROCESSING) - case OBJECTS_REMOTE: -#endif - case OBJECTS_ERROR: - break; + if ( !_Thread_queue_Is_empty( &the_rwlock->RWLock.Wait_queue.Queue ) ) { + _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); + _Objects_Allocator_unlock(); + return EBUSY; } - _Objects_Allocator_unlock(); + /* + * POSIX doesn't require behavior when it is locked. + */ - return EINVAL; + _Objects_Close( &_POSIX_RWLock_Information, &the_rwlock->Object ); + _CORE_RWLock_Release( &the_rwlock->RWLock, &lock_context ); + _POSIX_RWLock_Free( the_rwlock ); + _Objects_Allocator_unlock(); + return 0; } |