source: tests/concurrency/waituntil/repeat_close.cfa@ fc95df3

Last change on this file since fc95df3 was d829c6d, checked in by caparsons <caparson@…>, 2 years ago

added test that consistently produced the waituntil channel close failure case

  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include <select.hfa>
2#include <thread.hfa>
3#include <channel.hfa>
4#include <time.hfa>
5
6channel(long long int) A, B, C, D, E, F;
7
8volatile long long int inserts = 0;
9volatile long long int removes = 0;
10
11thread Producer {};
12void main( Producer & this ) {
13 long long int my_inserts = 0;
14 long long int A_i = 0, B_i = 0, C_i = 0, D_i = 0, E_i = 0, F_i = 0;
15 try {
16 for( long long int i = 0;;i++ ) {
17 waituntil( (i >> A) ) { A_i++; }
18 and waituntil( (i >> B) ) { B_i++; }
19 and waituntil( (i >> C) ) { C_i++; }
20 and waituntil( (i >> D) ) { D_i++; }
21 and waituntil( (i >> E) ) { E_i++; }
22 and waituntil( (i >> F) ) { F_i++; }
23 }
24 } catch ( channel_closed * e ) {}
25 __atomic_fetch_add( &inserts, A_i + B_i + C_i + D_i + E_i + F_i, __ATOMIC_SEQ_CST );
26}
27
28
29thread Consumer {};
30void main( Consumer & this ) {
31 long long int in, A_removes = 0, B_removes = 0, C_removes = 0, D_removes = 0, E_removes = 0, F_removes = 0;
32 try {
33 for( ;; ) {
34 waituntil( (in << F) ) { F_removes++; }
35 or waituntil( (in << E) ) { E_removes++; }
36 or waituntil( (in << D) ) { D_removes++; }
37 or waituntil( (in << C) ) { C_removes++; }
38 or waituntil( (in << B) ) { B_removes++; }
39 or waituntil( (in << A) ) { A_removes++; }
40 }
41 } catchResume ( channel_closed * e ) { } // continue to remove until would block
42 catch ( channel_closed * e ) {}
43 try {
44 for( ;; )
45 waituntil( (in << A) ) { A_removes++; }
46 } catchResume ( channel_closed * e ) {} // continue to remove until would block
47 catch ( channel_closed * e ) {}
48 try {
49 for( ;; )
50 waituntil( (in << B) ) { B_removes++; }
51 } catchResume ( channel_closed * e ) {} // continue to remove until would block
52 catch ( channel_closed * e ) {}
53 try {
54 for( ;; )
55 waituntil( (in << C) ) { C_removes++; }
56 } catchResume ( channel_closed * e ) {} // continue to remove until would block
57 catch ( channel_closed * e ) {}
58 try {
59 for( ;; )
60 waituntil( (in << D) ) { D_removes++; }
61 } catchResume ( channel_closed * e ) {} // continue to remove until would block
62 catch ( channel_closed * e ) {}
63 try {
64 for( ;; )
65 waituntil( (in << E) ) { E_removes++; }
66 } catchResume ( channel_closed * e ) {} // continue to remove until would block
67 catch ( channel_closed * e ) {}
68 try {
69 for( ;; )
70 waituntil( (in << F) ) { F_removes++; }
71 } catchResume ( channel_closed * e ) {} // continue to remove until would block
72 catch ( channel_closed * e ) {}
73 __atomic_fetch_add( &removes, A_removes + B_removes + C_removes + D_removes + E_removes + F_removes, __ATOMIC_SEQ_CST );
74}
75
76
77size_t time = 3, num_times = 10, chan_size = 0, num_thds = 2;
78int main( int argc, char * argv[] ) {
79 if ( argc == 2 )
80 time = atoi( argv[1] );
81
82 processor p[ num_thds - 1 ];
83
84 printf("Start\n");
85 for ( i; num_times ) {
86 printf("%lu\n", i);
87 A{chan_size};
88 B{chan_size};
89 C{chan_size};
90 D{chan_size};
91 E{chan_size};
92 F{chan_size};
93 {
94 Producer p[ num_thds / 2 ];
95 Consumer c[ 1 ];
96 sleep(time`s);
97 close(A);
98 close(B);
99 close(C);
100 close(D);
101 close(E);
102 close(F);
103 }
104 if ( inserts != removes ) {
105 printf("\n");
106 printf("CHECKSUM MISMATCH!! Producer got: %lld, Consumer got: %lld\n", inserts, removes);
107 assert(false);
108 }
109 ^A{};
110 ^B{};
111 ^C{};
112 ^D{};
113 ^E{};
114 ^F{};
115
116 inserts = 0;
117 removes = 0;
118 }
119
120 A{5};
121 B{5};
122 C{5};
123 D{5};
124 E{5};
125 F{5};
126 printf("Done\n");
127}
Note: See TracBrowser for help on using the repository browser.