• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_sync_backend/thread_notification_native.h"
17 
18 namespace pw::sync {
19 
20 // The ThreadNotification is a synchronization primitive that can be used to
21 // permit a SINGLE thread to block and consume a latching, saturating
22 // notification from multiple notifiers.
23 //
24 // IMPORTANT: This is a single consumer/waiter, multiple producer/notifier API!
25 // The acquire APIs must only be invoked by a single consuming thread. As a
26 // result, having multiple threads receiving notifications via the acquire API
27 // is unsupported.
28 //
29 // This is effectively a subset of a binary semaphore API, except that only a
30 // single thread can be notified and block at a time.
31 //
32 // The single consumer aspect of the API permits the use of a smaller and/or
33 // faster native APIs such as direct thread signaling.
34 class ThreadNotification {
35  public:
36   using native_handle_type = backend::NativeThreadNotificationHandle;
37 
38   ThreadNotification();
39   ~ThreadNotification();
40   ThreadNotification(const ThreadNotification&) = delete;
41   ThreadNotification(ThreadNotification&&) = delete;
42   ThreadNotification& operator=(const ThreadNotification&) = delete;
43   ThreadNotification& operator=(ThreadNotification&&) = delete;
44 
45   // Blocks indefinitely until the thread is notified, i.e. until the
46   // notification latch can be cleared because it was set.
47   //
48   // Clears the notification latch.
49   //
50   // IMPORTANT: This should only be used by a single consumer thread.
51   void acquire();
52 
53   // Returns whether the thread has been notified, i.e. whether the notificion
54   // latch was set and resets the latch regardless.
55   //
56   // Clears the notification latch.
57   //
58   // Returns true if the thread was notified, meaning the the internal latch was
59   // reset successfully.
60   //
61   // IMPORTANT: This should only be used by a single consumer thread.
62   bool try_acquire();
63 
64   // Notifies the thread in a saturating manner, setting the notification latch.
65   //
66   // Raising the notification multiple time without it being acquired by the
67   // consuming thread is equivalent to raising the notification once to the
68   // thread. The notification is latched in case the thread was not waiting at
69   // the time.
70   //
71   // This is IRQ and thread safe.
72   void release();
73 
74   native_handle_type native_handle();
75 
76  private:
77   // This may be a wrapper around a native type with additional members.
78   backend::NativeThreadNotification native_type_;
79 };
80 
81 }  // namespace pw::sync
82 
83 #include "pw_sync_backend/thread_notification_inline.h"
84