blob: c40707029ccc9c3868127eb6b8d296184b846772 [file] [log] [blame]
Brian Silvermand41b4422013-09-01 14:02:33 -07001#ifndef AOS_COMMON_CONDITION_H_
2#define AOS_COMMON_CONDITION_H_
3
Brian Silvermand41b4422013-09-01 14:02:33 -07004#include "aos/common/mutex.h"
Brian Silverman08661c72013-09-01 17:24:38 -07005#include "aos/atom_code/ipc_lib/aos_sync.h"
Brian Silvermand41b4422013-09-01 14:02:33 -07006
7namespace aos {
8
9// A condition variable (IPC mechanism where 1 process/task can notify all
Brian Silvermaneeb62ca2013-09-11 15:08:03 -070010// others that are waiting for something to happen) without the race condition
11// where a notification is sent after some process has checked if the thing has
12// happened but before it has started listening for notifications.
13//
14// This implementation will print debugging information and abort the process
15// if anything weird happens.
16//
17// A simple example of the use of a condition variable (adapted from
18// pthread_cond(3)):
19//
20// int x, y;
21// Mutex mutex;
22// Condition condition(&mutex);
23//
24// // Waiting until x is greater than y:
25// {
26// MutexLocker locker(&mutex);
27// while (!(x > y)) condition.Wait();
28// // do whatever
29// }
30//
31// // Modifying x and/or y:
32// {
33// MutexLocker locker(&mutex);
34// // modify x and y
35// if (x > y) condition.Broadcast();
36// }
37//
38// Notice the loop around the Wait(). This is very important because some other
39// process can lock the mutex and modify the shared state (possibly undoing
40// whatever the Wait()er was waiting for) in between the Broadcast()er unlocking
41// the mutex and the Wait()er(s) relocking it.
Brian Silvermand41b4422013-09-01 14:02:33 -070042//
Brian Silverman08661c72013-09-01 17:24:38 -070043// Multiple condition variables may be associated with the same mutex but
44// exactly 1 mutex must be associated with each condition variable.
Brian Silvermand41b4422013-09-01 14:02:33 -070045class Condition {
46 public:
Brian Silverman797e71e2013-09-06 17:29:39 -070047 // m is the mutex that will be associated with this condition variable. This
48 // object will hold on to a reference to it but does not take ownership.
Brian Silverman08661c72013-09-01 17:24:38 -070049 explicit Condition(Mutex *m);
Brian Silvermand41b4422013-09-01 14:02:33 -070050
Brian Silvermaneeb62ca2013-09-11 15:08:03 -070051 // Waits for the condition variable to be signalled, atomically unlocking the
52 // mutex associated with this condition variable at the same time. The mutex
53 // associated with this condition variable must be locked when this is called
54 // and will be locked when this method returns.
55 // NOTE: The relocking of the mutex is not performed atomically with waking
56 // up.
Brian Silverman08661c72013-09-01 17:24:38 -070057 void Wait();
58
59 // Signals at most 1 other process currently Wait()ing on this condition
60 // variable. Calling this does not require the mutex associated with this
61 // condition variable to be locked.
Brian Silverman797e71e2013-09-06 17:29:39 -070062 // One of the processes with the highest priority level will be woken.
Brian Silverman08661c72013-09-01 17:24:38 -070063 void Signal();
64 // Wakes all processes that are currently Wait()ing on this condition
65 // variable. Calling this does not require the mutex associated with this
66 // condition variable to be locked.
67 void Broadcast();
Brian Silvermand41b4422013-09-01 14:02:33 -070068
Brian Silverman797e71e2013-09-06 17:29:39 -070069 // Retrieves the mutex associated with this condition variable.
70 Mutex *m() { return m_; }
71
Brian Silvermand41b4422013-09-01 14:02:33 -070072 private:
Brian Silverman797e71e2013-09-06 17:29:39 -070073 mutex impl_;
Brian Silverman08661c72013-09-01 17:24:38 -070074 Mutex *m_;
Brian Silvermand41b4422013-09-01 14:02:33 -070075};
76
77} // namespace aos
78
79#endif // AOS_COMMON_CONDITION_H_