source: tests/concurrency/signal/wait.cfa @ 89da3a9

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