1 | #include <fstream>
|
---|
2 | #include <kernel>
|
---|
3 | #include <monitor>
|
---|
4 | #include <stdlib>
|
---|
5 | #include <thread>
|
---|
6 |
|
---|
7 | monitor global_t {};
|
---|
8 |
|
---|
9 | global_t globalA;
|
---|
10 | global_t globalB;
|
---|
11 | global_t globalC;
|
---|
12 |
|
---|
13 | condition condAB, condAC, condBC, condABC;
|
---|
14 |
|
---|
15 | thread Signaler {
|
---|
16 | int signals[4];
|
---|
17 | };
|
---|
18 |
|
---|
19 | void ?{}( Signaler * this ){
|
---|
20 | this->signals[0] = 0;
|
---|
21 | this->signals[1] = 0;
|
---|
22 | this->signals[2] = 0;
|
---|
23 | this->signals[3] = 0;
|
---|
24 | }
|
---|
25 |
|
---|
26 | thread WaiterAB {};
|
---|
27 | thread WaiterAC {};
|
---|
28 | thread WaiterBC {};
|
---|
29 | thread WaiterABC{};
|
---|
30 |
|
---|
31 | volatile bool done;
|
---|
32 |
|
---|
33 | //----------------------------------------------------------------------------------------------------
|
---|
34 | // Tools
|
---|
35 | void signal( condition * cond, global_t * mutex a, global_t * mutex b ) {
|
---|
36 | signal( cond );
|
---|
37 | }
|
---|
38 |
|
---|
39 | void signal( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
|
---|
40 | signal( cond );
|
---|
41 | }
|
---|
42 |
|
---|
43 | void wait( condition * cond, global_t * mutex a, global_t * mutex b ) {
|
---|
44 | wait( cond );
|
---|
45 | }
|
---|
46 |
|
---|
47 | void wait( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
|
---|
48 | wait( cond );
|
---|
49 | }
|
---|
50 |
|
---|
51 | //----------------------------------------------------------------------------------------------------
|
---|
52 | // Signaler
|
---|
53 | void main( Signaler* this ) {
|
---|
54 |
|
---|
55 | while( true ) {
|
---|
56 | int action = (unsigned)rand48() % 4;
|
---|
57 | bool finished = true;
|
---|
58 |
|
---|
59 | for(int i = 0; i < 4; i++) {
|
---|
60 | if( this->signals[action] < 10_000 ) {
|
---|
61 | finished = false;
|
---|
62 | break;
|
---|
63 | }
|
---|
64 | else {
|
---|
65 | action = (action + 1) % 4;
|
---|
66 | }
|
---|
67 | }
|
---|
68 |
|
---|
69 | this->signals[action]++;
|
---|
70 | if( finished ) break;
|
---|
71 |
|
---|
72 | //sout | action | this->signals[0] | this->signals[1] | this->signals[2] | this->signals[3] | endl;
|
---|
73 |
|
---|
74 | switch( action ) {
|
---|
75 | case 0:
|
---|
76 | signal( &condABC, &globalA, &globalB, &globalC );
|
---|
77 | break;
|
---|
78 | case 1:
|
---|
79 | signal( &condAB , &globalA, &globalB );
|
---|
80 | break;
|
---|
81 | case 2:
|
---|
82 | signal( &condBC , &globalB, &globalC );
|
---|
83 | break;
|
---|
84 | case 3:
|
---|
85 | signal( &condAC , &globalA, &globalC );
|
---|
86 | break;
|
---|
87 | default:
|
---|
88 | sout | "Something went wrong" | endl;
|
---|
89 | abort();
|
---|
90 | }
|
---|
91 | }
|
---|
92 | }
|
---|
93 |
|
---|
94 | //----------------------------------------------------------------------------------------------------
|
---|
95 | // Waiter ABC
|
---|
96 | void main( WaiterABC* this ) {
|
---|
97 | while( !done ) {
|
---|
98 | wait( &condABC, &globalA, &globalB, &globalC );
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 | //----------------------------------------------------------------------------------------------------
|
---|
103 | // Waiter AB
|
---|
104 | void main( WaiterAB* this ) {
|
---|
105 | while( !done ) {
|
---|
106 | wait( &condAB , &globalA, &globalB );
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | //----------------------------------------------------------------------------------------------------
|
---|
111 | // Waiter AC
|
---|
112 | void main( WaiterAC* this ) {
|
---|
113 | while( !done ) {
|
---|
114 | wait( &condAC , &globalA, &globalC );
|
---|
115 | }
|
---|
116 | }
|
---|
117 |
|
---|
118 | //----------------------------------------------------------------------------------------------------
|
---|
119 | // Waiter BC
|
---|
120 | void main( WaiterBC* this ) {
|
---|
121 | while( !done ) {
|
---|
122 | wait( &condBC , &globalB, &globalC );
|
---|
123 | }
|
---|
124 | }
|
---|
125 |
|
---|
126 | //----------------------------------------------------------------------------------------------------
|
---|
127 | // Main
|
---|
128 | int main(int argc, char* argv[]) {
|
---|
129 | done = false;
|
---|
130 | processor p;
|
---|
131 | {
|
---|
132 | WaiterABC a;
|
---|
133 | WaiterAB b;
|
---|
134 | WaiterBC c;
|
---|
135 | WaiterAC d;
|
---|
136 | {
|
---|
137 | Signaler e;
|
---|
138 | }
|
---|
139 | done = true;
|
---|
140 | signal( &condABC, &globalA, &globalB, &globalC );
|
---|
141 | signal( &condAB , &globalA, &globalB );
|
---|
142 | signal( &condBC , &globalB, &globalC );
|
---|
143 | signal( &condAC , &globalA, &globalC );
|
---|
144 | }
|
---|
145 | }
|
---|