source: libcfa/src/concurrency/future.hfa @ 6a4ef0c

ADTast-experimental
Last change on this file since 6a4ef0c was 8f1a99e, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Step 3 Fixed tests

  • Property mode set to 100644
File size: 2.8 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// io/types.hfa --
8//
9// Author           : Thierry Delisle & Peiran Hong
10// Created On       : Wed Jan 06 17:33:18 2021
11// Last Modified By :
12// Last Modified On :
13// Update Count     :
14//
15
16#pragma once
17
18#include "bits/locks.hfa"
19#include "monitor.hfa"
20
21forall( T ) {
22        struct future {
23                inline future_t;
24                T result;
25        };
26
27        static inline {
28                // Reset future back to original state
29                void reset(future(T) & this) { reset( (future_t&)this ); }
30
31                // check if the future is available
32                bool available( future(T) & this ) { return available( (future_t&)this ); }
33
34                // Mark the future as abandoned, meaning it will be deleted by the server
35                // This doesn't work beause of the potential need for a destructor
36                void abandon( future(T) & this );
37
38                // Fulfil the future, returns whether or not someone was unblocked
39                thread$ * fulfil( future(T) & this, T result ) {
40                        this.result = result;
41                        return fulfil( (future_t&)this );
42                }
43
44                // Wait for the future to be fulfilled
45                // Also return whether the thread had to block or not
46                [T, bool] wait( future(T) & this ) {
47                        bool r = wait( (future_t&)this );
48                        return [this.result, r];
49                }
50
51                // Wait for the future to be fulfilled
52                T wait( future(T) & this ) {
53                        [T, bool] tt;
54                        tt = wait(this);
55                        return tt.0;
56                }
57        }
58}
59
60forall( T ) {
61        monitor multi_future {
62                inline future_t;
63                condition blocked;
64                bool has_first;
65                T result;
66        };
67
68        static inline {
69                void ?{}(multi_future(T) & this) {
70                        this.has_first = false;
71                }
72
73                bool $first( multi_future(T) & mutex this ) {
74                        if (this.has_first) {
75                                wait( this.blocked );
76                                return false;
77                        }
78
79                        this.has_first = true;
80                        return true;
81                }
82
83                void $first_done( multi_future(T) & mutex this ) {
84                        this.has_first = false;
85                        signal_all( this.blocked );
86                }
87
88                // Reset future back to original state
89                void reset(multi_future(T) & mutex this) {
90                        if( this.has_first != false) abort("Attempting to reset a multi_future with at least one blocked threads");
91                        if( !is_empty(this.blocked) ) abort("Attempting to reset a multi_future with multiple blocked threads");
92                        reset( (future_t&)this );
93                }
94
95                // Fulfil the future, returns whether or not someone was unblocked
96                bool fulfil( multi_future(T) & this, T result ) {
97                        this.result = result;
98                        return fulfil( (future_t&)this ) != 0p;
99                }
100
101                // Wait for the future to be fulfilled
102                // Also return whether the thread had to block or not
103                [T, bool] wait( multi_future(T) & this ) {
104                        bool sw = $first( this );
105                        bool w = !sw;
106                        if ( sw ) {
107                                w = wait( (future_t&)this );
108                                $first_done( this );
109                        }
110
111                        return [this.result, w];
112                }
113
114                // Wait for the future to be fulfilled
115                T wait( multi_future(T) & this ) {
116                        return wait(this).0;
117                }
118        }
119}
Note: See TracBrowser for help on using the repository browser.