source: tests/concurrency/signal/wait.cfa@ 0497b6ba

Last change on this file since 0497b6ba was c26bea2a, checked in by Peter A. Buhr <pabuhr@…>, 2 years 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.