source: tests/concurrency/signal/disjoint.cfa @ d796be70

Last change on this file since d796be70 was c26bea2a, checked in by Peter A. Buhr <pabuhr@…>, 17 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: 2.9 KB
Line 
1#include <fstream.hfa>
2#include <kernel.hfa>
3#include <monitor.hfa>
4#include <thread.hfa>
5#include <time.hfa>
6
7#include "long_tests.hfa"
8
9#ifndef PREEMPTION_RATE
10#define PREEMPTION_RATE 10`ms
11#endif
12
13Duration default_preemption() {
14        return PREEMPTION_RATE;
15}
16
17#ifdef TEST_LONG
18static const unsigned long N = 300_000ul;
19#else
20static const unsigned long N = 10_000ul;
21#endif
22
23// This tests checks what happens when someone barges in the midle of the release
24// of a bulk of monitors.
25
26enum state_t { WAIT, SIGNAL, BARGE };
27
28monitor global_t {};
29
30monitor global_data_t;
31void ?{}( global_data_t & this );
32void ^?{} ( global_data_t & mutex this );
33
34monitor global_data_t {
35        int counter;
36        state_t state;
37};
38
39// Use a global struct because the order needs to match with Signaller thread
40static struct {
41        global_t mut;
42        global_data_t data;
43} globals;
44
45condition cond;
46
47volatile bool all_done;
48
49void ?{}( global_data_t & this ) {
50        this.counter = 0;
51        this.state = BARGE;
52}
53
54void ^?{} ( global_data_t & mutex this ) {}
55
56//------------------------------------------------------------------------------
57// Barging logic
58void barge( global_data_t & mutex d ) {
59        d.state = BARGE;
60}
61
62thread Barger {};
63void ?{}( Barger & this ) {
64        ((thread&)this){ "Barger Thread" };
65}
66
67void main( Barger & this ) {
68        while( !all_done ) {
69                barge( globals.data );
70                yield();
71        }
72}
73
74//------------------------------------------------------------------------------
75// Waiting logic
76bool wait( global_t & mutex m, global_data_t & mutex d ) {
77        wait( cond );
78        if( d.state != SIGNAL ) {
79                abort | "ERROR barging!";
80        }
81
82        #if !defined(TEST_FOREVER)
83                d.counter++;
84                if( (d.counter % 1000) == 0 ) sout | d.counter;
85        #endif
86
87        return TEST(d.counter < N);
88}
89
90thread Waiter {};
91void ?{}( Waiter & this ) {
92        ((thread&)this){ "Waiter Thread" };
93}
94
95void main( Waiter & this ) {
96        while( wait( globals.mut, globals.data ) ) { KICK_WATCHDOG; yield(); }
97}
98
99
100//------------------------------------------------------------------------------
101// Signalling logic
102void signal( condition & cond, global_t & mutex a, global_data_t & mutex b ) {
103        b.state = SIGNAL;
104        signal( cond );
105}
106
107void logic( global_t & mutex a ) {
108        signal( cond, a, globals.data );
109
110        yield( random( 10 ) );
111
112        //This is technically a mutual exclusion violation but the mutex monitor protects us
113        bool running = TEST(globals.data.counter < N) && globals.data.counter > 0;
114        if( globals.data.state != SIGNAL && running ) {
115                abort | "ERROR Eager signal" | globals.data.state;
116        }
117}
118
119thread Signaller {};
120void ?{}( Signaller & this ) {
121        ((thread&)this){ "Signaller Thread" };
122}
123
124void main( Signaller & this ) {
125        while( !all_done ) {
126                logic( globals.mut );
127                yield();
128        }
129}
130
131//------------------------------------------------------------------------------
132// Main loop
133int main(int argc, char* argv[]) {
134        srandom( time( NULL ) );
135        all_done = false;
136        processor p;
137        {
138                Signaller s;
139                Barger b[17];
140                {
141                        Waiter w[4];
142                }
143                sout | "All waiter done";
144                all_done = true;
145        }
146}
Note: See TracBrowser for help on using the repository browser.