diff --git a/doc/services/portability/posix/conformance/index.rst b/doc/services/portability/posix/conformance/index.rst index 2fe9156f943d..772194cbf311 100644 --- a/doc/services/portability/posix/conformance/index.rst +++ b/doc/services/portability/posix/conformance/index.rst @@ -64,7 +64,7 @@ POSIX System Interfaces :ref:`_POSIX_CLOCK_SELECTION`, 200809L, :kconfig:option:`CONFIG_POSIX_CLOCK` _POSIX_MAPPED_FILES, -1, :ref:`†` _POSIX_MEMORY_PROTECTION, -1, :ref:`†` - :ref:`_POSIX_READER_WRITER_LOCKS`, -1, :kconfig:option:`CONFIG_PTHREAD_IPC` + :ref:`_POSIX_READER_WRITER_LOCKS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_IPC` _POSIX_REALTIME_SIGNALS, -1, :ref:`†` :ref:`_POSIX_SEMAPHORES`, 200809L, :kconfig:option:`CONFIG_PTHREAD_IPC` :ref:`_POSIX_SPIN_LOCKS`, 200809L, :kconfig:option:`CONFIG_PTHREAD_SPINLOCK` diff --git a/doc/services/portability/posix/option_groups/index.rst b/doc/services/portability/posix/option_groups/index.rst index 0f5888b0f51a..18f1caa74dbc 100644 --- a/doc/services/portability/posix/option_groups/index.rst +++ b/doc/services/portability/posix/option_groups/index.rst @@ -401,9 +401,9 @@ _POSIX_READER_WRITER_LOCKS pthread_rwlock_unlock(),yes pthread_rwlock_wrlock(),yes pthread_rwlockattr_destroy(),yes - pthread_rwlockattr_getpshared(), + pthread_rwlockattr_getpshared(),yes pthread_rwlockattr_init(),yes - pthread_rwlockattr_setpshared(), + pthread_rwlockattr_setpshared(),yes .. _posix_option_thread_attr_stackaddr: diff --git a/include/zephyr/posix/pthread.h b/include/zephyr/posix/pthread.h index 7ffdb1318d8e..eb786f80e19e 100644 --- a/include/zephyr/posix/pthread.h +++ b/include/zephyr/posix/pthread.h @@ -390,22 +390,18 @@ int pthread_equal(pthread_t pt1, pthread_t pt2); * * See IEEE 1003.1 */ -static inline int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) -{ - ARG_UNUSED(attr); - return 0; -} +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); /** * @brief initialize the read-write lock attributes object. * * See IEEE 1003.1 */ -static inline int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) -{ - ARG_UNUSED(attr); - return 0; -} +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); + +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *ZRESTRICT attr, + int *ZRESTRICT pshared); +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); int pthread_attr_getguardsize(const pthread_attr_t *ZRESTRICT attr, size_t *ZRESTRICT guardsize); int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); diff --git a/lib/posix/options/rwlock.c b/lib/posix/options/rwlock.c index 34d10c6dfa63..b8a91a03232b 100644 --- a/lib/posix/options/rwlock.c +++ b/lib/posix/options/rwlock.c @@ -21,6 +21,11 @@ struct posix_rwlock { k_tid_t wr_owner; }; +struct posix_rwlockattr { + bool initialized: 1; + bool pshared: 1; +}; + int64_t timespec_to_timeoutms(const struct timespec *abstime); static uint32_t read_lock_acquire(struct posix_rwlock *rwl, int32_t timeout); static uint32_t write_lock_acquire(struct posix_rwlock *rwl, int32_t timeout); @@ -384,3 +389,63 @@ static uint32_t write_lock_acquire(struct posix_rwlock *rwl, int32_t timeout) } return ret; } + +int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *ZRESTRICT attr, + int *ZRESTRICT pshared) +{ + struct posix_rwlockattr *const a = (struct posix_rwlockattr *)attr; + + if (a == NULL || !a->initialized) { + return EINVAL; + } + + *pshared = a->pshared; + + return 0; +} + +int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared) +{ + struct posix_rwlockattr *const a = (struct posix_rwlockattr *)attr; + + if (a == NULL || !a->initialized) { + return EINVAL; + } + + if (!(pshared == PTHREAD_PROCESS_PRIVATE || pshared == PTHREAD_PROCESS_SHARED)) { + return EINVAL; + } + + a->pshared = pshared; + + return 0; +} + +int pthread_rwlockattr_init(pthread_rwlockattr_t *attr) +{ + struct posix_rwlockattr *const a = (struct posix_rwlockattr *)attr; + + if (a == NULL) { + return EINVAL; + } + + *a = (struct posix_rwlockattr){ + .initialized = true, + .pshared = PTHREAD_PROCESS_PRIVATE, + }; + + return 0; +} + +int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr) +{ + struct posix_rwlockattr *const a = (struct posix_rwlockattr *)attr; + + if (a == NULL || !a->initialized) { + return EINVAL; + } + + *a = (struct posix_rwlockattr){0}; + + return 0; +} diff --git a/tests/posix/common/src/rwlock.c b/tests/posix/common/src/rwlock.c index 44d3cce29710..a7012fc58327 100644 --- a/tests/posix/common/src/rwlock.c +++ b/tests/posix/common/src/rwlock.c @@ -117,6 +117,33 @@ ZTEST(rwlock, test_rw_lock) zassert_ok(pthread_rwlock_destroy(&rwlock), "Failed to destroy rwlock"); } +static void test_pthread_rwlockattr_pshared_common(bool set, int pshared) +{ + int tmp_pshared = 4242; + pthread_rwlockattr_t attr; + + zassert_ok(pthread_rwlockattr_init(&attr)); + zassert_ok(pthread_rwlockattr_getpshared(&attr, &tmp_pshared)); + zassert_equal(tmp_pshared, PTHREAD_PROCESS_PRIVATE); + if (set) { + zassert_ok(pthread_rwlockattr_setpshared(&attr, pshared)); + zassert_ok(pthread_rwlockattr_getpshared(&attr, &tmp_pshared)); + zassert_equal(tmp_pshared, pshared); + } + zassert_ok(pthread_rwlockattr_destroy(&attr)); +} + +ZTEST(rwlock, test_pthread_rwlockattr_getpshared) +{ + test_pthread_rwlockattr_pshared_common(false, 0); +} + +ZTEST(rwlock, test_pthread_rwlockattr_setpshared) +{ + test_pthread_rwlockattr_pshared_common(true, PTHREAD_PROCESS_PRIVATE); + test_pthread_rwlockattr_pshared_common(true, PTHREAD_PROCESS_SHARED); +} + static void before(void *arg) { ARG_UNUSED(arg);