summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-08 10:31:36 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-10-08 11:26:27 +0200
commitb9f952254b7f9afeb287ab6d846a56a512a480d3 (patch)
tree67d466d323a07abad18465bbfa1572097bb645ab
parentposix: Fix mutex auto initialization (diff)
downloadrtems-b9f952254b7f9afeb287ab6d846a56a512a480d3.tar.bz2
posix: Add auto initializaton for rwlock
-rw-r--r--cpukit/posix/include/rtems/posix/rwlockimpl.h24
-rw-r--r--cpukit/posix/src/prwlockdestroy.c3
-rw-r--r--cpukit/posix/src/prwlockinit.c52
-rw-r--r--cpukit/posix/src/prwlockrdlock.c3
-rw-r--r--cpukit/posix/src/prwlocktimedrdlock.c3
-rw-r--r--cpukit/posix/src/prwlocktimedwrlock.c3
-rw-r--r--cpukit/posix/src/prwlocktryrdlock.c3
-rw-r--r--cpukit/posix/src/prwlocktrywrlock.c3
-rw-r--r--cpukit/posix/src/prwlockunlock.c3
-rw-r--r--cpukit/posix/src/prwlockwrlock.c3
-rw-r--r--testsuites/psxtests/psxrwlock01/test.c37
11 files changed, 91 insertions, 46 deletions
diff --git a/cpukit/posix/include/rtems/posix/rwlockimpl.h b/cpukit/posix/include/rtems/posix/rwlockimpl.h
index a62d77638e..48e0a17366 100644
--- a/cpukit/posix/include/rtems/posix/rwlockimpl.h
+++ b/cpukit/posix/include/rtems/posix/rwlockimpl.h
@@ -92,28 +92,10 @@ RTEMS_INLINE_ROUTINE void _POSIX_RWLock_Free (
_Objects_Free( &_POSIX_RWLock_Information, &the_RWLock->Object );
}
-/**
- * @brief Get a RWLock control block.
- *
- * This function maps RWLock IDs to RWLock control blocks.
- * If ID corresponds to a local RWLock, then it returns
- * the_RWLock control pointer which maps to ID and location
- * is set to OBJECTS_LOCAL. if the RWLock ID is global and
- * resides on a remote node, then location is set to OBJECTS_REMOTE,
- * and the_RWLock is undefined. Otherwise, location is set
- * to OBJECTS_ERROR and the_RWLock is undefined.
- */
-RTEMS_INLINE_ROUTINE POSIX_RWLock_Control *_POSIX_RWLock_Get (
- pthread_rwlock_t *RWLock,
+POSIX_RWLock_Control *_POSIX_RWLock_Get(
+ pthread_rwlock_t *rwlock,
Objects_Locations *location
-)
-{
- return (POSIX_RWLock_Control *) _Objects_Get(
- &_POSIX_RWLock_Information,
- (Objects_Id) *RWLock,
- location
- );
-}
+);
#ifdef __cplusplus
}
diff --git a/cpukit/posix/src/prwlockdestroy.c b/cpukit/posix/src/prwlockdestroy.c
index d1261ca4fb..f3e08add06 100644
--- a/cpukit/posix/src/prwlockdestroy.c
+++ b/cpukit/posix/src/prwlockdestroy.c
@@ -41,9 +41,6 @@ int pthread_rwlock_destroy(
POSIX_RWLock_Control *the_rwlock = NULL;
Objects_Locations location;
- if ( !rwlock )
- return EINVAL;
-
_Objects_Allocator_lock();
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/cpukit/posix/src/prwlockinit.c b/cpukit/posix/src/prwlockinit.c
index 94973f6b78..7cf781ff2a 100644
--- a/cpukit/posix/src/prwlockinit.c
+++ b/cpukit/posix/src/prwlockinit.c
@@ -23,8 +23,58 @@
#include <pthread.h>
#include <errno.h>
-#include <rtems/system.h>
#include <rtems/posix/rwlockimpl.h>
+#include <rtems/score/apimutex.h>
+
+static bool _POSIX_RWLock_Check_id_and_auto_init(
+ pthread_mutex_t *rwlock,
+ Objects_Locations *location
+)
+{
+ if ( rwlock == NULL ) {
+ *location = OBJECTS_ERROR;
+
+ return false;
+ }
+
+ if ( *rwlock == PTHREAD_RWLOCK_INITIALIZER ) {
+ int eno;
+
+ _Once_Lock();
+
+ if ( *rwlock == PTHREAD_RWLOCK_INITIALIZER ) {
+ eno = pthread_rwlock_init( rwlock, NULL );
+ } else {
+ eno = 0;
+ }
+
+ _Once_Unlock();
+
+ if ( eno != 0 ) {
+ *location = OBJECTS_ERROR;
+
+ return false;
+ }
+ }
+
+ return true;
+}
+
+POSIX_RWLock_Control *_POSIX_RWLock_Get(
+ pthread_rwlock_t *rwlock,
+ Objects_Locations *location
+)
+{
+ if ( !_POSIX_RWLock_Check_id_and_auto_init( rwlock, location ) ) {
+ return NULL;
+ }
+
+ return (POSIX_RWLock_Control *) _Objects_Get(
+ &_POSIX_RWLock_Information,
+ *rwlock,
+ location
+ );
+}
/*
* pthread_rwlock_init
diff --git a/cpukit/posix/src/prwlockrdlock.c b/cpukit/posix/src/prwlockrdlock.c
index 6e12fb0f74..168a34a8c6 100644
--- a/cpukit/posix/src/prwlockrdlock.c
+++ b/cpukit/posix/src/prwlockrdlock.c
@@ -41,9 +41,6 @@ int pthread_rwlock_rdlock(
Objects_Locations location;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/cpukit/posix/src/prwlocktimedrdlock.c b/cpukit/posix/src/prwlocktimedrdlock.c
index 51c87d7b27..38fcb1a9ad 100644
--- a/cpukit/posix/src/prwlocktimedrdlock.c
+++ b/cpukit/posix/src/prwlocktimedrdlock.c
@@ -50,9 +50,6 @@ int pthread_rwlock_timedrdlock(
POSIX_Absolute_timeout_conversion_results_t status;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
/*
* POSIX requires that blocking calls with timeouts that take
* an absolute timeout must ignore issues with the absolute
diff --git a/cpukit/posix/src/prwlocktimedwrlock.c b/cpukit/posix/src/prwlocktimedwrlock.c
index 0e5b85ca47..2f192d4045 100644
--- a/cpukit/posix/src/prwlocktimedwrlock.c
+++ b/cpukit/posix/src/prwlocktimedwrlock.c
@@ -52,9 +52,6 @@ int pthread_rwlock_timedwrlock(
POSIX_Absolute_timeout_conversion_results_t status;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
/*
* POSIX requires that blocking calls with timeouts that take
* an absolute timeout must ignore issues with the absolute
diff --git a/cpukit/posix/src/prwlocktryrdlock.c b/cpukit/posix/src/prwlocktryrdlock.c
index d88d4f2e1f..6a70de5931 100644
--- a/cpukit/posix/src/prwlocktryrdlock.c
+++ b/cpukit/posix/src/prwlocktryrdlock.c
@@ -45,9 +45,6 @@ int pthread_rwlock_tryrdlock(
Objects_Locations location;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/cpukit/posix/src/prwlocktrywrlock.c b/cpukit/posix/src/prwlocktrywrlock.c
index 79cfb931c4..7afd41a17a 100644
--- a/cpukit/posix/src/prwlocktrywrlock.c
+++ b/cpukit/posix/src/prwlocktrywrlock.c
@@ -45,9 +45,6 @@ int pthread_rwlock_trywrlock(
Objects_Locations location;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/cpukit/posix/src/prwlockunlock.c b/cpukit/posix/src/prwlockunlock.c
index 98056ede75..9b61a5c897 100644
--- a/cpukit/posix/src/prwlockunlock.c
+++ b/cpukit/posix/src/prwlockunlock.c
@@ -47,9 +47,6 @@ int pthread_rwlock_unlock(
Objects_Locations location;
CORE_RWLock_Status status;
- if ( !rwlock )
- return EINVAL;
-
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/cpukit/posix/src/prwlockwrlock.c b/cpukit/posix/src/prwlockwrlock.c
index f6846194c4..67774648ad 100644
--- a/cpukit/posix/src/prwlockwrlock.c
+++ b/cpukit/posix/src/prwlockwrlock.c
@@ -47,9 +47,6 @@ int pthread_rwlock_wrlock(
Objects_Locations location;
Thread_Control *executing;
- if ( !rwlock )
- return EINVAL;
-
the_rwlock = _POSIX_RWLock_Get( rwlock, &location );
switch ( location ) {
diff --git a/testsuites/psxtests/psxrwlock01/test.c b/testsuites/psxtests/psxrwlock01/test.c
index f91f9838c8..e201293328 100644
--- a/testsuites/psxtests/psxrwlock01/test.c
+++ b/testsuites/psxtests/psxrwlock01/test.c
@@ -104,6 +104,7 @@ int main(
#endif
{
pthread_rwlock_t rwlock;
+ pthread_rwlock_t rwlock2;
pthread_rwlockattr_t attr;
int status;
int p;
@@ -153,6 +154,42 @@ int main(
status = pthread_rwlockattr_setpshared( &attr, ~PTHREAD_PROCESS_PRIVATE );
rtems_test_assert( status == EINVAL );
+ /*************** AUTO INITIALIZATION *****************/
+
+ rwlock = PTHREAD_RWLOCK_INITIALIZER;
+ rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
+
+ status = pthread_rwlock_rdlock( &rwlock );
+ rtems_test_assert( status == 0 );
+
+ status = pthread_rwlock_rdlock( &rwlock2 );
+ rtems_test_assert( status == EINVAL );
+
+ status = pthread_rwlock_destroy( &rwlock );
+ rtems_test_assert( status == 0 );
+
+ status = pthread_rwlock_rdlock( &rwlock2 );
+ rtems_test_assert( status == 0 );
+
+ status = pthread_rwlock_destroy( &rwlock );
+ rtems_test_assert( status == 0 );
+
+ rwlock = PTHREAD_RWLOCK_INITIALIZER;
+ rwlock2 = PTHREAD_RWLOCK_INITIALIZER;
+
+ status = pthread_rwlock_rdlock( &rwlock );
+ rtems_test_assert( status == 0 );
+
+ status = pthread_rwlock_destroy( &rwlock2 );
+ rtems_test_assert( status == EINVAL );
+
+ status = pthread_rwlock_destroy( &rwlock );
+ rtems_test_assert( status == 0 );
+
+ status = pthread_rwlock_destroy( &rwlock2 );
+ rtems_test_assert( status == 0 );
+ rtems_test_assert( rwlock2 != PTHREAD_RWLOCK_INITIALIZER );
+
/*************** ACTUALLY WORK THIS TIME *****************/
puts( "pthread_rwlockattr_init( &attr ) -- OK" );
status = pthread_rwlockattr_init( &attr );