1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 #pragma once 15 16 #include "pw_chrono/system_clock.h" 17 #include "pw_sync/thread_notification.h" 18 19 namespace pw::sync { 20 21 /// The `TimedThreadNotification` is a synchronization primitive that can be 22 /// used to permit a SINGLE thread to block and consume a latching, saturating 23 /// notification from multiple notifiers. 24 /// 25 /// @b IMPORTANT: This is a single consumer/waiter, multiple producer/notifier 26 /// API! The acquire APIs must only be invoked by a single consuming thread. As 27 /// a result, having multiple threads receiving notifications via the acquire 28 /// API is unsupported. 29 /// 30 /// This is effectively a subset of a binary semaphore API, except that only a 31 /// single thread can be notified and block at a time. 32 /// 33 /// The single consumer aspect of the API permits the use of a smaller and/or 34 /// faster native APIs such as direct thread signaling. 35 /// 36 /// The `TimedThreadNotification` is initialized to being empty (latch is not 37 /// set). 38 class TimedThreadNotification : public ThreadNotification { 39 public: 40 TimedThreadNotification() = default; 41 ~TimedThreadNotification() = default; 42 TimedThreadNotification(const TimedThreadNotification&) = delete; 43 TimedThreadNotification(TimedThreadNotification&&) = delete; 44 TimedThreadNotification& operator=(const TimedThreadNotification&) = delete; 45 TimedThreadNotification& operator=(TimedThreadNotification&&) = delete; 46 47 /// Blocks until the specified timeout duration has elapsed or the thread 48 /// has been notified (i.e. notification latch can be cleared because it was 49 /// set), whichever comes first. 50 /// 51 /// Clears the notification latch. 52 /// 53 /// Returns true if the thread was notified, meaning the the internal latch 54 /// was reset successfully. 55 /// 56 /// @b IMPORTANT: This should only be used by a single consumer thread. 57 [[nodiscard]] bool try_acquire_for(chrono::SystemClock::duration timeout); 58 59 /// Blocks until the specified deadline time has been reached the thread has 60 /// been notified (i.e. notification latch can be cleared because it was set), 61 /// whichever comes first. 62 /// 63 /// Clears the notification latch. 64 /// 65 /// Returns true if the thread was notified, meaning the the internal latch 66 /// was reset successfully. 67 /// 68 /// @b IMPORTANT: This should only be used by a single consumer thread. 69 [[nodiscard]] bool try_acquire_until( 70 chrono::SystemClock::time_point deadline); 71 }; 72 73 } // namespace pw::sync 74 75 #include "pw_sync_backend/timed_thread_notification_inline.h" 76