@@ -148,17 +148,26 @@ To assign a new value to a _sync_ variable, its state must be _empty_ (after the
148148completed, the state will be set as _ full_ ). On the contrary, to read a value from a _ sync_ variable, its
149149state must be _ full_ (after the read operation is completed, the state will be set as _ empty_ again).
150150
151+ Starting from Chapel 2.x, you must use functions ` writeEF ` and ` readFF ` to perform blocking write and read
152+ with sync variables. Below is an example to demonstrate the use of sync variables. Here we launch a new task
153+ that is busy for a short time executing the loop. While this loop is running, the main task continues printing
154+ the message "this is main task after launching new task... I will wait until it is done". As it takes time to
155+ spawn a new thread, it is very likely that you will see this message before the output from the loop. Next,
156+ the main task will attempt to read ` x ` and assign it to ` a ` which it can only do when ` x ` is full. We write
157+ into ` x ` after the loop, so you will see the final message "and now it is done" only after the message "New
158+ task finished". In other words, reading ` x ` , we pause the execution of the main thread.
159+
151160``` chpl
152161var x: sync int, a: int;
153162writeln("this is main task launching a new task");
154163begin {
155164 for i in 1..10 do writeln("this is new task working: ",i);
156- x.writeEF(2);
165+ x.writeEF(2); // assign 2 to x
157166 writeln("New task finished");
158167}
159168
160- writeln("this is main task after launching new task... I will wait until it is done");
161- a = x.readFF (); // don't run this line until the variable x is written in the other task
169+ writeln("this is main task after launching new task... I will wait until it is done");
170+ a = x.readFE (); // don't run this line until the variable x is written in the other task
162171writeln("and now it is done");
163172```
164173
@@ -169,7 +178,7 @@ chpl sync_example_2.chpl
169178
170179``` output
171180this is main task launching a new task
172- this is main task after launching new task... I will wait until it is done
181+ this is main task after launching new task... I will wait until it is done
173182this is new task working: 1
174183this is new task working: 2
175184this is new task working: 3
@@ -188,21 +197,28 @@ and now it is done
188197
189198## Discussion
190199
191- What would happen if we assign a value to _ x_ right before launching the new task? What would happen if we
192- assign a value to _ x_ right before launching the new task and after the _ writeln("and now it is done");_
193- statement?
194-
195- Discuss your observations.
196-
197-
198-
199- abc
200-
201-
202-
200+ What would happen if we try to read ` x ` inside the new task as well, i.e. we have the following ` begin `
201+ statement, without changing the rest of the code:
203202
203+ ``` chpl
204+ begin {
205+ for i in 1..10 do writeln("this is new task working: ",i);
206+ x.writeEF(2);
207+ writeln("New task finished");
208+ x.readFE();
209+ }
210+ ```
211+ :::::::::::::::::::::::: solution
204212
213+ The code will block (run forever), and you would need to press * Ctrl-C* to halt its execution. In this example
214+ we try to read ` x ` in two places: the main task and the new task. When we read a sync variable with ` readFE ` ,
215+ the state of the sync variable is set to empty when this method completes. In other words, one of the two
216+ ` readFE ` calls will succeed (which one -- depends on the runtime) and will mark the variable as empty. The
217+ other ` readFE ` will then attempt to read it but it will block waiting for ` x ` to become full again (which will
218+ never happen). In the end, the execution of either the main thread or the child thread will block, hanging the
219+ entire code.
205220
221+ :::::::::::::::::::::::::::::::::
206222:::::::::::::::::::::::::::::::::::::::::::::::::::
207223
208224There are a number of methods defined for _ sync_ variables. Suppose _ x_ is a sync variable of a given type,
0 commit comments