@@ -145,3 +145,74 @@ impl<T: ?Sized> Drop for MutexGuard<'_, T> {
145
145
self . lock . inner . unlock ( ) . unwrap ( ) ;
146
146
}
147
147
}
148
+
149
+ /// Inspired by
150
+ /// [`std::sync::Condvar`](https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html),
151
+ /// implemented directly using `z_condvar` in Zephyr.
152
+ ///
153
+ /// Condition variables represent the ability to block a thread such that it consumes no CPU time
154
+ /// while waiting for an even to occur. Condition variables are typically associated with a
155
+ /// boolean predicate (a condition) and a mutex. The predicate is always verified inside of the
156
+ /// mutex before determining that a thread must block.
157
+ ///
158
+ /// Functions in this module will block the current **thread** of execution. Note that any attempt
159
+ /// to use multiple mutexces on the same condition variable may result in a runtime panic.
160
+ pub struct Condvar {
161
+ inner : sys:: Condvar ,
162
+ }
163
+
164
+ impl Condvar {
165
+ /// Construct a new wrapped Condvar, using the given underlying `k_condvar`.
166
+ ///
167
+ /// This is different from `std::sync::Condvar` in that in Zephyr, objects are frequently
168
+ /// allocated statically, and the sys Condvar will be taken by this structure.
169
+ pub const fn new_from ( raw_condvar : sys:: Condvar ) -> Condvar {
170
+ Condvar { inner : raw_condvar }
171
+ }
172
+
173
+ /// Blocks the current thread until this conditional variable receives a notification.
174
+ ///
175
+ /// This function will automatically unlock the mutex specified (represented by `guard`) and
176
+ /// block the current thread. This means that any calls to `notify_one` or `notify_all` which
177
+ /// happen logically after the mutex is unlocked are candidates to wake this thread up. When
178
+ /// this function call returns, the lock specified will have been re-equired.
179
+ ///
180
+ /// Note that this function is susceptable to spurious wakeups. Condition variables normally
181
+ /// have a boolean predicate associated with them, and the predicate must always be checked
182
+ /// each time this function returns to protect against spurious wakeups.
183
+ pub fn wait < ' a , T > ( & self , guard : MutexGuard < ' a , T > ) -> LockResult < MutexGuard < ' a , T > > {
184
+ self . inner . wait ( & guard. lock . inner ) ;
185
+ Ok ( guard)
186
+ }
187
+
188
+ // TODO: wait_while
189
+ // TODO: wait_timeout_ms
190
+ // TODO: wait_timeout
191
+ // TODO: wait_timeout_while
192
+
193
+ /// Wakes up one blocked thread on this condvar.
194
+ ///
195
+ /// If there is a blocked thread on this condition variable, then it will be woken up from its
196
+ /// call to `wait` or `wait_timeout`. Calls to `notify_one` are not buffered in any way.
197
+ ///
198
+ /// To wakeup all threads, see `notify_all`.
199
+ pub fn notify_one ( & self ) {
200
+ self . inner . notify_one ( ) ;
201
+ }
202
+
203
+ /// Wakes up all blocked threads on this condvar.
204
+ ///
205
+ /// This methods will ensure that any current waiters on the condition variable are awoken.
206
+ /// Calls to `notify_all()` are not buffered in any way.
207
+ ///
208
+ /// To wake up only one thread, see `notify_one`.
209
+ pub fn notify_all ( & self ) {
210
+ self . inner . notify_all ( ) ;
211
+ }
212
+ }
213
+
214
+ impl fmt:: Debug for Condvar {
215
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
216
+ write ! ( f, "Condvar {:?}" , self . inner)
217
+ }
218
+ }
0 commit comments