source: doc/theses/colby_parsons_MMAth/benchmarks/waituntil/ucpp/future.cc @ 6c121eed

ast-experimental
Last change on this file since 6c121eed was 6c121eed, checked in by caparsons <caparson@…>, 13 months ago

intermediate commit to move some benchmarking to another machine

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include <iostream>
2using namespace std;
3#include <uFuture.h>
4
5size_t Clients = 2, Time = 10;
6
7size_t globalTotal = 0;
8Future_ISM<size_t> A, B, C;
9volatile bool server_done_loop = false;
10volatile bool client_done_loop = false;
11volatile bool client_done = false;
12volatile bool server_done = false;
13
14volatile size_t client_count = 0;
15volatile size_t client_loop_count = 0;
16_Task Client {
17        void main() {
18                size_t i = 0;
19        for(;; i++ ) {
20            _Select( A ) { A(); }
21            and _Select( B ) { B(); }
22            or _Select( C ) { C(); }
23
24            // needs to check after waituntil for termination synchronization
25            if ( client_done ) break;
26           
27            // Barrier-like synch needed to reset futures safely
28            if ( __atomic_add_fetch(&client_count, 1, __ATOMIC_SEQ_CST) == Clients ) {
29                client_count = 0;
30                A.reset();
31                B.reset();
32                C.reset();
33                client_done_loop = true;
34            }
35            while( !client_done_loop ) {} // client barrier
36            if ( __atomic_add_fetch( &client_loop_count, 1, __ATOMIC_SEQ_CST ) == Clients ) { 
37                client_done_loop = false; // reset barrier before clients can proceed past waituntil
38                server_done_loop = true; // unblock server to restart iteration
39                client_loop_count = 0;
40            }
41        }
42        __atomic_fetch_add( &globalTotal, i, __ATOMIC_SEQ_CST );
43        } 
44};
45
46_Task Server {
47        void main() {
48                for( size_t i = 0; !server_done; i++ ) {
49            if ( i % 4 == 0 ) {
50                A.delivery(i);
51                B.delivery(i);
52            } else if ( i % 4 == 1 ) {
53                A.delivery(i);
54                C.delivery(i);
55            } else if ( i % 4 == 2 ) {
56                B.delivery(i);
57                C.delivery(i);
58            } else {
59                C.delivery(i);
60            }
61            while( !server_done_loop && !server_done ) {} // server barrier
62            server_done_loop = false; // reset server barrier
63        }
64        }
65};
66
67int main( int argc, char * argv[] ) {
68        switch ( argc ) {
69          case 3:
70                if ( strcmp( argv[2], "d" ) != 0 ) {                    // default ?
71                        Time = atoi( argv[2] );
72                } // if
73          case 2:
74                if ( strcmp( argv[1], "d" ) != 0 ) {                    // default ?
75                        Clients = atoi( argv[1] );
76                        if ( Clients < 1 ) goto Usage;
77                } // if
78          case 1:                                                                                       // use defaults
79                break;
80          default:
81          Usage:
82                cerr << "Usage: " << argv[0]
83             << " [ clients (> 0) | 'd' (default " << Clients
84                         << ") ] [ time (>= 0) | 'd' (default " << Time
85                         << ") ]" ;
86                exit( EXIT_FAILURE );
87        } // switch
88    uProcessor p[Clients];
89
90    {
91        Client c[Clients];
92        {
93            Server s;
94
95            uBaseTask::sleep( uDuration( Time ) );
96
97            server_done = true;
98        }
99        while( A.available() || B.available() || C.available() ) {}
100        client_done = true;
101        C.delivery(1); // can't deliver 0 since it causes ambiguity
102    }
103    cout << globalTotal << endl;
104} // main
Note: See TracBrowser for help on using the repository browser.