blob: d846ab1b880cbd4a0db2a942533d72844bc30fdf [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_CONDITION_H_
2#define AOS_CONDITION_H_
Brian Silvermand41b4422013-09-01 14:02:33 -07003
Brian Silverman14fd0fb2014-01-14 21:42:01 -08004#include "aos/linux_code/ipc_lib/aos_sync.h"
Brian Silvermand41b4422013-09-01 14:02:33 -07005
6namespace aos {
7
Brian Silvermandc1eb272014-08-19 14:25:59 -04008class Mutex;
9
Brian Silvermand41b4422013-09-01 14:02:33 -070010// A condition variable (IPC mechanism where 1 process/task can notify all
Brian Silvermaneeb62ca2013-09-11 15:08:03 -070011// others that are waiting for something to happen) without the race condition
12// where a notification is sent after some process has checked if the thing has
13// happened but before it has started listening for notifications.
14//
Brian Silvermandc1eb272014-08-19 14:25:59 -040015// This implementation will LOG(FATAL) if anything weird happens.
Brian Silvermaneeb62ca2013-09-11 15:08:03 -070016//
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
Brian Silvermandc1eb272014-08-19 14:25:59 -040044// exactly one 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 Silverman71c55c52014-08-19 14:31:59 -040057 // Returns true if the previous owner of the mutex died before we relocked it.
Brian Silvermandc1eb272014-08-19 14:25:59 -040058 bool Wait() __attribute__((warn_unused_result));
Brian Silverman08661c72013-09-01 17:24:38 -070059
Brian Silvermandc1eb272014-08-19 14:25:59 -040060 // Signals approximately 1 other process currently Wait()ing on this condition
Brian Silverman08661c72013-09-01 17:24:38 -070061 // variable. Calling this does not require the mutex associated with this
62 // condition variable to be locked.
Brian Silverman797e71e2013-09-06 17:29:39 -070063 // One of the processes with the highest priority level will be woken.
Brian Silvermandc1eb272014-08-19 14:25:59 -040064 // If there aren't any waiting at the time, none will be woken. There is a
65 // small race condition in the Linux implementation that can result in more
66 // than 1 being woken.
Brian Silverman08661c72013-09-01 17:24:38 -070067 void Signal();
68 // Wakes all processes that are currently Wait()ing on this condition
69 // variable. Calling this does not require the mutex associated with this
70 // condition variable to be locked.
71 void Broadcast();
Brian Silvermand41b4422013-09-01 14:02:33 -070072
Brian Silverman797e71e2013-09-06 17:29:39 -070073 // Retrieves the mutex associated with this condition variable.
74 Mutex *m() { return m_; }
75
Brian Silvermand41b4422013-09-01 14:02:33 -070076 private:
Brian Silvermandc1eb272014-08-19 14:25:59 -040077 aos_condition impl_;
Brian Silverman08661c72013-09-01 17:24:38 -070078 Mutex *m_;
Brian Silvermand41b4422013-09-01 14:02:33 -070079};
80
81} // namespace aos
82
John Park33858a32018-09-28 23:05:48 -070083#endif // AOS_CONDITION_H_