source: tests/concurrency/signal/wait.cfa @ ecaedf35

Last change on this file since ecaedf35 was c26bea2a, checked in by Peter A. Buhr <pabuhr@…>, 18 months ago

first attempt at renaming directory tests/concurrent to tests/concurrency to harmonize with other concurrency directory names

  • Property mode set to 100644
File size: 3.5 KB
Line 
1//---------------------------------------------------------
2// Multi wait test
3// Ensures that no deadlock from waiting/signalling conditions
4//---------------------------------------------------------
5
6
7#include <fstream.hfa>
8#include <kernel.hfa>
9#include <monitor.hfa>
10#include <stdlib.hfa>
11#include <thread.hfa>
12#include <time.hfa>
13
14#define __kick_rate 12000ul
15#include "long_tests.hfa"
16
17#ifndef PREEMPTION_RATE
18#define PREEMPTION_RATE 10`ms
19#endif
20
21Duration default_preemption() {
22        return PREEMPTION_RATE;
23}
24
25#ifdef TEST_LONG
26static const unsigned long N = 375_000ul;
27#else
28static const unsigned long N = 2_500ul;
29#endif
30
31monitor global_t {};
32
33global_t globalA;
34global_t globalB;
35global_t globalC;
36
37condition condAB, condAC, condBC, condABC;
38
39thread Signaler {};
40thread WaiterAB {};
41thread WaiterAC {};
42thread WaiterBC {};
43thread WaiterABC{};
44
45volatile int waiter_left;
46
47//----------------------------------------------------------------------------------------------------
48// Tools
49void signal( condition & cond, global_t & mutex a, global_t & mutex b ) {
50        signal( cond );
51}
52
53void signal( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
54        signal( cond );
55}
56
57void wait( condition & cond, global_t & mutex a, global_t & mutex b ) {
58        wait( cond );
59}
60
61void wait( condition & cond, global_t & mutex a, global_t & mutex b, global_t & mutex c ) {
62        wait( cond );
63}
64
65//----------------------------------------------------------------------------------------------------
66// Signaler
67void main( Signaler & this ) {
68
69        while( waiter_left != 0 ) {
70                unsigned action = random( 4 );
71                switch( action ) {
72                        case 0:
73                                signal( condABC, globalA, globalB, globalC );
74                                break;
75                        case 1:
76                                signal( condAB , globalA, globalB );
77                                break;
78                        case 2:
79                                signal( condBC , globalB, globalC );
80                                break;
81                        case 3:
82                                signal( condAC , globalA, globalC );
83                                break;
84                        default:
85                                sout | "Something went wrong";
86                                abort();
87                }
88                yield();
89        }
90}
91
92//----------------------------------------------------------------------------------------------------
93// Waiter ABC
94void main( WaiterABC & this ) {
95        for( int i = 0; TEST(i < N); i++ ) {
96                wait( condABC, globalA, globalB, globalC );
97                KICK_WATCHDOG;
98        }
99
100        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
101}
102
103//----------------------------------------------------------------------------------------------------
104// Waiter AB
105void main( WaiterAB & this ) {
106        for( int i = 0; TEST(i < N); i++ ) {
107                wait( condAB , globalA, globalB );
108                KICK_WATCHDOG;
109        }
110
111        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
112}
113
114//----------------------------------------------------------------------------------------------------
115// Waiter AC
116void main( WaiterAC & this ) {
117        for( int i = 0; TEST(i < N); i++ ) {
118                wait( condAC , globalA, globalC );
119                KICK_WATCHDOG;
120        }
121
122        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
123}
124
125//----------------------------------------------------------------------------------------------------
126// Waiter BC
127void main( WaiterBC & this ) {
128        for( int i = 0; TEST(i < N); i++ ) {
129                wait( condBC , globalB, globalC );
130                KICK_WATCHDOG;
131        }
132
133        __atomic_fetch_sub( &waiter_left, 1,  __ATOMIC_SEQ_CST );
134}
135
136//----------------------------------------------------------------------------------------------------
137// Main
138int main(int argc, char* argv[]) {
139        srandom( time( NULL ) );
140        waiter_left = 4;
141        processor p[2];
142        sout | "Starting";
143        {
144                Signaler  e;
145                {
146                        WaiterABC a;
147                        WaiterAB  b;
148                        WaiterBC  c;
149                        WaiterAC  d;
150                }
151        }
152        sout | "Done";
153}
Note: See TracBrowser for help on using the repository browser.