source: src/tests/sched-ext-recurse.c@ bfd4974

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since bfd4974 was 9fe39530, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

Added test for external scheduling testing when and recursion

  • Property mode set to 100644
File size: 2.9 KB
Line 
1//----------------------------------------------------------------
2// Recursion test
3// Ensures that proper ordering occurs between the nested waitfors
4//-----------------------------------------------------------------
5
6#include <fstream>
7#include <kernel>
8#include <monitor>
9#include <stdlib>
10#include <thread>
11
12#include <stdbool.h>
13#include <time.h>
14
15static const unsigned long N = 5_000ul;
16
17static inline void rand_yield() { yield(((unsigned)rand48()) % 10); }
18
19enum state_t { FIRST, SECOND, THIRD, LAST, STOP };
20void shuffle(enum state_t * array)
21{
22 int i;
23 for (i = 0; i < 4; i++)
24 {
25 int j = ((unsigned)rand48()) % 4;
26 enum state_t t = array[j];
27 array[j] = array[i];
28 array[i] = t;
29 }
30}
31
32
33monitor global_t {
34 int counter;
35 volatile bool ready;
36 state_t actions[4];
37};
38
39void ?{} ( global_t & this ) {
40 this.counter = 0;
41 this.ready = false;
42 this.actions[0] = FIRST;
43 this.actions[1] = SECOND;
44 this.actions[2] = THIRD;
45 this.actions[3] = LAST;
46 shuffle( this.actions );
47}
48
49void ^?{} ( global_t & mutex this ) {}
50
51global_t global;
52
53state_t call4( global_t & mutex this, int idx ) {
54 sout | "Last";
55
56 rand_yield();
57 this.counter++;
58 this.ready = false;
59 shuffle( this.actions );
60
61 return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
62}
63
64state_t call3( global_t & mutex this, int idx ) {
65 sout | "3rd";
66
67 rand_yield();
68 waitfor( call4, this );
69 rand_yield();
70
71 sout | "3rd";
72
73 return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
74}
75
76state_t call2( global_t & mutex this, int idx ) {
77 sout | "2nd";
78
79 rand_yield();
80 waitfor( call3, this );
81 rand_yield();
82
83 sout | "2nd";
84
85 return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
86}
87
88state_t call1( global_t & mutex this, int idx ) {
89 this.ready = true;
90
91 sout | this.counter | "1st";
92
93 rand_yield();
94 waitfor( call2, this );
95 rand_yield();
96
97 sout | "1st" | endl;
98
99 return this.counter < N ? (state_t)this.actions[idx] : (state_t)STOP;
100}
101
102thread waiter_t{
103 int idx;
104 state_t state;
105};
106
107void ^?{} ( waiter_t & mutex this ) {}
108void ?{} ( waiter_t & this ) {}
109
110void ?{}( waiter_t & this, int idx, state_t state ) {
111 this.idx = idx;
112 this.state = state;
113}
114
115
116void main( waiter_t & this ) {
117 while( this.state != STOP ) {
118 rand_yield();
119
120 switch( this.state ) {
121 case FIRST : this.state = call1( global, this.idx ); break;
122 case SECOND : while( !global.ready ) { yield(); } this.state = call2( global, this.idx ); break;
123 case THIRD : while( !global.ready ) { yield(); } this.state = call3( global, this.idx ); break;
124 case LAST : while( !global.ready ) { yield(); } this.state = call4( global, this.idx ); break;
125 case STOP : serr | "This should not happen" | endl;
126 }
127 }
128}
129
130static waiter_t * volatile the_threads;
131
132int main() {
133 rand48seed( time(NULL) );
134 sout | "Starting" | endl;
135 {
136 waiter_t waiters[4] = {
137 { 0, FIRST },
138 { 1, SECOND },
139 { 2, THIRD },
140 { 3, LAST }
141 };
142 the_threads = waiters;
143 }
144 sout | "Stopping" | endl;
145}
Note: See TracBrowser for help on using the repository browser.