source: tests/concurrency/signal/block.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.1 KB
RevLine 
[9fe39530]1//---------------------------------------------------------
2// Barging test
3// Ensures that no barging can occur between :
4//   - the frontend of the signal_block and the signaled thread
5//   - the signaled  threadand the backend of the signal_block
6//---------------------------------------------------------
7
8
[73abe95]9#include <fstream.hfa>
[096a2ff]10#include <kernel.hfa>
[73abe95]11#include <monitor.hfa>
12#include <stdlib.hfa>
13#include <thread.hfa>
14#include <time.hfa>
[cd99ef1]15
[dc8511c]16#include "long_tests.hfa"
[7bdcac1]17
[cd99ef1]18#ifndef PREEMPTION_RATE
[8ad6533]19#define PREEMPTION_RATE 10`ms
[e1c1829]20#endif
[2c9ebab]21
[8ad6533]22Duration default_preemption() {
[cd99ef1]23        return PREEMPTION_RATE;
24}
25
[7bdcac1]26#ifdef TEST_LONG
[b9da9585]27static const unsigned long N = 150_000ul;
28#else
29static const unsigned long N = 5_000ul;
30#endif
31
[2c9ebab]32enum state_t { WAITED, SIGNAL, BARGE };
33
34monitor global_data_t {
[8f1a99e]35        thread$ * last_thread;
36        thread$ * last_signaller;
[2c9ebab]37};
38
[00e80b6]39void ?{} ( global_data_t & this ) {
40        this.last_thread = NULL;
41        this.last_signaller = NULL;
[2c9ebab]42}
43
[8638cef]44void ^?{} ( global_data_t & mutex this ) {}
[2c9ebab]45
46global_data_t globalA, globalB;
47
48condition cond;
49
50volatile bool done;
51
52//------------------------------------------------------------------------------
[83a071f9]53void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) {
[94ddede]54    wait( cond, (uintptr_t)active_thread() );
[2c9ebab]55
[6c7b1e7]56        yield( random( 10 ) );
[2c9ebab]57
[83a071f9]58        if(a.last_thread != a.last_signaller || b.last_thread != b.last_signaller ) {
[200fcb3]59                sout | "ERROR Barging detected, expected" | a.last_signaller | b.last_signaller | "got" | a.last_thread | b.last_thread;
[2c9ebab]60                abort();
61        }
62
[94ddede]63        a.last_thread = b.last_thread = active_thread();
[2c9ebab]64
[6c7b1e7]65        yield( random( 10 ) );
[2c9ebab]66}
67
68thread Waiter {};
[83a071f9]69void main( Waiter & this ) {
[7bdcac1]70        for( int i = 0; TEST(i < N); i++ ) {
[83a071f9]71                wait_op( globalA, globalB, i );
[7bdcac1]72                KICK_WATCHDOG;
[2c9ebab]73        }
74}
75
76//------------------------------------------------------------------------------
[83a071f9]77void signal_op( global_data_t & mutex a, global_data_t & mutex b ) {
[6c7b1e7]78        yield( random( 10 ) );
[2c9ebab]79
[94ddede]80        [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = active_thread();
[2c9ebab]81
[4cedd9f]82        if( !is_empty( cond ) ) {
[2c9ebab]83
[8f1a99e]84                thread$ * next = ( thread$ * ) front( cond );
[2c9ebab]85
[4cedd9f]86                if( ! signal_block( cond ) ) {
[200fcb3]87                        sout | "ERROR expected to be able to signal";
[ccd349d]88                        abort();
89                }
90
[6c7b1e7]91                yield( random( 10 ) );
[ccd349d]92
[83a071f9]93                if(a.last_thread != next || b.last_thread != next) {
[200fcb3]94                        sout | "ERROR Barging detected, expected" | next | "got" | a.last_thread | b.last_thread;
[2c9ebab]95                        abort();
96                }
97        }
98
99}
100
101thread Signaller {};
[83a071f9]102void main( Signaller & this ) {
[2c9ebab]103        while( !done ) {
[83a071f9]104                signal_op( globalA, globalB );
[2c9ebab]105        }
106}
107
108//------------------------------------------------------------------------------
[83a071f9]109void barge_op( global_data_t & mutex a ) {
[94ddede]110        a.last_thread = active_thread();
[2c9ebab]111}
112
113thread Barger {};
[83a071f9]114void main( Barger & this ) {
[2c9ebab]115        for( unsigned i = 0; !done; i++ ) {
116                //Choose some monitor to barge into with some irregular pattern
117                bool choose_a = (i % 13) > (i % 17);
[83a071f9]118                if ( choose_a ) barge_op( globalA );
119                else barge_op( globalB );
[2c9ebab]120        }
121}
122
123//------------------------------------------------------------------------------
124
125int main(int argc, char* argv[]) {
[54aba8d]126        srandom( time( NULL ) );
[2c9ebab]127        done = false;
128        processor p;
129        {
130                Signaller s[4];
131                Barger b[13];
[200fcb3]132                sout | "Starting waiters";
[2c9ebab]133                {
134                        Waiter w[3];
135                }
[200fcb3]136                sout | "Waiters done";
[2c9ebab]137                done = true;
138        }
[736fe25]139}
Note: See TracBrowser for help on using the repository browser.