Add sem_try_acquire(). Fixes #846 (#856)

Co-authored-by: Geoff Simmons <geoff@uplex.de>
This commit is contained in:
Graham Sanderson 2022-06-08 13:23:36 -05:00 committed by GitHub
parent ef47dfeeaf
commit 672e48e9e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 57 additions and 1 deletions

View File

@ -122,6 +122,17 @@ bool sem_acquire_timeout_us(semaphore_t *sem, uint32_t timeout_us);
*/ */
bool sem_acquire_block_until(semaphore_t *sem, absolute_time_t until); bool sem_acquire_block_until(semaphore_t *sem, absolute_time_t until);
/*! \brief Attempt to acquire a permit from a semaphore without blocking
* \ingroup sem
*
* This function will return false without blocking if no permits are
* available, otherwise it will acquire a permit and return true.
*
* \param sem Pointer to semaphore structure
* \return true if permit was acquired.
*/
bool sem_try_acquire(semaphore_t *sem);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -52,6 +52,17 @@ bool __time_critical_func(sem_acquire_block_until)(semaphore_t *sem, absolute_ti
} while (true); } while (true);
} }
bool __time_critical_func(sem_try_acquire)(semaphore_t *sem) {
uint32_t save = spin_lock_blocking(sem->core.spin_lock);
if (sem->permits > 0) {
sem->permits--;
lock_internal_spin_unlock_with_notify(&sem->core, save);
return true;
}
spin_unlock(sem->core.spin_lock, save);
return false;
}
// todo this should really have a blocking variant for when permits are maxed out // todo this should really have a blocking variant for when permits are maxed out
bool __time_critical_func(sem_release)(semaphore_t *sem) { bool __time_critical_func(sem_release)(semaphore_t *sem) {
uint32_t save = spin_lock_blocking(sem->core.spin_lock); uint32_t save = spin_lock_blocking(sem->core.spin_lock);

View File

@ -9,4 +9,5 @@ if (PICO_ON_DEVICE)
add_subdirectory(hardware_irq_test) add_subdirectory(hardware_irq_test)
add_subdirectory(hardware_pwm_test) add_subdirectory(hardware_pwm_test)
add_subdirectory(cmsis_test) add_subdirectory(cmsis_test)
add_subdirectory(pico_sem_test)
endif() endif()

View File

@ -0,0 +1,4 @@
add_executable(pico_sem_test pico_sem_test.c)
target_link_libraries(pico_sem_test PRIVATE pico_test pico_sync)
pico_add_extra_outputs(pico_sem_test)

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "pico/sem.h"
#include "pico/test.h"
#include "pico/stdio.h"
PICOTEST_MODULE_NAME("SEM", "semaphore test");
int main() {
semaphore_t sem;
stdio_init_all();
sem_init(&sem, 1, 1);
PICOTEST_START();
PICOTEST_START_SECTION("sem_try_acquire");
PICOTEST_CHECK(sem_try_acquire(&sem), "available permit not acquired");
PICOTEST_CHECK(!sem_try_acquire(&sem), "success with no permits");
PICOTEST_END_SECTION();
PICOTEST_END_TEST();
}