source: tests/concurrency/waitfor/barge.cfa @ 115ac1ce

Last change on this file since 115ac1ce was c26bea2a, checked in by Peter A. Buhr <pabuhr@…>, 17 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: 1.7 KB
Line 
1//---------------------------------------------------------
2// Barging test
3// Ensures that no barging can occur between :
4//   - the frontend of the waitfor and the waited call
5//   - the waited call and the backend of the waitfor
6//---------------------------------------------------------
7
8#include <fstream.hfa>
9#include <kernel.hfa>
10#include <monitor.hfa>
11#include <stdlib.hfa>
12#include <thread.hfa>
13
14#include <stdbool.h>
15
16static const unsigned long N = 5_000ul;
17
18enum state_t { WAITFOR, CALL, BARGE };
19
20monitor global_t {
21        bool done;
22        bool started;
23        state_t state;
24};
25
26void ?{} ( global_t & this ) {
27        this.done = false;
28        this.started = false;
29        this.state = BARGE;
30}
31
32void ^?{} ( global_t & mutex this ) {}
33
34global_t global;
35
36bool barge( global_t & mutex this ) {
37        this.state = BARGE;
38        return !this.done;
39}
40
41thread barger_t {};
42void main( barger_t & this ) {
43        yield();
44        while( barge( global ) ) { yield(random( 10 )); }
45}
46
47bool do_call( global_t & mutex this ) {
48        yield(random( 10 ));
49        if( this.state != WAITFOR && !this.done && this.started ) {
50                serr | "Barging before caller detected";
51        }
52
53        this.state = CALL;
54        return !this.done;
55}
56
57thread caller_t {};
58void main( caller_t & this ) {
59        while( do_call(global) ) { yield(random( 10 )); }
60}
61
62void do_wait( global_t & mutex this ) {
63        this.started = true;
64        for( int i = 0; i < N; i++) {
65                yield(random( 10 ));
66                this.state = WAITFOR;
67                waitfor(do_call : this) {
68                        sout | i;
69                }
70
71                if( this.state != CALL ) {
72                        serr | "Barging after caller detected";
73                }
74        }
75
76        this.done = true;
77}
78
79thread waiter_t{};
80void main( waiter_t & this ) {
81        do_wait(global);
82}
83
84int main() {
85        sout | "Starting";
86        {
87                barger_t bargers[17];
88                caller_t callers[7];
89                waiter_t waiters;
90        }
91        sout | "Stopping";
92}
Note: See TracBrowser for help on using the repository browser.