[PATCH 1/1] v2: Implement clockrdlock / clockwrlock and test

Matt Joyce mfjoyce2004 at gmail.com
Mon Oct 11 11:23:32 UTC 2021


Added implementations of the pthread_rwlock_clockrdlock and the
pthread_rwlock_clockwrlock methods to cpukit/posix/src. Both of these
methods have been newly added to the POSIX Issue 8 Standard.

Added psxrwlock02 test to testsuites/psxtests to test the newly
added methods.
---
 cpukit/posix/src/prwlockclockrdlock.c         | 111 +++++
 cpukit/posix/src/prwlockclockwrlock.c         | 112 +++++
 spec/build/testsuites/psxtests/grp.yml        |   2 +
 .../build/testsuites/psxtests/psxrwlock02.yml |  21 +
 testsuites/psxtests/Makefile.am               |   9 +
 testsuites/psxtests/configure.ac              |   1 +
 testsuites/psxtests/psxrwlock02/main.c        | 391 ++++++++++++++++++
 7 files changed, 647 insertions(+)
 create mode 100644 cpukit/posix/src/prwlockclockrdlock.c
 create mode 100644 cpukit/posix/src/prwlockclockwrlock.c
 create mode 100644 spec/build/testsuites/psxtests/psxrwlock02.yml
 create mode 100644 testsuites/psxtests/psxrwlock02/main.c

diff --git a/cpukit/posix/src/prwlockclockrdlock.c b/cpukit/posix/src/prwlockclockrdlock.c
new file mode 100644
index 0000000000..1d7dfc2cd8
--- /dev/null
+++ b/cpukit/posix/src/prwlockclockrdlock.c
@@ -0,0 +1,111 @@
+/**
+ * @file
+ *
+ * @ingroup POSIXAPI
+ *
+ * @brief Attempt to Obtain a Read Lock on a RWLock Instance
+ */
+
+/*
+ *  POSIX RWLock Manager -- Attempt to Obtain a Read Lock on a RWLock Instance.
+ *  The timeout is specified by abstime on the clock specified by clock_id.
+ */
+
+/* 
+* Copyright (C) 2021 Matthew Joyce
+* COPYRIGHT (c) 1989-2008
+* On-Line Applications Research Corporation (OAR)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* Defining to have access to function prototype in libc/include/pthread.h */
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/posix/rwlockimpl.h>
+#include <rtems/posix/posixapi.h>
+#include <stdio.h>
+
+/* The POSIX Issue 8 Standard adds pthread_rwlock_clockrdlock */
+int pthread_rwlock_clockrdlock(
+  pthread_rwlock_t      *rwlock,
+  clockid_t             clock_id,
+  const struct timespec *abstime
+)
+{
+  POSIX_RWLock_Control  *the_rwlock;
+  Thread_queue_Context  queue_context;
+  Status_Control        status;
+
+  the_rwlock = _POSIX_RWLock_Get( rwlock );
+  POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
+
+  _Thread_queue_Context_initialize( &queue_context );
+
+  /* 
+   * The POSIX Issue 8 Standard specifies a return value of EINVAL if
+   * the abstime nsec value is less than zero or greater than or equal to
+   * 1 billion.  
+   */
+  if ( abstime->tv_nsec < 0 ) {
+    return EINVAL; 
+  }
+	
+  if ( abstime->tv_nsec >= 1000000000 ) {
+    return EINVAL; 
+  }
+
+  if ( clock_id == CLOCK_REALTIME ) {
+    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+      &queue_context,
+      abstime,
+      true
+    );
+  }
+  
+  else if ( clock_id == CLOCK_MONOTONIC ) {
+    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+      &queue_context,
+      abstime,
+      true
+    );
+  }
+
+  /* 
+   * The POSIX Issue 8 Standard specifies a return value of EINVAL if
+   * the clock_id parameter is not CLOCK_REALTIME or CLOCK_MONOTONIC 
+   */
+  else {
+    return EINVAL;
+  }
+
+  status = _CORE_RWLock_Seize_for_reading(
+    &the_rwlock->RWLock,
+    true,
+    &queue_context
+  );
+  return _POSIX_Get_error( status );
+}
diff --git a/cpukit/posix/src/prwlockclockwrlock.c b/cpukit/posix/src/prwlockclockwrlock.c
new file mode 100644
index 0000000000..ac17ae13f8
--- /dev/null
+++ b/cpukit/posix/src/prwlockclockwrlock.c
@@ -0,0 +1,112 @@
+/**
+ * @file
+ *
+ * @ingroup POSIXAPI
+ *
+ * @brief Attempt to Obtain a Write lock on a RWLock instance 
+ */
+
+/*
+ *  POSIX RWLock Manager -- Attempt to Obtain a Write Lock on a RWLock Instance
+ *  The timeout is specified by abstime on the clock specified by clock_id.
+ */
+
+/* 
+* Copyright (C) 2021 Matthew Joyce
+* COPYRIGHT (c) 1989-2008
+* On-Line Applications Research Corporation (OAR)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* Defining to have access to function prototype in libc/include/pthread.h */
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/posix/rwlockimpl.h>
+#include <rtems/posix/posixapi.h>
+#include <stdio.h>
+
+
+/* The POSIX Issue 8 Standard adds pthread_rwlock_clockwrlock */
+int pthread_rwlock_clockwrlock(
+  pthread_rwlock_t      *rwlock,
+  clockid_t             clock_id,
+  const struct timespec *abstime
+)
+{
+  POSIX_RWLock_Control  *the_rwlock;
+  Thread_queue_Context  queue_context;
+  Status_Control        status;
+
+  the_rwlock = _POSIX_RWLock_Get( rwlock );
+  POSIX_RWLOCK_VALIDATE_OBJECT( the_rwlock );
+
+  _Thread_queue_Context_initialize( &queue_context );
+	
+  /* 
+   * The POSIX Issue 8 Standard specifies a return value of EINVAL if
+   * the abstime nsec value is less than zero or greater than or equal to
+   * 1 billion.  
+   */
+  if ( abstime->tv_nsec < 0 ) {
+		return EINVAL; 
+	}
+
+  if ( abstime->tv_nsec >= 1000000000 ) {
+		return EINVAL; 
+	}
+
+  if ( clock_id == CLOCK_REALTIME ) {
+    _Thread_queue_Context_set_enqueue_timeout_realtime_timespec(
+      &queue_context,
+      abstime,
+      true
+    );
+  }
+  
+  else if ( clock_id == CLOCK_MONOTONIC ) {
+    _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec(
+      &queue_context,
+      abstime,
+      true
+    );
+  }
+	
+  /* 
+   * The POSIX Issue 8 Standard specifies a return value of EINVAL if
+   * the clock_id parameter is not CLOCK_REALTIME or CLOCK_MONOTONIC 
+   */
+  else {
+    return EINVAL;
+  }
+  
+  status = _CORE_RWLock_Seize_for_writing(
+    &the_rwlock->RWLock,
+    true,
+    &queue_context
+  );
+  return _POSIX_Get_error( status );
+}
diff --git a/spec/build/testsuites/psxtests/grp.yml b/spec/build/testsuites/psxtests/grp.yml
index fb7ce465ae..51b8d1d758 100644
--- a/spec/build/testsuites/psxtests/grp.yml
+++ b/spec/build/testsuites/psxtests/grp.yml
@@ -183,6 +183,8 @@ links:
   uid: psxreaddir
 - role: build-dependency
   uid: psxrwlock01
+- role: build-dependency
+  uid: psxrwlock02
 - role: build-dependency
   uid: psxsem01
 - role: build-dependency
diff --git a/spec/build/testsuites/psxtests/psxrwlock02.yml b/spec/build/testsuites/psxtests/psxrwlock02.yml
new file mode 100644
index 0000000000..8ee4434f78
--- /dev/null
+++ b/spec/build/testsuites/psxtests/psxrwlock02.yml
@@ -0,0 +1,21 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+cppflags: []
+cxxflags: []
+enabled-by: true
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/psxtests/psxrwlock02/main.c
+- cpukit/posix/src/prwlockclockrdlock.c
+- cpukit/posix/src/prwlockclockwrlock.c
+stlib: []
+target: testsuites/psxtests/psxrwlock02.exe
+type: build
+use-after: []
+use-before: []
diff --git a/testsuites/psxtests/Makefile.am b/testsuites/psxtests/Makefile.am
index a35f00b665..6e3c30a012 100755
--- a/testsuites/psxtests/Makefile.am
+++ b/testsuites/psxtests/Makefile.am
@@ -811,6 +811,15 @@ psxrwlock01_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_psxrwlock01) \
 	$(support_includes) -I$(top_srcdir)/include
 endif
 
+if TEST_psxrwlock02
+psx_tests += psxrwlock02
+psx_screens += psxrwlock02/psxrwlock02.scn
+psxrwlock02_SOURCES = psxrwlock02/main.c psxrwlock02/test.c \
+	include/pmacros.h
+psxrwlock02_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_psxrwlock02) \
+	$(support_includes) -I$(top_srcdir)/include
+endif
+
 if TEST_psxsem01
 psx_tests += psxsem01
 psx_screens += psxsem01/psxsem01.scn
diff --git a/testsuites/psxtests/configure.ac b/testsuites/psxtests/configure.ac
index 3f95010cd3..a49f809d54 100644
--- a/testsuites/psxtests/configure.ac
+++ b/testsuites/psxtests/configure.ac
@@ -127,6 +127,7 @@ RTEMS_TEST_CHECK([psxpipe01])
 RTEMS_TEST_CHECK([psxrdwrv])
 RTEMS_TEST_CHECK([psxreaddir])
 RTEMS_TEST_CHECK([psxrwlock01])
+RTEMS_TEST_CHECK([psxrwlock02])
 RTEMS_TEST_CHECK([psxsem01])
 RTEMS_TEST_CHECK([psxshm01])
 RTEMS_TEST_CHECK([psxshm02])
diff --git a/testsuites/psxtests/psxrwlock02/main.c b/testsuites/psxtests/psxrwlock02/main.c
new file mode 100644
index 0000000000..b5e9b0de10
--- /dev/null
+++ b/testsuites/psxtests/psxrwlock02/main.c
@@ -0,0 +1,391 @@
+/* 
+* Copyright (C) 2021 Matthew Joyce
+* COPYRIGHT (c) 1989-2008
+* On-Line Applications Research Corporation (OAR)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* Defining to have access to function prototype in libc/include/pthread.h */
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test-info.h>
+#include <bsp.h>
+#include <pmacros.h>
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "tmacros.h"
+
+#define BAD_CLOCK 0xdeadbeef
+
+const char rtems_test_name[] = "PSXRWLOCK 2";
+pthread_rwlock_t RWLock;
+
+static void test_rwlock_auto_initialization( void )
+{
+  struct timespec to;
+  int eno;
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockrdlock( &rw, BAD_CLOCK, &to );
+    rtems_test_assert( eno == EINVAL );
+  }
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockwrlock( &rw, BAD_CLOCK, &to );
+    rtems_test_assert( eno == EINVAL );
+  }
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
+    rtems_test_assert( eno == 0 );
+  }
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockrdlock( &rw, CLOCK_REALTIME, &to );
+    rtems_test_assert( eno == 0 );
+  }
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
+    rtems_test_assert( eno == 0 );
+  }
+
+  {
+    static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER;
+
+    to.tv_sec = 1;
+    to.tv_nsec = 1;
+    eno = pthread_rwlock_clockwrlock( &rw, CLOCK_REALTIME, &to );
+    rtems_test_assert( eno == 0 );
+  }
+}
+
+static void test_rwlock_null( void )
+{
+  struct timespec to;
+  int eno;
+	
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( NULL, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( NULL, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( NULL, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( NULL, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+}
+
+static void test_invalid_clock( void )
+{
+  pthread_rwlock_t rw;
+  struct timespec to;
+  int eno;
+	
+  eno = pthread_rwlock_init( &rw, NULL );
+  rtems_test_assert( eno == 0 );
+	
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( &rw, BAD_CLOCK, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( &rw, BAD_CLOCK, &to );
+  rtems_test_assert( eno == EINVAL );
+}
+
+static void test_invalid_abstime( void )
+{
+  pthread_rwlock_t rw;
+  struct timespec to;
+  int eno;
+
+  eno = pthread_rwlock_init( &rw, NULL );
+  rtems_test_assert( eno == 0 );
+	
+  to.tv_sec = 1;
+  to.tv_nsec = -1;
+  eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1000000000;
+  eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+
+  to.tv_sec = 1;
+  to.tv_nsec = 1100000000;
+  eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+
+  to.tv_sec = 1;
+  to.tv_nsec = -1;
+  eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1000000000;
+  eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+
+  to.tv_sec = 1;
+  to.tv_nsec = 1100000000;
+  eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+}
+
+static void test_rwlock_invalid_copy( void )
+{
+  pthread_rwlock_t rw;
+  pthread_rwlock_t rw2;
+  struct timespec to;
+  int eno;
+
+  eno = pthread_rwlock_init( &rw, NULL );
+  rtems_test_assert( eno == 0 );
+
+  memcpy( &rw2, &rw, sizeof( rw2 ) );
+	
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( &rw2, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( &rw2, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( &rw2, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( &rw2, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+}
+
+static void test_rwlock_not_initialized( void )
+{
+  pthread_rwlock_t rw;
+  struct timespec to;
+  int eno;
+
+  memset( &rw, 0xff, sizeof( rw ) );
+	
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockrdlock( &rw, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( &rw, CLOCK_MONOTONIC, &to );
+  rtems_test_assert( eno == EINVAL );
+  
+  to.tv_sec = 1;
+  to.tv_nsec = 1;
+  eno = pthread_rwlock_clockwrlock( &rw, CLOCK_REALTIME, &to );
+  rtems_test_assert( eno == EINVAL );
+}
+
+static void *POSIX_Init(
+  void *argument
+)
+{
+  int                  status;
+  struct timespec      abstime;
+	
+  TEST_BEGIN();
+
+  test_rwlock_auto_initialization();
+  test_rwlock_null();
+  test_invalid_clock();
+  test_invalid_abstime(); 
+  test_rwlock_invalid_copy();	
+  test_rwlock_not_initialized();
+	
+  /*************** TIMEOUT ON RWLOCK MONOTONIC ***************/
+  status = pthread_rwlock_init( &RWLock, NULL );
+  rtems_test_assert( status == 0 );
+
+  status = clock_gettime( CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec += 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec += 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+
+  /*************** OBTAIN RWLOCK FOR READ WITH ABSTIME IN PAST ***************/
+  status = pthread_rwlock_unlock( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == 0 );
+
+  /*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
+  status = pthread_rwlock_unlock( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime );
+  rtems_test_assert( status == 0 );
+
+  /*************** DESTROY RWLOCK ***************/
+  status = pthread_rwlock_destroy( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  /*************** TIMEOUT ON RWLOCK REALTIME ***************/
+  status = pthread_rwlock_init( &RWLock, NULL );
+  rtems_test_assert( status == 0 );
+
+  status = clock_gettime( CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec += 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec += 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == ETIMEDOUT );
+  
+  /*************** OBTAIN RWLOCK FOR READ WITH ABSTIME IN PAST ***************/
+  status = pthread_rwlock_unlock( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == 0 );
+
+  /*************** OBTAIN RWLOCK FOR WRITE WITH ABSTIME IN PAST ***************/
+  status = pthread_rwlock_unlock( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  abstime.tv_sec -= 1;
+  status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_REALTIME, &abstime );
+  rtems_test_assert( status == 0 );
+
+  /*************** DESTROY RWLOCK ***************/
+  status = pthread_rwlock_destroy( &RWLock );
+  rtems_test_assert( status == 0 );
+
+  /*************** END OF TEST *****************/
+  TEST_END();
+  rtems_test_exit( 0 );
+
+  return NULL; /* just so the compiler thinks we returned something */
+}
+
+/* configuration information */
+
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE 
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+#define CONFIGURE_POSIX_INIT_THREAD_STACK_SIZE (RTEMS_MINIMUM_STACK_SIZE * 2)
+
+#define CONFIGURE_INIT_TASK_PRIORITY 2
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_PREEMPT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/* end of file */
-- 
2.31.1



More information about the devel mailing list