From f929bcba5b2d2ea84ecd29d1dfb94f7d677f8d14 Mon Sep 17 00:00:00 2001 From: Mazen Adel Elmessady Date: Tue, 1 Jul 2025 03:25:16 +0300 Subject: [PATCH] cpukit/posix: Added pthread clock functions Added pthread_cond_clockwait(), pthread_mutex_clocklock() pthread_rwlock_clockrdlock() and pthread_rwlock_clockwrlock() that are new in POSIX Issue 8. Also added tests. The implementation used the timed versions of these functions as a reference. Updates rtems/programs/gsoc#69 --- cpukit/include/rtems/posix/condimpl.h | 3 +- cpukit/posix/src/condclockwait.c | 65 +++++++ cpukit/posix/src/condtimedwait.c | 12 +- cpukit/posix/src/condwait.c | 3 +- cpukit/posix/src/condwaitsupp.c | 3 +- cpukit/posix/src/mutexclocklock.c | 63 +++++++ cpukit/posix/src/prwlockclockrdlock.c | 81 +++++++++ cpukit/posix/src/prwlockclockwrlock.c | 81 +++++++++ spec/build/bsps/tstsmallmem.yml | 5 + spec/build/cpukit/librtemscpu.yml | 4 + spec/build/testsuites/psxtmtests/grp.yml | 10 ++ .../testsuites/psxtmtests/psxtmcond11.yml | 21 +++ .../testsuites/psxtmtests/psxtmcond12.yml | 21 +++ .../testsuites/psxtmtests/psxtmmutex08.yml | 21 +++ .../testsuites/psxtmtests/psxtmrwlock08.yml | 21 +++ .../testsuites/psxtmtests/psxtmrwlock09.yml | 21 +++ testsuites/psxtests/psx05/init.c | 55 ++++++ testsuites/psxtests/psx05/psx05.doc | 1 + testsuites/psxtests/psx05/psx05.scn | 6 + testsuites/psxtests/psx10/init.c | 91 ++++++++++ testsuites/psxtests/psx10/psx10.scn | 8 + testsuites/psxtests/psxautoinit02/init.c | 8 + .../psxtests/psxautoinit02/psxautoinit02.scn | 2 + .../psxtests/psxrwlock01/psxrwlock01.scn | 20 ++- testsuites/psxtests/psxrwlock01/test.c | 143 ++++++++++++++++ .../psxtmtests/psxtmcond08/psxtmcond08.doc | 1 + .../psxtmtests/psxtmcond08/psxtmcond08impl.h | 28 ++++ testsuites/psxtmtests/psxtmcond11/init.c | 20 +++ .../psxtmtests/psxtmcond11/psxtmcond11.doc | 45 +++++ testsuites/psxtmtests/psxtmcond12/init.c | 20 +++ .../psxtmtests/psxtmcond12/psxtmcond12.doc | 45 +++++ testsuites/psxtmtests/psxtmmutex03/init.c | 44 +++++ .../psxtmtests/psxtmmutex03/psxtmmutex03.doc | 4 + .../psxtmtests/psxtmmutex03/psxtmmutex03.scn | 18 +- testsuites/psxtmtests/psxtmmutex08/init.c | 144 ++++++++++++++++ .../psxtmtests/psxtmmutex08/psxtmmutex08.doc | 29 ++++ .../psxtmtests/psxtmmutex08/psxtmmutex08.scn | 3 + testsuites/psxtmtests/psxtmrwlock01/init.c | 48 ++++++ .../psxtmrwlock01/psxtmrwlock01.doc | 2 + testsuites/psxtmtests/psxtmrwlock08/init.c | 158 ++++++++++++++++++ .../psxtmrwlock08/psxtmrwlock08.doc | 29 ++++ testsuites/psxtmtests/psxtmrwlock09/init.c | 156 +++++++++++++++++ .../psxtmrwlock09/psxtmrwlock09.doc | 29 ++++ testsuites/psxtmtests/psxtmtests_plan.csv | 8 + 44 files changed, 1587 insertions(+), 13 deletions(-) create mode 100644 cpukit/posix/src/condclockwait.c create mode 100644 cpukit/posix/src/mutexclocklock.c create mode 100644 cpukit/posix/src/prwlockclockrdlock.c create mode 100644 cpukit/posix/src/prwlockclockwrlock.c create mode 100644 spec/build/testsuites/psxtmtests/psxtmcond11.yml create mode 100644 spec/build/testsuites/psxtmtests/psxtmcond12.yml create mode 100644 spec/build/testsuites/psxtmtests/psxtmmutex08.yml create mode 100644 spec/build/testsuites/psxtmtests/psxtmrwlock08.yml create mode 100644 spec/build/testsuites/psxtmtests/psxtmrwlock09.yml create mode 100644 testsuites/psxtmtests/psxtmcond11/init.c create mode 100644 testsuites/psxtmtests/psxtmcond11/psxtmcond11.doc create mode 100644 testsuites/psxtmtests/psxtmcond12/init.c create mode 100644 testsuites/psxtmtests/psxtmcond12/psxtmcond12.doc create mode 100644 testsuites/psxtmtests/psxtmmutex08/init.c create mode 100644 testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.doc create mode 100644 testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.scn create mode 100644 testsuites/psxtmtests/psxtmrwlock08/init.c create mode 100644 testsuites/psxtmtests/psxtmrwlock08/psxtmrwlock08.doc create mode 100644 testsuites/psxtmtests/psxtmrwlock09/init.c create mode 100644 testsuites/psxtmtests/psxtmrwlock09/psxtmrwlock09.doc diff --git a/cpukit/include/rtems/posix/condimpl.h b/cpukit/include/rtems/posix/condimpl.h index 5bbc35c4b3..c293c940f6 100644 --- a/cpukit/include/rtems/posix/condimpl.h +++ b/cpukit/include/rtems/posix/condimpl.h @@ -171,7 +171,8 @@ int _POSIX_Condition_variables_Signal_support( int _POSIX_Condition_variables_Wait_support( pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime + const struct timespec *abstime, + clockid_t clock_id ); bool _POSIX_Condition_variables_Auto_initialization( diff --git a/cpukit/posix/src/condclockwait.c b/cpukit/posix/src/condclockwait.c new file mode 100644 index 0000000000..4ce2ff4f88 --- /dev/null +++ b/cpukit/posix/src/condclockwait.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup POSIXAPI + * + * @brief This source file contains the implementation of pthread_cond_clockwait(). + */ + +/* + * Copyright (C) 2025, Mazen Adel Elmessady + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +int pthread_cond_clockwait( + pthread_cond_t *cond, + pthread_mutex_t *mutex, + clockid_t clock_id, + const struct timespec *abstime +) +{ + if ( abstime == NULL ) { + return EINVAL; + } + + if ( !_POSIX_Is_valid_clock_id( clock_id ) ) + { + return EINVAL; + } + + return _POSIX_Condition_variables_Wait_support( + cond, + mutex, + abstime, + clock_id + ); +} diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c index 258e38a357..1906709c74 100644 --- a/cpukit/posix/src/condtimedwait.c +++ b/cpukit/posix/src/condtimedwait.c @@ -50,12 +50,22 @@ int pthread_cond_timedwait( const struct timespec *abstime ) { + POSIX_Condition_variables_Control *the_cond; + unsigned long flags; + clockid_t clock_id; + if ( abstime == NULL ) { return EINVAL; /* not specified */ } + + the_cond = _POSIX_Condition_variables_Get( cond ); + POSIX_CONDITION_VARIABLES_VALIDATE_OBJECT( the_cond, flags ); + clock_id = _POSIX_Condition_variables_Get_clock( flags ); + return _POSIX_Condition_variables_Wait_support( cond, mutex, - abstime + abstime, + clock_id ); } diff --git a/cpukit/posix/src/condwait.c b/cpukit/posix/src/condwait.c index 5f505abce5..fb8fd64141 100644 --- a/cpukit/posix/src/condwait.c +++ b/cpukit/posix/src/condwait.c @@ -73,6 +73,7 @@ int pthread_cond_wait( return _POSIX_Condition_variables_Wait_support( cond, mutex, - NULL + NULL, + CLOCK_REALTIME ); } diff --git a/cpukit/posix/src/condwaitsupp.c b/cpukit/posix/src/condwaitsupp.c index 861ad35a4a..ba5cc828b6 100644 --- a/cpukit/posix/src/condwaitsupp.c +++ b/cpukit/posix/src/condwaitsupp.c @@ -97,7 +97,8 @@ static void _POSIX_Condition_variables_Enqueue_with_timeout_by_clock_id( int _POSIX_Condition_variables_Wait_support( pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime + const struct timespec *abstime, + clockid_t clock_id ) { POSIX_Condition_variables_Control *the_cond; diff --git a/cpukit/posix/src/mutexclocklock.c b/cpukit/posix/src/mutexclocklock.c new file mode 100644 index 0000000000..a56f1e2181 --- /dev/null +++ b/cpukit/posix/src/mutexclocklock.c @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup POSIXAPI + * + * @brief This source file contains the implementation of pthread_mutex_clocklock(). + */ + +/* + * Copyright (C) 2025, Mazen Adel Elmessady + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +int pthread_mutex_clocklock( + pthread_mutex_t *mutex, + clockid_t clock_id, + const struct timespec *abstime +) +{ + if ( clock_id == CLOCK_REALTIME ) { + return _POSIX_Mutex_Lock_support( + mutex, + abstime, + _Thread_queue_Add_timeout_realtime_timespec + ); + } else if ( clock_id == CLOCK_MONOTONIC ) { + return _POSIX_Mutex_Lock_support( + mutex, + abstime, + _Thread_queue_Add_timeout_monotonic_timespec + ); + } + + return EINVAL; +} \ No newline at end of file diff --git a/cpukit/posix/src/prwlockclockrdlock.c b/cpukit/posix/src/prwlockclockrdlock.c new file mode 100644 index 0000000000..58075dac4a --- /dev/null +++ b/cpukit/posix/src/prwlockclockrdlock.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup POSIXAPI + * + * @brief This source file contains the implementation of + * pthread_rwlock_clockrdlock(). + */ + +/* + * Copyright (C) 2025, Mazen Adel Elmessady + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +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 ); + + 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 + ); + } else { + return EINVAL; + } + + status = _CORE_RWLock_Seize_for_reading( + &the_rwlock->RWLock, + true, + &queue_context + ); + return _POSIX_Get_error( status ); +} \ No newline at end of file diff --git a/cpukit/posix/src/prwlockclockwrlock.c b/cpukit/posix/src/prwlockclockwrlock.c new file mode 100644 index 0000000000..ab6fd2c9e5 --- /dev/null +++ b/cpukit/posix/src/prwlockclockwrlock.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup POSIXAPI + * + * @brief This source file contains the implementation of + * pthread_rwlock_clockwrlock(). + */ + +/* + * Copyright (C) 2025, Mazen Adel Elmessady + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +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 ); + + 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 + ); + } else { + return EINVAL; + } + + status = _CORE_RWLock_Seize_for_writing( + &the_rwlock->RWLock, + true, + &queue_context + ); + return _POSIX_Get_error( status ); +} \ No newline at end of file diff --git a/spec/build/bsps/tstsmallmem.yml b/spec/build/bsps/tstsmallmem.yml index f62fb2b72f..6d0e6c5265 100644 --- a/spec/build/bsps/tstsmallmem.yml +++ b/spec/build/bsps/tstsmallmem.yml @@ -60,6 +60,8 @@ actions: - append-test-cppflags: psxtmcond08 - append-test-cppflags: psxtmcond09 - append-test-cppflags: psxtmcond10 +- append-test-cppflags: psxtmcond11 +- append-test-cppflags: psxtmcond12 - append-test-cppflags: psxtmkey01 - append-test-cppflags: psxtmkey02 - append-test-cppflags: psxtmmq01 @@ -72,6 +74,7 @@ actions: - append-test-cppflags: psxtmmutex05 - append-test-cppflags: psxtmmutex06 - append-test-cppflags: psxtmmutex07 +- append-test-cppflags: psxtmmutex08 - append-test-cppflags: psxtmmutexattr01 - append-test-cppflags: psxtmnanosleep01 - append-test-cppflags: psxtmnanosleep02 @@ -83,6 +86,8 @@ actions: - append-test-cppflags: psxtmrwlock05 - append-test-cppflags: psxtmrwlock06 - append-test-cppflags: psxtmrwlock07 +- append-test-cppflags: psxtmrwlock08 +- append-test-cppflags: psxtmrwlock09 - append-test-cppflags: psxtmsem01 - append-test-cppflags: psxtmsem02 - append-test-cppflags: psxtmsem03 diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index 29a763484f..48793bc850 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -1032,6 +1032,7 @@ source: - cpukit/posix/src/condattrsetclock.c - cpukit/posix/src/condattrsetpshared.c - cpukit/posix/src/condbroadcast.c +- cpukit/posix/src/condclockwait.c - cpukit/posix/src/conddefaultattributes.c - cpukit/posix/src/conddestroy.c - cpukit/posix/src/condinit.c @@ -1081,6 +1082,7 @@ source: - cpukit/posix/src/mutexattrsetprotocol.c - cpukit/posix/src/mutexattrsetpshared.c - cpukit/posix/src/mutexattrsettype.c +- cpukit/posix/src/mutexclocklock.c - cpukit/posix/src/mutexdestroy.c - cpukit/posix/src/mutexgetprioceiling.c - cpukit/posix/src/mutexinit.c @@ -1095,6 +1097,8 @@ source: - cpukit/posix/src/pbarrierinit.c - cpukit/posix/src/pbarrierwait.c - cpukit/posix/src/posix_madvise.c +- cpukit/posix/src/prwlockclockrdlock.c +- cpukit/posix/src/prwlockclockwrlock.c - cpukit/posix/src/prwlockdestroy.c - cpukit/posix/src/prwlockinit.c - cpukit/posix/src/prwlockrdlock.c diff --git a/spec/build/testsuites/psxtmtests/grp.yml b/spec/build/testsuites/psxtmtests/grp.yml index 27fd02a29e..b99d7227c1 100644 --- a/spec/build/testsuites/psxtmtests/grp.yml +++ b/spec/build/testsuites/psxtmtests/grp.yml @@ -53,6 +53,10 @@ links: uid: psxtmcond09 - role: build-dependency uid: psxtmcond10 +- role: build-dependency + uid: psxtmcond11 +- role: build-dependency + uid: psxtmcond12 - role: build-dependency uid: psxtmkey01 - role: build-dependency @@ -77,6 +81,8 @@ links: uid: psxtmmutex06 - role: build-dependency uid: psxtmmutex07 +- role: build-dependency + uid: psxtmmutex08 - role: build-dependency uid: psxtmmutexattr01 - role: build-dependency @@ -99,6 +105,10 @@ links: uid: psxtmrwlock06 - role: build-dependency uid: psxtmrwlock07 +- role: build-dependency + uid: psxtmrwlock08 +- role: build-dependency + uid: psxtmrwlock09 - role: build-dependency uid: psxtmsem01 - role: build-dependency diff --git a/spec/build/testsuites/psxtmtests/psxtmcond11.yml b/spec/build/testsuites/psxtmtests/psxtmcond11.yml new file mode 100644 index 0000000000..9be2fd43ff --- /dev/null +++ b/spec/build/testsuites/psxtmtests/psxtmcond11.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) 2025 Mazen Adel Elmessady +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtmtests/psxtmcond11/init.c +- testsuites/support/src/tmtests_empty_function.c +- testsuites/support/src/tmtests_support.c +stlib: [] +target: testsuites/psxtmtests/psxtmcond11.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/psxtmtests/psxtmcond12.yml b/spec/build/testsuites/psxtmtests/psxtmcond12.yml new file mode 100644 index 0000000000..4884baa38c --- /dev/null +++ b/spec/build/testsuites/psxtmtests/psxtmcond12.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) 2025 Mazen Adel Elmessady +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtmtests/psxtmcond12/init.c +- testsuites/support/src/tmtests_empty_function.c +- testsuites/support/src/tmtests_support.c +stlib: [] +target: testsuites/psxtmtests/psxtmcond12.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/psxtmtests/psxtmmutex08.yml b/spec/build/testsuites/psxtmtests/psxtmmutex08.yml new file mode 100644 index 0000000000..4dc19f7ac7 --- /dev/null +++ b/spec/build/testsuites/psxtmtests/psxtmmutex08.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) 2025 Mazen Adel Elmessady +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtmtests/psxtmmutex08/init.c +- testsuites/support/src/tmtests_empty_function.c +- testsuites/support/src/tmtests_support.c +stlib: [] +target: testsuites/psxtmtests/psxtmmutex08.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/psxtmtests/psxtmrwlock08.yml b/spec/build/testsuites/psxtmtests/psxtmrwlock08.yml new file mode 100644 index 0000000000..39abaf5264 --- /dev/null +++ b/spec/build/testsuites/psxtmtests/psxtmrwlock08.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) 2025 Mazen Adel Elmessady +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtmtests/psxtmrwlock08/init.c +- testsuites/support/src/tmtests_empty_function.c +- testsuites/support/src/tmtests_support.c +stlib: [] +target: testsuites/psxtmtests/psxtmrwlock08.exe +type: build +use-after: [] +use-before: [] diff --git a/spec/build/testsuites/psxtmtests/psxtmrwlock09.yml b/spec/build/testsuites/psxtmtests/psxtmrwlock09.yml new file mode 100644 index 0000000000..f738927bb1 --- /dev/null +++ b/spec/build/testsuites/psxtmtests/psxtmrwlock09.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) 2025 Mazen Adel Elmessady +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/psxtmtests/psxtmrwlock09/init.c +- testsuites/support/src/tmtests_empty_function.c +- testsuites/support/src/tmtests_support.c +stlib: [] +target: testsuites/psxtmtests/psxtmrwlock09.exe +type: build +use-after: [] +use-before: [] diff --git a/testsuites/psxtests/psx05/init.c b/testsuites/psxtests/psx05/init.c index 96a7b2740b..4483037227 100644 --- a/testsuites/psxtests/psx05/init.c +++ b/testsuites/psxtests/psx05/init.c @@ -292,6 +292,7 @@ static void test_mutex_null( void ) { struct timespec to; int eno; + clockid_t clock_id; eno = pthread_mutex_destroy( NULL ); rtems_test_assert( eno == EINVAL ); @@ -307,6 +308,10 @@ static void test_mutex_null( void ) eno = pthread_mutex_timedlock( NULL, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_mutex_clocklock( NULL, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_trylock( NULL ); rtems_test_assert( eno == EINVAL ); @@ -319,6 +324,7 @@ static void test_mutex_not_initialized( void ) pthread_mutex_t mutex; struct timespec to; int eno; + clockid_t clock_id; memset( &mutex, 0xff, sizeof( mutex ) ); @@ -333,6 +339,10 @@ static void test_mutex_not_initialized( void ) eno = pthread_mutex_timedlock( &mutex, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_mutex_clocklock( NULL, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_trylock( &mutex ); rtems_test_assert( eno == EINVAL ); @@ -346,6 +356,7 @@ static void test_mutex_invalid_copy( void ) pthread_mutex_t mutex2; struct timespec to; int eno; + clockid_t clock_id; eno = pthread_mutex_init( &mutex, NULL ); rtems_test_assert( eno == 0 ); @@ -363,6 +374,10 @@ static void test_mutex_invalid_copy( void ) eno = pthread_mutex_timedlock( &mutex2, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_mutex_clocklock( NULL, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_trylock( &mutex2 ); rtems_test_assert( eno == EINVAL ); @@ -377,6 +392,7 @@ static void test_mutex_auto_initialization( void ) { struct timespec to; int eno; + clockid_t clock_id; { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -410,6 +426,16 @@ static void test_mutex_auto_initialization( void ) rtems_test_assert( eno == 0 ); } + { + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_mutex_clocklock( &mutex, clock_id, &to ); + rtems_test_assert( eno == 0 ); + } + { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; @@ -432,6 +458,7 @@ static void test_mutex_prio_protect_with_cv( void ) pthread_cond_t cond; int eno; struct timespec timeout; + clockid_t clock_id; eno = pthread_mutexattr_init( &attr ); rtems_test_assert( eno == 0 ); @@ -457,6 +484,10 @@ static void test_mutex_prio_protect_with_cv( void ) eno = pthread_cond_timedwait( &cond, &mutex, &timeout ); rtems_test_assert( eno == ETIMEDOUT ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_cond_clockwait( &cond, &mutex, clock_id, &timeout ); + rtems_test_assert( eno == ETIMEDOUT ); + eno = pthread_mutex_unlock( &mutex ); rtems_test_assert( eno == 0 ); @@ -482,6 +513,7 @@ void *POSIX_Init( int ceiling; int old_ceiling; int priority; + clockid_t clock_id; Mutex_bad_id = NULL; @@ -818,6 +850,29 @@ void *POSIX_Init( /* destroy a mutex */ + clock_id = CLOCK_REALTIME; + puts( "Init: pthread_mutex_clocklock - time out in 1/2 second" ); + calculate_abstimeout( ×, 0, (TOD_NANOSECONDS_PER_SECOND / 2) ); + + status = pthread_mutex_clocklock( &Mutex_id, clock_id,× ); + if ( status != ETIMEDOUT ) + printf( "status = %d\n", status ); + rtems_test_assert( status == ETIMEDOUT ); + + puts( "Init: pthread_mutex_clocklock - time out in the past" ); + calculate_abstimeout( ×, -1, (TOD_NANOSECONDS_PER_SECOND / 2) ); + + status = pthread_mutex_clocklock( &Mutex_id, clock_id, × ); + if ( status != ETIMEDOUT ) + printf( "status = %d\n", status ); + rtems_test_assert( status == ETIMEDOUT ); + + /* switch to idle */ + + puts( "Init: pthread_mutex_clocklock - EAGAIN (timeout)" ); + + /* destroy a mutex */ + empty_line(); puts( "Init: pthread_mutex_init - SUCCESSFUL" ); diff --git a/testsuites/psxtests/psx05/psx05.doc b/testsuites/psxtests/psx05/psx05.doc index 9a69fa3de6..f63704942d 100644 --- a/testsuites/psxtests/psx05/psx05.doc +++ b/testsuites/psxtests/psx05/psx05.doc @@ -43,6 +43,7 @@ directives: + pthread_mutex_lock + pthread_mutex_unlock + pthread_mutex_timedlock ++ pthread_mutex_clocklock + pthread_mutex_destroy + pthread_setschedparam + pthread_getschedparam diff --git a/testsuites/psxtests/psx05/psx05.scn b/testsuites/psxtests/psx05/psx05.scn index 700f3bfb4f..61638375fe 100644 --- a/testsuites/psxtests/psx05/psx05.scn +++ b/testsuites/psxtests/psx05/psx05.scn @@ -65,6 +65,9 @@ Task: mutex acquired Task: sleep for 2 seconds Init: pthread_mutex_timedlock - time out in the past Init: pthread_mutex_timedlock - EAGAIN (timeout) +Init: pthread_mutex_clocklock - time out in 1/2 second +Init: pthread_mutex_clocklock - time out in the past +Init: pthread_mutex_clocklock - EAGAIN (timeout) Init: pthread_mutex_init - SUCCESSFUL Init: pthread_mutex_init - SUCCESSFUL @@ -111,9 +114,12 @@ Init: pthread_getschedparam - priority = 2 Init: pthread_setschedparam - set Task3 priority to highest Init: Sleep 1 second Task 3: pthread_mutex_lock unavailable (inherit case) +Task: exit Init: pthread_mutex_unlock - SUCCESSFUL Task 3: mutex acquired Task 3: unlock Mutex 2 +Task 3: pthread_getschedparam priority = 199 +Task 3: exit Init: pthread_mutex_getprioceiling- ceiling = 200 Init: pthread_setschedparam - set Init priority to highest Init: pthread_mutex_lock - EINVAL (priority ceiling violation) diff --git a/testsuites/psxtests/psx10/init.c b/testsuites/psxtests/psx10/init.c index 90ed097133..c2555845d4 100644 --- a/testsuites/psxtests/psx10/init.c +++ b/testsuites/psxtests/psx10/init.c @@ -41,6 +41,7 @@ static void test_cond_null( void ) pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; int eno; struct timespec to; + clockid_t clock_id; eno = pthread_cond_init( NULL, NULL ); rtems_test_assert( eno == EINVAL ); @@ -56,6 +57,10 @@ static void test_cond_null( void ) eno = pthread_cond_timedwait( NULL, &mtx, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_cond_clockwait( NULL, &mtx, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_unlock( &mtx ); rtems_test_assert( eno == 0 ); @@ -78,6 +83,7 @@ static void test_cond_not_initialized( void ) pthread_cond_t cond; int eno; struct timespec to; + clockid_t clock_id; memset( &cond, 0xff, sizeof( cond ) ); @@ -92,6 +98,10 @@ static void test_cond_not_initialized( void ) eno = pthread_cond_timedwait( &cond, &mtx, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_cond_clockwait( &cond, &mtx, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_unlock( &mtx ); rtems_test_assert( eno == 0 ); @@ -115,6 +125,7 @@ static void test_cond_invalid_copy( void ) pthread_cond_t cond2; int eno; struct timespec to; + clockid_t clock_id; eno = pthread_cond_init( &cond, NULL ); rtems_test_assert( eno == 0 ); @@ -132,6 +143,10 @@ static void test_cond_invalid_copy( void ) eno = pthread_cond_timedwait( &cond2, &mtx, &to ); rtems_test_assert( eno == EINVAL ); + clock_id = CLOCK_MONOTONIC; + eno = pthread_cond_clockwait( &cond2, &mtx, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_mutex_unlock( &mtx ); rtems_test_assert( eno == 0 ); @@ -161,6 +176,7 @@ void *POSIX_Init( int pshared; pthread_cond_t cond; struct timespec timeout; + clockid_t clock_id; TEST_BEGIN(); @@ -331,6 +347,29 @@ void *POSIX_Init( status = pthread_mutex_unlock( &Mutex_id ); rtems_test_assert( !status ); +/* clockwait case - timeout */ + + status = pthread_mutex_lock( &Mutex_id ); + rtems_test_assert( !status ); + +/* set timeout to 3 seconds */ + + status = clock_gettime( CLOCK_REALTIME, &timeout ); + rtems_test_assert( !status ); + timeout.tv_sec += 3; + timeout.tv_nsec = 0; + clock_id = CLOCK_REALTIME; + + puts( "Init: pthread_cond_clockwait for 3 seconds" ); + status = pthread_cond_clockwait( &Cond1_id, &Mutex_id, clock_id ,&timeout ); + if ( status != ETIMEDOUT ) + printf( "status = %d\n", status ); + rtems_test_assert( status == ETIMEDOUT ); + puts( "Init: pthread_cond_clockwait - ETIMEDOUT - (mutex not acquired)" ); + + status = pthread_mutex_unlock( &Mutex_id ); + rtems_test_assert( !status ); + /* remaining error messages */ empty_line(); @@ -366,6 +405,12 @@ void *POSIX_Init( rtems_test_assert( status == EINVAL ); puts( "Init: pthread_cond_timedwait - EINVAL (cond invalid)" ); + status = pthread_cond_clockwait( NULL, &Mutex_id, clock_id, &timeout ); + if ( status != EINVAL ) + printf( "status = %d\n", status ); + rtems_test_assert( status == EINVAL ); + puts( "Init: pthread_cond_clockwait - EINVAL (cond invalid)" ); + status = pthread_cond_wait( &Cond1_id, NULL ); if ( status != EINVAL ) printf( "status = %d\n", status ); @@ -378,12 +423,31 @@ void *POSIX_Init( rtems_test_assert( status == EINVAL ); puts( "Init: pthread_cond_timedwait - EINVAL (mutex invalid)" ); + status = pthread_cond_clockwait( &Cond1_id, NULL, clock_id, &timeout ); + if ( status != EINVAL ) + printf( "status = %d\n", status ); + rtems_test_assert( status == EINVAL ); + puts( "Init: pthread_cond_clockwait - EINVAL (mutex invalid)" ); + status = pthread_cond_timedwait( &Cond1_id, &Mutex_id, NULL ); if ( status != EINVAL ) printf( "status = %d\n", status ); rtems_test_assert( status == EINVAL ); puts( "Init: pthread_cond_timedwait - EINVAL (abstime NULL)" ); + status = pthread_cond_clockwait( &Cond1_id, &Mutex_id, clock_id,NULL ); + if ( status != EINVAL ) + printf( "status = %d\n", status ); + rtems_test_assert( status == EINVAL ); + puts( "Init: pthread_cond_clockwait - EINVAL (abstime NULL)" ); + + clock_id = (clockid_t) 99 ; //invalid clock value + status = pthread_cond_clockwait( &Cond1_id, NULL, clock_id, &timeout ); + if ( status != EINVAL ) + printf( "status = %d\n", status ); + rtems_test_assert( status == EINVAL ); + puts( "Init: pthread_cond_clockwait - EINVAL (clock invalid)" ); + status = clock_gettime( CLOCK_REALTIME, &timeout ); rtems_test_assert( !status ); timeout.tv_sec -= 1; @@ -413,6 +477,33 @@ void *POSIX_Init( status = pthread_mutex_unlock( &Mutex_id ); rtems_test_assert( !status ); + status = clock_gettime( CLOCK_MONOTONIC, &timeout ); + rtems_test_assert( !status ); + timeout.tv_sec -= 1; + clock_id = CLOCK_MONOTONIC; + status = pthread_cond_clockwait( &Cond1_id, &Mutex_id, clock_id, &timeout ); + if ( status != ETIMEDOUT ) + printf( "status = %d\n", status ); + rtems_test_assert( status == ETIMEDOUT ); + puts( "Init: pthread_cond_clockwait - ETIMEDOUT (abstime->tv_sec < current time)" ); + status = pthread_mutex_unlock( &Mutex_id ); + rtems_test_assert( !status ); + + do { + status = clock_gettime( CLOCK_MONOTONIC, &timeout ); + rtems_test_assert( !status ); + timeout.tv_nsec -= 1; + } while ( timeout.tv_nsec < 0); + + clock_id = CLOCK_MONOTONIC; + status = pthread_cond_clockwait( &Cond1_id, &Mutex_id, clock_id, &timeout ); + if ( status != ETIMEDOUT ) + printf( "status = %d\n", status ); + rtems_test_assert( status == ETIMEDOUT ); + puts( "Init: pthread_cond_clockwait - ETIMEDOUT (abstime->tv_nsec < current time)" ); + status = pthread_mutex_unlock( &Mutex_id ); + rtems_test_assert( !status ); + /* wait and timedwait without mutex */ /* XXX - this case is commented out in the code pending review diff --git a/testsuites/psxtests/psx10/psx10.scn b/testsuites/psxtests/psx10/psx10.scn index 3d5680c9b5..c5a0597ddd 100644 --- a/testsuites/psxtests/psx10/psx10.scn +++ b/testsuites/psxtests/psx10/psx10.scn @@ -38,16 +38,24 @@ Task_2: back from pthread_cond_wait release mutex Task_2: task exit Init: pthread_cond_timedwait for 3 seconds Init: pthread_cond_timedwait - ETIMEDOUT - (mutex not acquired) +Init: pthread_cond_clockwait for 3 seconds +Init: pthread_cond_clockwait - ETIMEDOUT - (mutex not acquired) Init: pthread_cond_signal - EINVAL (cond invalid) Init: pthread_cond_broadcast - EINVAL (cond invalid) Init: pthread_cond_wait - EINVAL (cond invalid) Init: pthread_cond_timedwait - EINVAL (cond invalid) +Init: pthread_cond_clockwait - EINVAL (cond invalid) Init: pthread_cond_wait - EINVAL (mutex invalid) Init: pthread_cond_timedwait - EINVAL (mutex invalid) +Init: pthread_cond_clockwait - EINVAL (mutex invalid) Init: pthread_cond_timedwait - EINVAL (abstime NULL) +Init: pthread_cond_clockwait - EINVAL (abstime NULL) +Init: pthread_cond_clockwait - EINVAL (clock invalid) Init: pthread_cond_timedwait - ETIMEDOUT (abstime->tv_sec < current time) Init: pthread_cond_timedwait - ETIMEDOUT (abstime->tv_nsec < current time) +Init: pthread_cond_clockwait - ETIMEDOUT (abstime->tv_sec < current time) +Init: pthread_cond_clockwait - ETIMEDOUT (abstime->tv_nsec < current time) Init: pthread_cond_wait - EINVAL (mutex not locked before call) Init: pthread_cond_timedwait - EINVAL (mutex not locked before call) diff --git a/testsuites/psxtests/psxautoinit02/init.c b/testsuites/psxtests/psxautoinit02/init.c index 4f510c0408..10a1de14d6 100644 --- a/testsuites/psxtests/psxautoinit02/init.c +++ b/testsuites/psxtests/psxautoinit02/init.c @@ -51,6 +51,7 @@ void *POSIX_Init( pthread_cond_t cond5 = PTHREAD_COND_INITIALIZER; pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; struct timespec to; + clockid_t clock_id; TEST_BEGIN(); @@ -76,6 +77,13 @@ void *POSIX_Init( sc = pthread_cond_timedwait( &cond4, &mtx, &to ); fatal_posix_service_status( sc, ETIMEDOUT, "cond timedwait OK" ); + puts( "Init - pthread_cond_clockwait - auto initialize - OK" ); + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + sc = pthread_cond_clockwait( &cond4, &mtx, clock_id, &to ); + fatal_posix_service_status( sc, ETIMEDOUT, "cond clockwait OK" ); + puts( "Init - pthread_mutex_unlock - OK" ); sc = pthread_mutex_unlock( &mtx ); fatal_posix_service_status( sc, 0, "mtx unlock OK" ); diff --git a/testsuites/psxtests/psxautoinit02/psxautoinit02.scn b/testsuites/psxtests/psxautoinit02/psxautoinit02.scn index 047088a6d9..301e0880c0 100644 --- a/testsuites/psxtests/psxautoinit02/psxautoinit02.scn +++ b/testsuites/psxtests/psxautoinit02/psxautoinit02.scn @@ -4,9 +4,11 @@ Init - pthread_cond_signal - auto initialize - OK Init - pthread_cond_init - auto initialize - OK Init - pthread_mutex_lock - OK Init - pthread_cond_timedwait - auto initialize - OK +Init - pthread_cond_clockwait - auto initialize - OK Init - pthread_mutex_unlock - OK Init - pthread_mutex_destroy - OK Init - pthread_cond_destroy - OK +Init - pthread_cond_destroy - EINVAL Init - pthread_cond_destroy - OK Init - pthread_cond_destroy - OK Init - pthread_cond_destroy - OK diff --git a/testsuites/psxtests/psxrwlock01/psxrwlock01.scn b/testsuites/psxtests/psxrwlock01/psxrwlock01.scn index fe47b19bea..e5013e693d 100644 --- a/testsuites/psxtests/psxrwlock01/psxrwlock01.scn +++ b/testsuites/psxtests/psxrwlock01/psxrwlock01.scn @@ -19,20 +19,28 @@ pthread_rwlock_init(NULL, &attr) -- EINVAL pthread_rwlock_destroy(NULL) -- EINVAL pthread_rwlock_rdlock(NULL) -- EINVAL pthread_rwlock_timedrdlock( NULL, &abstime) -- EINVAL -pthread_rwlock_timedrdlock( &rwlock, NULL) -- EINVAL +pthread_rwlock_clockrdlock( NULL, Clock_id, &abstime ) -- EINVAL pthread_rwlock_tryrdlock(NULL) -- EINVAL pthread_rwlock_wrlock(NULL) -- EINVAL pthread_rwlock_timedwrlock( NULL, &abstime) -- EINVAL -pthread_rwlock_timedwrlock( &rwlock, NULL) -- EINVAL +pthread_rwlock_clockwrlock( NULL, Clock_id, &abstime ) -- EINVAL pthread_rwlock_trywrlock(NULL) -- EINVAL pthread_rwlock_unlock(NULL) -- EINVAL +pthread_rwlock_timedrdlock( &rwlock, NULL) -- EINVAL +pthread_rwlock_timedwrlock( &rwlock, NULL) -- EINVAL +pthread_rwlock_clockrdlock( &rwlock, Clock_id, NULL ) -- EINVAL +pthread_rwlock_clockwrlock( &rwlock, Clock_id, NULL ) -- EINVAL +pthread_rwlock_clockrdlock( &rwlock, 99, NULL ) -- EINVAL +pthread_rwlock_clockwrlock( &rwlock, 99, NULL ) -- EINVAL clock_gettime(CLOCK_REALTIME, &abstime) -- OK pthread_rwlock_destroy(BadId) -- EINVAL pthread_rwlock_rdlock(BadId) -- EINVAL pthread_rwlock_timedrdlock(BadId, &abstime) -- EINVAL +pthread_rwlock_clockrdlock( BadId, Clock_id, &abstime ) -- EINVAL pthread_rwlock_tryrdlock(BadId) -- EINVAL pthread_rwlock_wrlock(BadId) -- EINVAL pthread_rwlock_timedwrlock(BadId, &abstime) -- EINVAL +pthread_rwlock_clockwrlock( BadId, Clock_id, &abstime ) -- EINVAL pthread_rwlock_trywrlock(BadId) -- EINVAL pthread_rwlock_unlock(BadId) -- EINVAL pthread_rwlockattr_init( &attr ) -- OK @@ -87,8 +95,16 @@ pthread_rwlock_timedwrlock( &RWLock, &abstime) -- OK pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT pthread_rwlock_timedrdlock( &RWLock, &abstime) -- ETIMEDOUT pthread_rwlock_timedwrlock( &RWLock, &abstime) -- ETIMEDOUT +pthread_rwlock_unlock(&RWLock) -- OK +clock_gettime(CLOCK_MONOTONIC, &abstime ) -- OK +pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- OK +pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT +pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT +pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT pthread_rwlock_timedrdlock( &RWLock, &abstime) -- in past -- OK +pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- in past -- OK pthread_rwlock_timedwrlock( &RWLock, &abstime) -- in past -- OK +pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- in past -- OK pthread_rwlock_destroy( &RWLock ) -- OK pthread_rwlock_init( &rwlock, NULL ) -- OK pthread_rwlock_unlock ( &rwlock ) -- OK diff --git a/testsuites/psxtests/psxrwlock01/test.c b/testsuites/psxtests/psxrwlock01/test.c index f6954007c0..7a39269269 100644 --- a/testsuites/psxtests/psxrwlock01/test.c +++ b/testsuites/psxtests/psxrwlock01/test.c @@ -144,6 +144,7 @@ static void test_rwlock_null( void ) { struct timespec to; int eno; + clockid_t clock_id; eno = pthread_rwlock_destroy( NULL ); rtems_test_assert( eno == EINVAL ); @@ -164,6 +165,18 @@ static void test_rwlock_null( void ) eno = pthread_rwlock_timedwrlock( NULL, &to ); rtems_test_assert( eno == EINVAL ); + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockrdlock( NULL, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockwrlock( NULL, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_rwlock_tryrdlock( NULL ); rtems_test_assert( eno == EINVAL ); @@ -182,6 +195,7 @@ static void test_rwlock_not_initialized( void ) pthread_rwlock_t rw; struct timespec to; int eno; + clockid_t clock_id; memset( &rw, 0xff, sizeof( rw ) ); @@ -201,6 +215,18 @@ static void test_rwlock_not_initialized( void ) eno = pthread_rwlock_timedwrlock( &rw, &to ); rtems_test_assert( eno == EINVAL ); + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockrdlock( &rw, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockwrlock( &rw, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_rwlock_tryrdlock( &rw ); rtems_test_assert( eno == EINVAL ); @@ -220,6 +246,7 @@ static void test_rwlock_invalid_copy( void ) pthread_rwlock_t rw2; struct timespec to; int eno; + clockid_t clock_id; eno = pthread_rwlock_init( &rw, NULL ); rtems_test_assert( eno == 0 ); @@ -242,6 +269,18 @@ static void test_rwlock_invalid_copy( void ) eno = pthread_rwlock_timedwrlock( &rw2, &to ); rtems_test_assert( eno == EINVAL ); + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockrdlock( &rw2, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockwrlock( &rw2, clock_id, &to ); + rtems_test_assert( eno == EINVAL ); + eno = pthread_rwlock_tryrdlock( &rw2 ); rtems_test_assert( eno == EINVAL ); @@ -262,6 +301,7 @@ static void test_rwlock_auto_initialization( void ) { struct timespec to; int eno; + clockid_t clock_id; { static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER; @@ -304,6 +344,26 @@ static void test_rwlock_auto_initialization( void ) rtems_test_assert( eno == 0 ); } + { + static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER; + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockrdlock( &rw, clock_id, &to ); + rtems_test_assert( eno == 0 ); + } + + { + static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER; + + to.tv_sec = 1; + to.tv_nsec = 1; + clock_id = CLOCK_MONOTONIC; + eno = pthread_rwlock_clockwrlock( &rw, clock_id, &to ); + rtems_test_assert( eno == 0 ); + } + { static pthread_rwlock_t rw = PTHREAD_RWLOCK_INITIALIZER; @@ -352,6 +412,7 @@ int main( int p; int i; struct timespec abstime; + clockid_t clock_id; TEST_BEGIN(); @@ -437,6 +498,7 @@ int main( /*************** NULL ARGUMENT CHECKS *****************/ abstime.tv_sec = 0; abstime.tv_nsec = 0; + clock_id = CLOCK_MONOTONIC; puts( "pthread_rwlock_init(NULL, &attr) -- EINVAL" ); status = pthread_rwlock_init(NULL, &attr); @@ -454,6 +516,10 @@ int main( status = pthread_rwlock_timedrdlock( NULL, &abstime); rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_clockrdlock( NULL, clock_id, &abstime ) -- EINVAL" ); + status = pthread_rwlock_clockrdlock( NULL, clock_id, &abstime ); + rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_tryrdlock(NULL) -- EINVAL" ); status = pthread_rwlock_tryrdlock(NULL); rtems_test_assert( status == EINVAL ); @@ -466,6 +532,10 @@ int main( status = pthread_rwlock_timedwrlock( NULL, &abstime ); rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_clockwrlock( NULL, clock_id, &abstime ) -- EINVAL" ); + status = pthread_rwlock_clockwrlock( NULL, clock_id, &abstime ); + rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_trywrlock(NULL) -- EINVAL" ); status = pthread_rwlock_trywrlock(NULL); rtems_test_assert( status == EINVAL ); @@ -488,12 +558,29 @@ int main( status = pthread_rwlock_timedwrlock( &rwlock, NULL); rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_clockrdlock( &rwlock, clock_id, NULL ) -- EINVAL" ); + status = pthread_rwlock_clockrdlock( &rwlock, clock_id, NULL ); + rtems_test_assert( status == EINVAL ); + + puts( "pthread_rwlock_clockwrlock( &rwlock, clock_id, NULL ) -- EINVAL" ); + status = pthread_rwlock_clockwrlock( &rwlock, clock_id, NULL ); + rtems_test_assert( status == EINVAL ); + status = pthread_rwlock_unlock( &rwlock ); rtems_test_assert( status == 0 ); status = pthread_rwlock_destroy( &rwlock ); rtems_test_assert( status == 0 ); + /*************** BAD CLOCK CHECK *****************/ + puts( "pthread_rwlock_clockrdlock( &rwlock, 99, NULL ) -- EINVAL" ); + status = pthread_rwlock_clockrdlock( &rwlock, 99, &abstime ); + rtems_test_assert( status == EINVAL ); + + puts( "pthread_rwlock_clockwrlock( &rwlock, 99, NULL ) -- EINVAL" ); + status = pthread_rwlock_clockwrlock( &rwlock, 99, &abstime ); + rtems_test_assert( status == EINVAL ); + /*************** BAD ID CHECK *****************/ /* make a valid abstime */ puts( "clock_gettime(CLOCK_REALTIME, &abstime) -- OK" ); @@ -513,6 +600,11 @@ int main( status = pthread_rwlock_timedrdlock( NULL, &abstime); rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_clockrdlock( BadId, clock_id, &abstime ) -- EINVAL" ); + status = pthread_rwlock_clockrdlock( NULL, clock_id, &abstime ); + rtems_test_assert( status == EINVAL ); + + puts( "pthread_rwlock_tryrdlock(BadId) -- EINVAL" ); status = pthread_rwlock_tryrdlock(NULL); rtems_test_assert( status == EINVAL ); @@ -525,6 +617,10 @@ int main( status = pthread_rwlock_timedwrlock( NULL, &abstime ); rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_clockwrlock( BadId, clock_id, &abstime ) -- EINVAL" ); + status = pthread_rwlock_clockwrlock( NULL, clock_id, &abstime ); + rtems_test_assert( status == EINVAL ); + puts( "pthread_rwlock_trywrlock(BadId) -- EINVAL" ); status = pthread_rwlock_trywrlock(NULL); rtems_test_assert( status == EINVAL ); @@ -701,6 +797,37 @@ int main( status = pthread_rwlock_timedwrlock( &RWLock, &abstime ); rtems_test_assert( status == ETIMEDOUT ); + puts( "pthread_rwlock_unlock(&RWLock) -- OK" ); + status = pthread_rwlock_unlock(&RWLock); + rtems_test_assert( !status ); + + sleep( 5 ); + + puts( "clock_gettime(CLOCK_MONOTONIC, &abstime ) -- OK" ); + status = clock_gettime( CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( !status ); + + abstime.tv_sec += 1; + puts( "pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- OK" ); + status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == 0 ); + + abstime.tv_sec += 1; + puts( "pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT" ); + status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == ETIMEDOUT ); + + abstime.tv_sec -= 1; + puts( "pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT" ); + status = pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == ETIMEDOUT ); + + abstime.tv_sec -= 1; + puts( "pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- ETIMEDOUT" ); + status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == ETIMEDOUT ); + + /*************** OBTAIN RWLOCK WITH ABSTIME IN PAST ***************/ status = pthread_rwlock_unlock(&RWLock); rtems_test_assert( !status ); @@ -710,6 +837,14 @@ int main( status = pthread_rwlock_timedrdlock( &RWLock, &abstime ); rtems_test_assert( status == 0 ); + status = pthread_rwlock_unlock(&RWLock); + rtems_test_assert( !status ); + + abstime.tv_sec -= 1; + puts( "pthread_rwlock_clockrdlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- in past -- OK" ); + 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 ); @@ -719,6 +854,14 @@ int main( status = pthread_rwlock_timedwrlock( &RWLock, &abstime ); rtems_test_assert( status == 0 ); + status = pthread_rwlock_unlock(&RWLock); + rtems_test_assert( !status ); + + abstime.tv_sec -= 1; + puts( "pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ) -- in past -- OK" ); + status = pthread_rwlock_clockwrlock( &RWLock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == 0 ); + /*************** DESTROY RWLOCK ***************/ puts( "pthread_rwlock_destroy( &RWLock ) -- OK" ); status = pthread_rwlock_destroy( &RWLock ); diff --git a/testsuites/psxtmtests/psxtmcond08/psxtmcond08.doc b/testsuites/psxtmtests/psxtmcond08/psxtmcond08.doc index 7002430c6c..6d493b21fc 100644 --- a/testsuites/psxtmtests/psxtmcond08/psxtmcond08.doc +++ b/testsuites/psxtmtests/psxtmcond08/psxtmcond08.doc @@ -40,6 +40,7 @@ directives: + pthread_cond_init + pthread_create + pthread_cond_timedwait ++ pthread_cond_clockwait concepts: + Benchmark the call pthread_cond_wait blocking threads and using a mutex and diff --git a/testsuites/psxtmtests/psxtmcond08/psxtmcond08impl.h b/testsuites/psxtmtests/psxtmcond08/psxtmcond08impl.h index 91f5b4f638..01bc063574 100644 --- a/testsuites/psxtmtests/psxtmcond08/psxtmcond08impl.h +++ b/testsuites/psxtmtests/psxtmcond08/psxtmcond08impl.h @@ -39,6 +39,12 @@ #elif defined(USE_TIMEDWAIT_WAIT_VALUE_IN_PAST) #define TEST_NUMBER "10" #define TEST_CASE "pthread_cond_timedwait: time in past error" +#elif defined(USE_CLOCKWAIT_WITH_VALUE) + #define TEST_NUMBER "11" + #define TEST_CASE "pthread_cond_clockwait: blocking" +#elif defined(USE_CLOCKWAIT_WAIT_VALUE_IN_PAST) + #define TEST_NUMBER "12" + #define TEST_CASE "pthread_cond_clockwait: time in past error" #else #error "How am I being compiled?" #endif @@ -69,6 +75,7 @@ void *Low(void *argument); pthread_cond_t CondID; pthread_mutex_t MutexID; struct timespec sleepTime; +clockid_t clock_id; void *Low( void *argument @@ -126,8 +133,26 @@ void *Middle( rtems_test_assert(rc == ETIMEDOUT); benchmark_timer_read(); } + #elif defined(USE_CLOCKWAIT_WITH_VALUE) + /* adjust sleepTime to get something obviously in the future */ + ++sleepTime.tv_sec; + + rc = pthread_cond_clockwait( &CondID, &MutexID, clock_id, &sleepTime ); + rtems_test_assert( rc == 0 ); + + #elif defined(USE_CLOCKWAIT_WAIT_VALUE_IN_PAST) + { + /* override sleepTime with something obviously in the past */ + sleepTime.tv_sec = 0; + sleepTime.tv_nsec = 5; + + rc = pthread_cond_clockwait( &CondID, &MutexID, clock_id, &sleepTime ); + rtems_test_assert(rc == ETIMEDOUT); + benchmark_timer_read(); + } #endif + pthread_mutex_unlock(&MutexID); #if defined(USE_TIMEDWAIT_WAIT_VALUE_IN_PAST) /* @@ -160,6 +185,8 @@ void *POSIX_Init( sleepTime.tv_sec = tp.tv_sec; sleepTime.tv_nsec = tp.tv_usec * 1000; + clock_id = CLOCK_MONOTONIC; + rc = pthread_cond_init(&CondID, NULL); rtems_test_assert( rc == 0 ); @@ -199,3 +226,4 @@ void *POSIX_Init( #include /* end of file */ + \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmcond11/init.c b/testsuites/psxtmtests/psxtmcond11/init.c new file mode 100644 index 0000000000..0ea3691ba6 --- /dev/null +++ b/testsuites/psxtmtests/psxtmcond11/init.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2025 Mazen Adel Elmessady + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR + * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#define USE_CLOCKWAIT_WITH_VALUE +#include "../psxtmcond08/psxtmcond08impl.h" \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmcond11/psxtmcond11.doc b/testsuites/psxtmtests/psxtmcond11/psxtmcond11.doc new file mode 100644 index 0000000000..e07b8c1bca --- /dev/null +++ b/testsuites/psxtmtests/psxtmcond11/psxtmcond11.doc @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# Copyright (C) 2025, Mazen Adel Elmessady +# +# 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. +# + +This test benchmarks the following operations: + ++ pthread_cond_clockwait - blocking with timeout value in future + +This file describes the directives and concepts tested by this test set. + +test set name: psxtmcond11 + +directives: ++ pthread_cond_clockwait ++ pthread_mutex_lock ++ pthread_mutex_unlock ++ pthread_mutex_init ++ pthread_cond_init ++ pthread_create + +concepts: ++ Benchmark the call pthread_cond_clockwait with a timeout value set to a time + in the future, measuring the time for threads to block and then be awakened. diff --git a/testsuites/psxtmtests/psxtmcond12/init.c b/testsuites/psxtmtests/psxtmcond12/init.c new file mode 100644 index 0000000000..5fc9f50e4c --- /dev/null +++ b/testsuites/psxtmtests/psxtmcond12/init.c @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * Copyright (C) 2025 Mazen Adel Elmessady + * + * Permission to use, copy, modify, and/or distribute this software + * for any purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR + * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#define USE_CLOCKWAIT_WAIT_VALUE_IN_PAST +#include "../psxtmcond08/psxtmcond08impl.h" \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmcond12/psxtmcond12.doc b/testsuites/psxtmtests/psxtmcond12/psxtmcond12.doc new file mode 100644 index 0000000000..59425b9b8a --- /dev/null +++ b/testsuites/psxtmtests/psxtmcond12/psxtmcond12.doc @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# Copyright (C) 2025, Mazen Adel Elmessady +# +# 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. +# + +This test benchmarks the following operations: + ++ pthread_cond_clockwait - timeout value in past, immediate return + +This file describes the directives and concepts tested by this test set. + +test set name: psxtmcond12 + +directives: ++ pthread_cond_clockwait ++ pthread_mutex_lock ++ pthread_mutex_unlock ++ pthread_mutex_init ++ pthread_cond_init ++ pthread_create + +concepts: ++ Benchmark the call pthread_cond_clockwait with a timeout value set to a time + in the past, which should return immediately with ETIMEDOUT error code. diff --git a/testsuites/psxtmtests/psxtmmutex03/init.c b/testsuites/psxtmtests/psxtmmutex03/init.c index 9e990281b4..c13142b1a4 100644 --- a/testsuites/psxtmtests/psxtmmutex03/init.c +++ b/testsuites/psxtmtests/psxtmmutex03/init.c @@ -45,6 +45,8 @@ void benchmark_mutex_unlock_no_threads_waiting(void); void benchmark_mutex_trylock_available(void); void benchmark_mutex_trylock_not_available(void); void benchmark_mutex_timedlock_available(void); +void benchmark_mutex_clocklock_available_clockmonotonic(void); +void benchmark_mutex_clocklock_available_clockrealtime(void); pthread_mutex_t MutexId; @@ -148,6 +150,44 @@ void benchmark_mutex_timedlock_available(void) ); } +void benchmark_mutex_clocklock_available_clockmonotonic(void) +{ + benchmark_timer_t end_time; + int status; + + benchmark_timer_initialize(); + status = pthread_mutex_clocklock( &MutexId, CLOCK_MONOTONIC, 0 ); + end_time = benchmark_timer_read(); + rtems_test_assert( !status ); + + put_time( + "pthread_mutex_clocklock: available CLOCK_MONOTONIC ", + end_time, + 1, + 0, + 0 + ); +} + +void benchmark_mutex_clocklock_available_clockrealtime(void) +{ + benchmark_timer_t end_time; + int status; + + benchmark_timer_initialize(); + status = pthread_mutex_clocklock( &MutexId, CLOCK_REALTIME, 0 ); + end_time = benchmark_timer_read(); + rtems_test_assert( !status ); + + put_time( + "pthread_mutex_clocklock: available CLOCK_REALTIME", + end_time, + 1, + 0, + 0 + ); +} + void *POSIX_Init( void *argument ) @@ -173,6 +213,10 @@ void *POSIX_Init( benchmark_mutex_unlock_no_threads_waiting(); benchmark_mutex_timedlock_available(); benchmark_mutex_unlock_no_threads_waiting(); + benchmark_mutex_clocklock_available_clockmonotonic(); + benchmark_mutex_unlock_no_threads_waiting(); + benchmark_mutex_clocklock_available_clockrealtime(); + benchmark_mutex_unlock_no_threads_waiting(); /* diff --git a/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.doc b/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.doc index 9c444a05a3..f1e6d728e8 100644 --- a/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.doc +++ b/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.doc @@ -34,3 +34,7 @@ This test benchmarks the following operations: + pthread_mutex_unlock - no threads waiting + pthread_mutex_timedlock - available + pthread_mutex_unlock - no threads waiting ++ pthread_mutex_clocklock - available CLOCK_MONOTONIC ++ pthread_mutex_unlock - no threads waiting ++ pthread_mutex_clocklock - available CLOCK_REALTIME ++ pthread_mutex_unlock - no threads waiting diff --git a/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.scn b/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.scn index 7892cea985..f1e2da9993 100644 --- a/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.scn +++ b/testsuites/psxtmtests/psxtmmutex03/psxtmmutex03.scn @@ -1,9 +1,13 @@ *** POSIX TIME TEST PSXTMMUTEX03 *** -pthread_mutex_lock - available 12 -pthread_mutex_unlock - no threads waiting 26 -pthread_mutex_trylock - available 12 -pthread_mutex_trylock - not available 12 -pthread_mutex_unlock - no threads waiting 27 -pthread_mutex_timedlock - available 14 -pthread_mutex_unlock - no threads waiting 26 +pthread_mutex_lock: available - 53 +pthread_mutex_unlock: no threads waiting - 3 +pthread_mutex_trylock: available - 4 +pthread_mutex_trylock: not available - 5 +pthread_mutex_unlock: no threads waiting - 2 +pthread_mutex_timedlock: available - 4 +pthread_mutex_unlock: no threads waiting - 3 +pthread_mutex_clocklock: available CLOCK_MONOTONIC - 4 +pthread_mutex_unlock: no threads waiting - 2 +pthread_mutex_clocklock: available CLOCK_REALTIME - 4 +pthread_mutex_unlock: no threads waiting - 3 *** END OF POSIX TIME TEST PSXTMMUTEX03 *** diff --git a/testsuites/psxtmtests/psxtmmutex08/init.c b/testsuites/psxtmtests/psxtmmutex08/init.c new file mode 100644 index 0000000000..12eb5b7253 --- /dev/null +++ b/testsuites/psxtmtests/psxtmmutex08/init.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * COPYRIGHT (c) 2025 Mazen Adel Elmessady + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "test_support.h" +#include +#include +#include + +#include +#include + +const char rtems_test_name[] = "PSXTMMUTEX 08"; + +/* forward declarations to avoid warnings */ +void *POSIX_Init( void *argument ); +void *Middle( void *argument ); +void *Low( void *argument ); + +pthread_mutex_t MutexId; + +void *Low( void *argument ) +{ + benchmark_timer_t end_time; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + end_time = benchmark_timer_read(); + + put_time( + "pthread_mutex_clocklock: not available block", + end_time, + OPERATION_COUNT, + 0, + 0 + ); + + TEST_END(); + + rtems_test_exit( 0 ); + return NULL; +} + +void *Middle( void *argument ) +{ + int status; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + status = pthread_mutex_lock( &MutexId ); + rtems_test_assert( !status ); /*this is important*/ + + return NULL; +} + +void *POSIX_Init( void *argument ) +{ + int i; + int status; + pthread_t threadId; + + TEST_BEGIN(); + + for ( i = 0; i < OPERATION_COUNT - 1; i++ ) { + status = pthread_create( &threadId, NULL, Middle, NULL ); + rtems_test_assert( !status ); + } + + status = pthread_create( &threadId, NULL, Low, NULL ); + rtems_test_assert( !status ); + + /* + * Deliberately create the mutex after the threads. This way if the + * threads do run before we intend, they will get an error. + */ + status = pthread_mutex_init( &MutexId, NULL ); + rtems_test_assert( !status ); + + /* + * Let the other threads start so the thread startup overhead, + * is accounted for. When we return, we can start the benchmark. + */ + sched_yield(); + /* let other threads run */ + + /* start the timer and switch through all the other tasks */ + benchmark_timer_initialize(); + status = pthread_mutex_clocklock( &MutexId, CLOCK_MONOTONIC, 0 ); + rtems_test_assert( !status ); + + return NULL; +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2 +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT + +#include +/* end of file */ diff --git a/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.doc b/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.doc new file mode 100644 index 0000000000..dc7d6e72d5 --- /dev/null +++ b/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.doc @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# COPYRIGHT (c) 2025 Mazen Adel Elmessady +# +# 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. +# + +This test benchmarks the following operations: + ++ pthread_mutex_clocklock - not available, block diff --git a/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.scn b/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.scn new file mode 100644 index 0000000000..de1560e331 --- /dev/null +++ b/testsuites/psxtmtests/psxtmmutex08/psxtmmutex08.scn @@ -0,0 +1,3 @@ +*** POSIX TIME TEST PSXTMMUTEX08 *** +pthread_mutex_clocklock: not available block - 113 +*** END OF POSIX TIME TEST PSXTMMUTEX08 *** diff --git a/testsuites/psxtmtests/psxtmrwlock01/init.c b/testsuites/psxtmtests/psxtmrwlock01/init.c index 1132867dae..1479728a00 100644 --- a/testsuites/psxtmtests/psxtmrwlock01/init.c +++ b/testsuites/psxtmtests/psxtmrwlock01/init.c @@ -153,6 +153,26 @@ static void benchmark_pthread_rwlock_timedrdlock(void) } +static void benchmark_pthread_rwlock_clockrdlock(void) +{ + benchmark_timer_t end_time; + int status; + + benchmark_timer_initialize(); + status = pthread_rwlock_clockrdlock( &rwlock, CLOCK_MONOTONIC, 0 ); + end_time = benchmark_timer_read(); + rtems_test_assert( status == 0 ); + + put_time( + "pthread_rwlock_clockrdlock: available", + end_time, + 1, /* Only executed once */ + 0, + 0 + ); + +} + static void benchmark_pthread_rwlock_wrlock(void) { benchmark_timer_t end_time; @@ -221,6 +241,26 @@ static void benchmark_pthread_rwlock_timedwrlock(void) ); } +static void benchmark_pthread_rwlock_clockwrlock(void) +{ + benchmark_timer_t end_time; + int status; + + benchmark_timer_initialize(); + status = pthread_rwlock_clockwrlock( &rwlock, CLOCK_MONOTONIC, 0 ); + end_time = benchmark_timer_read(); + rtems_test_assert( status == 0 ); + + put_time( + "pthread_rwlock_clockwrlock: available", + end_time, + 1, /* Only executed once */ + 0, + 0 + ); +} + + static void benchmark_pthread_rwlock_destroy(void) { benchmark_timer_t end_time; @@ -261,6 +301,10 @@ void *POSIX_Init( benchmark_pthread_rwlock_timedrdlock(); /* unlocking rwlock */ benchmark_pthread_rwlock_unlock(0); + /* applying a clock read lock */ + benchmark_pthread_rwlock_clockrdlock(); + /* unlocking rwlock */ + benchmark_pthread_rwlock_unlock(0); /* applying a write lock */ benchmark_pthread_rwlock_wrlock(); /* trying to get read lock, when is not available*/ @@ -276,6 +320,10 @@ void *POSIX_Init( /* applying a timed write lock */ benchmark_pthread_rwlock_timedwrlock(); /* unlocking rwlock */ + benchmark_pthread_rwlock_unlock(0); + /* applying a clock write lock */ + benchmark_pthread_rwlock_clockwrlock(); + /* unlocking rwlock */ benchmark_pthread_rwlock_unlock(1); /* destroying rwlock */ benchmark_pthread_rwlock_destroy(); diff --git a/testsuites/psxtmtests/psxtmrwlock01/psxtmrwlock01.doc b/testsuites/psxtmtests/psxtmrwlock01/psxtmrwlock01.doc index 0166b4fb24..a7faa79acc 100644 --- a/testsuites/psxtmtests/psxtmrwlock01/psxtmrwlock01.doc +++ b/testsuites/psxtmtests/psxtmrwlock01/psxtmrwlock01.doc @@ -33,8 +33,10 @@ This test benchmarks the following operations: + pthread_rwlock_tryrdlock - available + pthread_rwlock_tryrdlock - not available + pthread_rwlock_timedrdlock - available ++ pthread_rwlock_clockrdlock - available + pthread_rwlock_wrlock - available + pthread_rwlock_trywrlock - available + pthread_rwlock_trywrlock - not available + pthread_rwlock_timedwrlock - available ++ pthread_rwlock_clockwrlock - available + pthread_rwlock_destroy diff --git a/testsuites/psxtmtests/psxtmrwlock08/init.c b/testsuites/psxtmtests/psxtmrwlock08/init.c new file mode 100644 index 0000000000..9fa4a13c7c --- /dev/null +++ b/testsuites/psxtmtests/psxtmrwlock08/init.c @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * COPYRIGHT (c) 2025 Mazen Adel Elmessady. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "test_support.h" +#include +#include +#include +#include +#include +#include + +const char rtems_test_name[] = "PSXTMRWLOCK 08"; + +/* forward declarations to avoid warnings */ +void *POSIX_Init( void *argument ); +void *Middle( void *argument ); +void *Low( void *argument ); + +pthread_rwlock_t rwlock; +struct timespec abstime; + +void *Low( void *argument ) +{ + benchmark_timer_t end_time; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + end_time = benchmark_timer_read(); + + put_time( + "pthread_rwlock_clockrdlock: not available blocks", + end_time, + OPERATION_COUNT, + 0, + 0 + ); + + TEST_END(); + + rtems_test_exit( 0 ); + return NULL; +} + +void *Middle( void *argument ) +{ + int status; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + /* this clock read lock operation will be blocked + * cause a write operation has the lock */ + status = pthread_rwlock_clockrdlock( &rwlock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == 0 ); + return NULL; +} + +void *POSIX_Init( void *argument ) +{ + int i; + int status; + pthread_t threadId; + pthread_rwlockattr_t attr; + + TEST_BEGIN(); + + for ( i = 0; i < OPERATION_COUNT - 1; i++ ) { + status = pthread_create( &threadId, NULL, Middle, NULL ); + rtems_test_assert( !status ); + } + + status = pthread_create( &threadId, NULL, Low, NULL ); + rtems_test_assert( !status ); + + /* + * Timeout for 5 seconds from now. + */ + status = clock_gettime( CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( !status ); + abstime.tv_sec += 5; + + /* + * Deliberately create the rwlock after the threads. This way if the + * threads do run before we intend, they will get an error. + */ + status = pthread_rwlockattr_init( &attr ); + rtems_test_assert( status == 0 ); + status = pthread_rwlock_init( &rwlock, &attr ); + rtems_test_assert( status == 0 ); + + /* + * Let the other threads start so the thread startup overhead, + * is accounted for. When we return, we can start the benchmark. + */ + sched_yield(); + /* let other threads run */ + + /* start the timer and switch through all the other tasks */ + benchmark_timer_initialize(); + + /* + * Write lock operation, this could be any write lock + */ + status = pthread_rwlock_clockwrlock( &rwlock, CLOCK_MONOTONIC, 0 ); + rtems_test_assert( status == 0 ); + return NULL; +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2 +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT + +#include +/* end of file */ \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmrwlock08/psxtmrwlock08.doc b/testsuites/psxtmtests/psxtmrwlock08/psxtmrwlock08.doc new file mode 100644 index 0000000000..bdf1d137d9 --- /dev/null +++ b/testsuites/psxtmtests/psxtmrwlock08/psxtmrwlock08.doc @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# COPYRIGHT (c) 2025 Mazen Adel Elmessady. +# +# 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. +# + +This test benchmarks the following operations: + ++ pthread_rwlock_clockrdlock - not available, blocks \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmrwlock09/init.c b/testsuites/psxtmtests/psxtmrwlock09/init.c new file mode 100644 index 0000000000..800ce5aa0f --- /dev/null +++ b/testsuites/psxtmtests/psxtmrwlock09/init.c @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/* + * COPYRIGHT (c) 2025 Mazen Adel Elmessady. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "test_support.h" +#include +#include +#include +#include +#include +#include + +const char rtems_test_name[] = "PSXTMRWLOCK 09"; + +/* forward declarations to avoid warnings */ +void *POSIX_Init( void *argument ); +void *Middle( void *argument ); +void *Low( void *argument ); + +pthread_rwlock_t rwlock; +struct timespec abstime; + +void *Low( void *argument ) +{ + benchmark_timer_t end_time; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + end_time = benchmark_timer_read(); + + put_time( + "pthread_rwlock_clockwrlock: not available blocks", + end_time, + OPERATION_COUNT, + 0, + 0 + ); + + TEST_END(); + + rtems_test_exit( 0 ); + return NULL; +} + +void *Middle( void *argument ) +{ + int status; + + /* + * Now we have finished the thread startup overhead, + * so let other threads run. When we return, we can + * finish the benchmark. + */ + sched_yield(); + /* let other threads run */ + + /* This clock write lock operation will be blocked + * because the other write operation has the lock + */ + status = pthread_rwlock_clockwrlock( &rwlock, CLOCK_MONOTONIC, &abstime ); + rtems_test_assert( status == 0 ); + return NULL; +} + +void *POSIX_Init( void *argument ) +{ + int i; + int status; + pthread_t threadId; + pthread_rwlockattr_t attr; + + TEST_BEGIN(); + + for ( i = 0; i < OPERATION_COUNT - 1; i++ ) { + status = pthread_create( &threadId, NULL, Middle, NULL ); + rtems_test_assert( !status ); + } + + status = pthread_create( &threadId, NULL, Low, NULL ); + rtems_test_assert( !status ); + + /* + * Timeout for 5 seconds from now. + */ + status = clock_gettime( CLOCK_REALTIME, &abstime ); + rtems_test_assert( !status ); + abstime.tv_sec += 5; + + /* + * Deliberately create the rwlock after the threads. This way if the + * threads do run before we intend, they will get an error. + */ + status = pthread_rwlockattr_init( &attr ); + rtems_test_assert( status == 0 ); + status = pthread_rwlock_init( &rwlock, &attr ); + rtems_test_assert( status == 0 ); + /* + * Let the other threads start so the thread startup overhead, + * is accounted for. When we return, we can start the benchmark. + */ + sched_yield(); + /* let other threads run */ + + /* start the timer and switch through all the other tasks */ + benchmark_timer_initialize(); + + /* write lock operation, this could be any write lock */ + status = pthread_rwlock_clockwrlock( &rwlock, CLOCK_MONOTONIC, 0 ); + rtems_test_assert( status == 0 ); + return NULL; +} + +/* configuration information */ + +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_TIMER_DRIVER + +#define CONFIGURE_MAXIMUM_POSIX_THREADS OPERATION_COUNT + 2 +#define CONFIGURE_POSIX_INIT_THREAD_TABLE + +#define CONFIGURE_INIT + +#include +/* end of file */ \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmrwlock09/psxtmrwlock09.doc b/testsuites/psxtmtests/psxtmrwlock09/psxtmrwlock09.doc new file mode 100644 index 0000000000..49659e95e6 --- /dev/null +++ b/testsuites/psxtmtests/psxtmrwlock09/psxtmrwlock09.doc @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: BSD-2-Clause + +# COPYRIGHT (c) 2025 Mazen Adel Elmessady. +# +# 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. +# + +This test benchmarks the following operations: + ++ pthread_rwlock_timedwrlock - not available, blocks \ No newline at end of file diff --git a/testsuites/psxtmtests/psxtmtests_plan.csv b/testsuites/psxtmtests/psxtmtests_plan.csv index 4adb25c62f..074c3369ed 100644 --- a/testsuites/psxtmtests/psxtmtests_plan.csv +++ b/testsuites/psxtmtests/psxtmtests_plan.csv @@ -10,6 +10,8 @@ "pthread_mutex_unlock: thread waiting: preempt","psxtmmutex06","psxtmtest_unblocking_preempt","Yes" "pthread_mutex_timedlock: available","psxtmmutex03","psxtmtest_single","Yes" "pthread_mutex_timedlock: not available: block","psxtmmutex04","psxtmtest_blocking","Yes" +"pthread_mutex_clocklock: available","psxtmmutex03","psxtmtest_single","Yes" +"pthread_mutex_clocklock: not available: block","psxtmmutex08","psxtmtest_blocking","Yes" "pthread_mutex_setprioceiling","psxtmmutex07","psxtmtest_single","Yes" "pthread_mutex_getprioceiling","psxtmmutex07","psxtmtest_single","Yes" @@ -36,6 +38,8 @@ "pthread_cond_wait: blocks","psxtmcond08","psxtmtest_blocking","Yes" "pthread_cond_timedwait: blocks","psxtmcond09","psxtmtest_blocking","Yes" "pthread_cond_timedwait: time in past error","psxtmcond10","psxtmtest_blocking","Yes" +"pthread_cond_clockwait: blocks","psxtmcond11","psxtmtest_blocking","Yes" +"pthread_cond_clockwait: time in past error","psxtmcond12","psxtmtest_blocking","Yes" "pthread_create: no preempt","psxtmthread01","psxtmtest_single","Yes" "pthread_create: preempt","psxtmthread02","psxtmtest_single","Yes" @@ -115,6 +119,8 @@ "pthread_rwlock_tryrdlock: not available","psxtmrwlock01","psxtmtest_single","Yes" "pthread_rwlock_timedrdlock: available","psxtmrwlock01","psxtmtest_single","Yes" "pthread_rwlock_timedrdlock: not available: blocks","psxtmrwlock03","psxtmtest_blocking","Yes" +"pthread_rwlock_clockrdlock: available","psxtmrwlock01","psxtmtest_single","Yes" +"pthread_rwlock_clockrdlock: not available: blocks","psxtmrwlock08","psxtmtest_blocking","Yes" "pthread_rwlock_unlock: no threads waiting","psxtmrwlock01","psxtmtest_single","Yes" "pthread_rwlock_unlock: thread waiting: no preempt","psxtmrwlock06",,"Yes" "pthread_rwlock_unlock: thread waiting: preempt","psxtmrwlock07",,"Yes" @@ -124,6 +130,8 @@ "pthread_rwlock_trywrlock: not available","psxtmrwlock01","psxtmtest_single","Yes" "pthread_rwlock_timedwrlock: available","psxtmrwlock01","psxtmtest_single","Yes" "pthread_rwlock_timedwrlock: not available: blocks","psxtmrwlock05","psxtmtest_blocking","Yes" +"pthread_rwlock_clockwrlock: available","psxtmrwlock01","psxtmtest_single","Yes" +"pthread_rwlock_clockwrlock: not available: blocks","psxtmrwlock09","psxtmtest_blocking","Yes" "mq_open: first open","psxtmmq01","psxtmtest_init_destroy","Yes" "mq_close: close of first","psxtmmq01","psxtmtest_init_destroy","Yes"