source: libcfa/src/concurrency/future.hfa@ 708ae38

ADT ast-experimental enum pthread-emulation qualifiedEnum
Last change on this file since 708ae38 was 8f1a99e, checked in by Thierry Delisle <tdelisle@…>, 4 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.