From 84a539885335c629100a6a12b57ead54bbbc0165 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 21 Apr 2016 06:32:16 +0200 Subject: score: Avoid Giant lock for CORE rwlock Update #2555. --- cpukit/posix/src/prwlockdestroy.c | 72 +++++++++++++-------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) (limited to 'cpukit/posix/src/prwlockdestroy.c') 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 -#include - #include -#include -/** - * 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; } -- cgit v1.2.3