source: src/tests/concurrent/signal/block.c @ 0f56058

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumwith_gc
Last change on this file since 0f56058 was 0f56058, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

divide "time" into type and functions

  • Property mode set to 100644
File size: 3.1 KB
Line 
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
9#include <fstream>
10#include <kernel>
11#include <monitor>
12#include <stdlib>
13#include <thread>
14#include <time>
15
16#ifdef LONG_TEST
17static const unsigned long N = 150_000ul;
18#else
19static const unsigned long N = 5_000ul;
20#endif
21
22#ifndef PREEMPTION_RATE
23#define PREEMPTION_RATE 10`ms
24#endif
25
26Duration default_preemption() {
27        return PREEMPTION_RATE;
28}
29
30enum state_t { WAITED, SIGNAL, BARGE };
31
32monitor global_data_t {
33        thread_desc * last_thread;
34        thread_desc * last_signaller;
35};
36
37void ?{} ( global_data_t & this ) {
38        this.last_thread = NULL;
39        this.last_signaller = NULL;
40}
41
42void ^?{} ( global_data_t & this ) {}
43
44global_data_t globalA, globalB;
45
46condition cond;
47
48volatile bool done;
49
50//------------------------------------------------------------------------------
51void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) {
52    wait( cond, (uintptr_t)active_thread() );
53
54        yield( random( 10 ) );
55
56        if(a.last_thread != a.last_signaller || b.last_thread != b.last_signaller ) {
57                sout | "ERROR Barging detected, expected" | a.last_signaller | b.last_signaller | "got" | a.last_thread | b.last_thread | endl;
58                abort();
59        }
60
61        a.last_thread = b.last_thread = active_thread();
62
63        yield( random( 10 ) );
64}
65
66thread Waiter {};
67void main( Waiter & this ) {
68        for( int i = 0; i < N; i++ ) {
69                wait_op( globalA, globalB, i );
70        }
71}
72
73//------------------------------------------------------------------------------
74void signal_op( global_data_t & mutex a, global_data_t & mutex b ) {
75        yield( random( 10 ) );
76
77        [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = active_thread();
78
79        if( !is_empty( cond ) ) {
80
81                thread_desc * next = front( cond );
82
83                if( ! signal_block( cond ) ) {
84                        sout | "ERROR expected to be able to signal" | endl;
85                        abort();
86                }
87
88                yield( random( 10 ) );
89
90                if(a.last_thread != next || b.last_thread != next) {
91                        sout | "ERROR Barging detected, expected" | next | "got" | a.last_thread | b.last_thread | endl;
92                        abort();
93                }
94        }
95
96}
97
98thread Signaller {};
99void main( Signaller & this ) {
100        while( !done ) {
101                signal_op( globalA, globalB );
102        }
103}
104
105//------------------------------------------------------------------------------
106void barge_op( global_data_t & mutex a ) {
107        a.last_thread = active_thread();
108}
109
110thread Barger {};
111void main( Barger & this ) {
112        for( unsigned i = 0; !done; i++ ) {
113                //Choose some monitor to barge into with some irregular pattern
114                bool choose_a = (i % 13) > (i % 17);
115                if ( choose_a ) barge_op( globalA );
116                else barge_op( globalB );
117        }
118}
119
120//------------------------------------------------------------------------------
121
122int main(int argc, char* argv[]) {
123        srandom( time( NULL ) );
124        done = false;
125        processor p;
126        {
127                Signaller s[4];
128                Barger b[13];
129                sout | "Starting waiters" | endl;
130                {
131                        Waiter w[3];
132                }
133                sout | "Waiters done" | endl;
134                done = true;
135        }
136}
Note: See TracBrowser for help on using the repository browser.