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

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