// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/blob/master/LICENSE.md #include "SynchronizationMechanism.hpp" #include namespace service::gui { class FreeRtosSynchronization : public SynchronizationMechanism { public: FreeRtosSynchronization(); FreeRtosSynchronization(const FreeRtosSynchronization &) = delete; FreeRtosSynchronization(FreeRtosSynchronization &&) noexcept = default; FreeRtosSynchronization &operator=(const FreeRtosSynchronization &) = delete; FreeRtosSynchronization &operator=(FreeRtosSynchronization &&) noexcept = default; ~FreeRtosSynchronization() noexcept override; void wait(cpp_freertos::Mutex &lock, std::chrono::milliseconds timeout, Predicate predicate) override; void notify() override; private: SemaphoreHandle_t semaphore; }; FreeRtosSynchronization::FreeRtosSynchronization() : semaphore{xSemaphoreCreateBinary()} {} FreeRtosSynchronization::~FreeRtosSynchronization() noexcept { vSemaphoreDelete(semaphore); } void FreeRtosSynchronization::wait(cpp_freertos::Mutex &lock, std::chrono::milliseconds timeout, Predicate predicate) { if (!predicate) { // Predicate needed to cover spurious wake-ups. throw std::invalid_argument{"Null predicate passed."}; } while (!predicate()) { lock.Unlock(); xSemaphoreTake(semaphore, timeout.count()); lock.Lock(); } } void FreeRtosSynchronization::notify() { xSemaphoreGive(semaphore); } std::unique_ptr getFreeRtosSynchronizationMechanism() { return std::make_unique(); } } // namespace service::gui