mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/pthread_rwlock_try_functions' into 'master'
pthread: added pthread_rwlock_tryrd/rwlock() Closes IDFGH-7685 See merge request espressif/esp-idf!23228
This commit is contained in:
commit
05cbd19f25
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -191,6 +191,34 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
int res;
|
||||
|
||||
res = checkrw_lock(rwlock);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_rwlock = (esp_pthread_rwlock_t *)*rwlock;
|
||||
res = pthread_mutex_trylock(&esp_rwlock->resource_mutex);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (esp_rwlock->active_writers == 0) {
|
||||
esp_rwlock->active_readers++;
|
||||
res = 0;
|
||||
} else {
|
||||
res = EBUSY;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&esp_rwlock->resource_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
@ -219,6 +247,35 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) {
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
int res;
|
||||
|
||||
res = checkrw_lock(rwlock);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_rwlock = (esp_pthread_rwlock_t *)*rwlock;
|
||||
res = pthread_mutex_trylock(&esp_rwlock->resource_mutex);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (esp_rwlock->active_readers > 0 ||
|
||||
esp_rwlock->active_writers > 0 ||
|
||||
esp_rwlock->waiting_writers > 0) { // the last check for waiting_writers is to avoid skipping the queue
|
||||
res = EBUSY;
|
||||
} else {
|
||||
esp_rwlock->active_writers++;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&esp_rwlock->resource_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
|
@ -293,3 +293,89 @@ TEST_CASE("wrlock multiple writers wait", "[pthread][rwlock]")
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
vQueueDelete(wait_queue);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock invalid param", "[pthread][rwlock]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(NULL), EINVAL);
|
||||
|
||||
pthread_rwlock_t rwlock = 0;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), EINVAL);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock fails on write-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_wrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock succeeds on read-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_rdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock lock statically initialized lock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock invalid param", "[pthread][rwlock]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(NULL), EINVAL);
|
||||
|
||||
pthread_rwlock_t rwlock = 0;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EINVAL);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock fails on write-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_wrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock fails on read-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_rdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock lock statically initialized lock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
@ -123,18 +123,23 @@ In IDF, POSIX *unnamed* semaphores are implemented. The accessible API is descri
|
||||
* `sem_getvalue() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sem_getvalue.html>`_
|
||||
|
||||
Read/Write Locks
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
^^^^^^^^^^^^^^^^
|
||||
The following API functions of the POSIX reader-writer locks specification are implemented:
|
||||
|
||||
* `pthread_rwlock_init() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_init.html>`_
|
||||
|
||||
* ``pthread_rwlock_init()``
|
||||
- The ``attr`` argument is not implemented and is ignored.
|
||||
* ``pthread_rwlock_destroy()``
|
||||
* ``pthread_rwlock_rdlock()``
|
||||
* ``pthread_rwlock_wrlock()``
|
||||
* ``pthread_rwlock_unlock()``
|
||||
|
||||
Static initializer constant ``PTHREAD_RWLOCK_INITIALIZER`` is supported.
|
||||
* `pthread_rwlock_destroy() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_destroy.html>`_
|
||||
* `pthread_rwlock_rdlock() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_rdlock.html>`_
|
||||
* `pthread_rwlock_tryrdlock() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_tryrdlock.html>`_
|
||||
* `pthread_rwlock_wrlock() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_wrlock.html>`_
|
||||
* `pthread_rwlock_trywrlock() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_trywrlock.html>`_
|
||||
* `pthread_rwlock_unlock() <https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_unlock.html>`_
|
||||
|
||||
.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs
|
||||
The static initializer constant ``PTHREAD_RWLOCK_INITIALIZER`` is supported.
|
||||
|
||||
.. note:: These functions can be called from tasks created using either pthread or FreeRTOS APIs.
|
||||
|
||||
Thread-Specific Data
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
Loading…
x
Reference in New Issue
Block a user