-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtmp.html
592 lines (561 loc) · 25.9 KB
/
tmp.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
<html><head>
<style type="text/css">
body {margin:3%; }
h1 {color:gray; font-size:120%;}
h2 {color:gray; font-size:105%;}
h3 {font-size:100%;}
h4 {font-size:95%;}
h5 {font-size:95%;}
span.fstring {color:darkblue; font-style:italic; }
span.comment {font-family:arial; color:blue; font-style:italic; }
span.doccomment {font-family:arial; color:green; font-style:italic; }
span.big_keyword {color:#FF1010; }
span.small_keyword {color:#802040; }
span.qualifier {color:#A02020; }
span.library {color:#A02000; }
span.ctor {color:#406020; }
span.hack {color:#66DD00; }
span.preproc {color:#005500; }
span.embedded_c{background-color:#DDDDDD; }
span.fpc_fieldname {color:#DD0000; }
span.lineno {color:#101010; background-color:#E0E0E0; font-size:80%; font-family:"courier",monospace; font-style:normal; }
pre.flxbg {background-color:#A0FFA0; color:black; padding:2px; box-shadow:5px 5px 2px #807080; }
pre.uncheckedflxbg {background-color:#D0D0D0; color:black; padding:2px; box-shadow:5px 5px 2px #807080; }
pre.cppbg {background-color:#80FF80; color:black; }
pre.prefmtbg {background-color:#D0D0D0; color:black; }
pre.expected {background-color:#E0FF80; color:black; }
pre.input {background-color:#E08080; color:black; }
pre.inclusion {background-color:#D070D0; color:black; }
code.inclusion {background-color:#D070D0; color:black; }
.obsolete { background-color:#FFEFEF; font-size: small; color:black; }
.future { background-color:#FF8080; font-size: small; color:black; }
.implementation_detail { background-color:#E0E0E0; font-size: small; color:black; }
.bug { background-color:#FFE0E0; font-size: small; color:black; }
.fixed{ background-color:#FFE0E0; font-size: small; color:black; }
.done { background-color:#FFE0E0; font-size: small; color:black; }
.caveat { background-color:#FF8080; color:black; }
</style>
<title>coroutines</title></head><body>
<style>
body {margin:3%; font-family: sans-serif; }
h1 {color:black; font-size:120%; border-bottom: 2px solid #ddd; padding: 0 0 3px 0;}
h2 {color:#202020; font-size:105%;}
h3 {font-size:100%;}
h4 {font-size:95%;}
h5 {font-size:95%;}
span.fstring {color:darkblue; font-style:italic; }
span.comment {font-family:arial; color:blue; font-style:italic; }
span.doccomment {font-family:arial; color:green; font-style:italic; }
span.big_keyword {color:#FF1010; }
span.small_keyword {color:#802040; }
span.qualifier {color:#A02020; }
span.library {color:#A02000; }
span.ctor {color:#406020; }
span.hack {color:#66DD00; }
span.preproc {color:#005500; }
span.embedded_c{background-color:#DDDDDD; }
span.fpc_fieldname {color:#DD0000; }
span.lineno {color:#101010; background-color:#E0E0E0; font-size:80%; font-family:"courier",monospace; font-style:normal; }
pre { border: 1px solid #ccc; color: black; box-shadow:3px 3px 2px rgba(0,0,0,0.1); padding:2px; }
pre.flxbg {background-color:#C2FDC2; box-shadow:3px 3px 2px rgba(0,0,0,0.1) }
pre.uncheckedflxbg {background-color:#eee; box-shadow:3px 3px 2px rgba(0,0,0,0.1); }
pre.cppbg {background-color:#C2FDC2; }
pre.prefmtbg {background-color:#F1F1F1; }
pre.expected {background-color:hsla(74,94%,88%,1); }
pre.input {background-color:hsla(20,94%,88%,1); }
pre.inclusion {
font-family: Arial;
font-weight: normal;
font-size: 0.9em;
color: #555;
border: none;
box-shadow: none;
text-align: right;
margin: -7px 11px -12px 0;
padding: 0;
background-color:#fafafa;
}
code.inclusion {background-color:#D070D0; color:black; }
.obsolete { background-color:#FFEFEF; font-size: small; color:black; }
.future { background-color:#FF8080; font-size: small; color:black; }
.implementation_detail { background-color:#E0E0E0; font-size: small; color:black; }
.bug { background-color:#FFE0E0; font-size: small; color:black; }
.fixed{ background-color:#FFE0E0; font-size: small; color:black; }
.done { background-color:#FFE0E0; font-size: small; color:black; }
.caveat { background-color:hsla(0,100%,91%,1); color:black; padding: 0.6em; }
.container {
position: fixed;
top:0px;
left:0px;
height : 100%;
width: 100%;
background-color: grey;
margin: 0px;
padding: 0px;
border-width: 0px;
color: #404040;
}
.maincontent {
padding:4px;
padding-left:8px;
line-height:1.3em;
color:#404040; background-color:#fafafa;
}
.maincontent h1 { margin-left:-8px; position: relative; font-family: georgia, serif; font-size: 1.8em; font-weight: normal; }
.maincontent h2 { margin-left:-8px; position: relative; margin-bottom:-5px; }
.maincontent h3 { margin-left:-8px; position: relative; margin-bottom:-5px; }
.maincontent h4 { margin-left:-8px; position: relative; margin-bottom:-5px; }
.maincontent code { color:#902030; }
.toppanel {
position:absolute; left:0px; top:0px; height:20px; right:0px;
background-color: #e0e0e0;
}
.bottompanel {
position:absolute; left:0px; top:22px; bottom:0px; right:0px;
background-color: #fafafa;
font-size:14px;
}
.leftpanel {
position:absolute; left:0px; top:0px; bottom:0px; width: 150px;
background-color: #eaeaea; overflow: auto;
}
.rightpanel {
position:absolute; right: 0px; left:160px; top:0px; bottom: 0px;
background-color: #fafafa; overflow: auto;
}
.divider {
position:absolute; left: 150px; top:0px; bottom:0px;
background-color: black; width:2px;
box-shadow: 0 0 8px #000;
}
#panemover {
position:absolute;
left: 150px;
width : 10px;
top: 0px;
bottom: 0px;
opacity: 0.3;
cursor:col-resize;
}
div.m {
margin: 0px;
padding:0px;
border-width:2px;
border-color: green;
}
div.m1 {
background-color: #86E870;
border-style:outset;
border-color:#ccc;
border-width:2px 0;
font-size:90%;
padding: 1px 0 2px 10px;
}
div.m2 {
background-color: #70C070;
padding-left:15px;
padding-top:2px;
border-style:outset;
border-color:green;
border-width:0 0 1px 0;
font-size:80%;
}
div.m1:hover, div.m2:hover {
background-color: white;
}
#leftmargintoc a {
text-decoration: none;
color: #404040;
}
</style>
<style>
div.m {
margin: 0px;
padding:0px;
border-width:2px;
border-color: green;
}
div.m1 {
background-color: #86E870;
border-style:outset;
border-color:#ccc;
border-width:2px 0;
font-size:90%;
padding: 1px 0 2px 10px;
}
div.m2 {
background-color: #70C070;
padding-left:15px;
padding-top:2px;
border-style:outset;
border-color:green;
border-width:0 0 1px 0;
font-size:80%;
}
div.m1:hover, div.m2:hover {
background-color: white;
}
#leftmargintoc a {
text-decoration: none;
color: #404040;
}
</style>
<script async="true">
function dragStart(e, left, right){
document.getElementById("panemover").style.width="70%";
document.getElementById("panemover").style.left="50px";
mousedown = true;
x = e.clientX
dragOffsetLeft =
document.getElementById(left).getBoundingClientRect().right -
document.getElementById(left).getBoundingClientRect().left -
x
;
dragOffsetDivider= document.getElementById("divider").getBoundingClientRect().left - x;
dragOffsetRight = document.getElementById(right).getBoundingClientRect().left - x;
}
function dragRelease(){
document.getElementById('panemover').style.width = '10px';
document.getElementById('panemover').style.left = document.getElementById('divider').offsetLeft + 'px';
mousedown = false;
}
function drag(e, left, right){
if(!mousedown){return}
x = e.clientX
tmpLeft = dragOffsetLeft + x
tmpDivider= dragOffsetDivider + x
tmpRight = dragOffsetRight + x
document.getElementById(left).style.width= tmpLeft + 'px';
document.getElementById("divider").style.left= tmpDivider + 'px';
document.getElementById(right).style.left = tmpRight + 'px';
};
</script>
<script type="text/javascript">
function mexpand(id)
{
var n = document.getElementById(id).style;
n.display = "block";
}
function mcollapse(id)
{
var n = document.getElementById(id).style;
n.display = "none";
}
var counter_max = 0;
function mshow(id,loc)
{
var i;
for(i=1; i<=counter_max; ++i)
mcollapse("menu"+String(i));
mexpand(id);
window.location.replace(loc);
}
</script>
<script type="text/javascript">
function expand(but,id)
{
var n = document.getElementById(id).style;
var button = document.getElementById(but);
button.src = "/share/src/web/images/minus.gif";
button.alt = "-";
n.display = "block";
}
function collapse(but,id)
{
var n = document.getElementById(id).style;
var button = document.getElementById(but);
button.src = "/share/src/web/images/plus.gif";
button.alt = "+";
n.display = "none";
}
function toggle(button,id)
{
var n = document.getElementById(id).style;
if (n.display == "none")
{
button.src = "/share/src/web/images/minus.gif";
button.alt = "-";
n.display = "block";
}
else
{
button.src = "/share/src/web/images/plus.gif";
button.alt = "+";
n.display = "none";
}
}
var allbuttons = [
"A low level example.",
"The concept of fibration",
"next",
"high",
"med1",
"med2",
"med3",
"low"
];
function expand_all(dummy)
{
for (i in allbuttons)
{
expand(allbuttons[i], allbuttons[i]+"_d");
}
}
function collapse_all(dummy)
{
for (i in allbuttons)
{
collapse(allbuttons[i], allbuttons[i]+"_d");
}
}
</script>
<script>
function mouseover(id)
{
var elt = document.getElementById(id);
elt.style.display="none";
var elt2 = document.getElementById(id+"_mo");
elt2.style.display="inline";
}
function mouseout(id)
{
var elt = document.getElementById(id+"_mo");
elt.style.display="none";
var elt2 = document.getElementById(id);
elt2.style.display="inline";
}
</script>
<script> function nop(dummy) {} </script>
<div class="container">
<div class="toppanel">
<!--Main Content top navbar-->
<span style="position:relative; bottom:6px"
onmouseover="mouseover('expand')"
onmouseout="mouseout('expand')"
onclick="expand_all('expand')"
><span id="expand"><svg height="30px" width="65px"><rect x="4px" y="6px" rx="4px" ry="40px" width="60px" height="20px" style="fill:blue;opacity:0.2;stroke:black;stroke-width:2"/><text x="13px" y="21px" fill="black" style="font-size:12px;">Expand</text></svg></span><span id="expand_mo" style="display:none"><svg height="30px" width="65px"><rect x="4px" y="6px" rx="4px" ry="40px" width="60px" height="20px" style="fill:red;opacity:0.2;stroke:black;stroke-width:2"/><text x="13px" y="21px" fill="black" style="font-size:12px;">Expand</text></svg></span></span><span style="position:relative; bottom:6px"
onmouseover="mouseover('collapse')"
onmouseout="mouseout('collapse')"
onclick="collapse_all('collapse')"
><span id="collapse"><svg height="30px" width="65px"><rect x="4px" y="6px" rx="4px" ry="40px" width="60px" height="20px" style="fill:blue;opacity:0.2;stroke:black;stroke-width:2"/><text x="13px" y="21px" fill="black" style="font-size:12px;">Collapse</text></svg></span><span id="collapse_mo" style="display:none"><svg height="30px" width="65px"><rect x="4px" y="6px" rx="4px" ry="40px" width="60px" height="20px" style="fill:red;opacity:0.2;stroke:black;stroke-width:2"/><text x="13px" y="21px" fill="black" style="font-size:12px;">Collapse</text></svg></span></span> <!--Main Content top navbar End-->
</div> <!-- toppanel end -->
<div class="bottompanel">
<span id="divider" class="divider"></span>
<span id="left" class="leftpanel" >
<div class="menucontent">
<!--Left Margin Toc-->
<div id="leftmargintoc">
<!--Left Margin Toc Main Contents-->
<div class=m1 onclick="mshow('menu1','#A low level example._h')"> <a href="#A_low_level_example._h">A low level example.</a></div>
<div class=sm id=menu1>
</div>
<div class=m1 onclick="mshow('menu2','#The concept of fibration_h')"> <a href="#The_concept_of_fibration_h">The concept of fibration</a></div>
<div class=sm id=menu2>
<div class=m2><a href="#next_h">next</a></div>
</div>
<div class=m1 onclick="mshow('menu3','#high_h')"> <a href="#high_h">high</a></div>
<div class=sm id=menu3>
<div class=m2><a href="#med1_h">med1</a></div>
<div class=m2><a href="#med2_h">med2</a></div>
<div class=m2><a href="#med3_h">med3</a></div>
</div>
<script>counter_max=3;</script>
</div>
<!--End Left Margin Toc-->
</div> <!-- leftpanel contents end -->
</span> <!-- leftpanel end -->
<span id="right" class="rightpanel">
<div class="maincontent">
<!--Main Content Body-->
<h1 id='A_low_level_example._h'><img src='/share/src/web/images/minus.gif' id='A low level example.' onclick='toggle(this,"A_low_level_example._d")' alt='+'/> 1 A low level example.</h1><div id='A_low_level_example._d' style='display:block'>
<p>I will show a simple low level example of coroutines, it will be a
simple pipeline consisting of a source, a transducer, a limiter, and a sink.
</p><p>First we have our source, which just write all the integers starting from 0
down the channel <code>inp</code>. The type <code>%>int</code> is an output channel endpoint
for <code>int</code>.
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a procedure, a function with side-effects not returning a value">proc</span> source (out: %><span class="library" title="binding of C int type">int</span>) () {
<span class="lineno" id=line2></span> <span class="big_keyword" title="Define a mutable variable">var</span> i = 0;
<span class="lineno" id=line3></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span>
<span class="lineno" id=line4></span> <span class="library" title="Print a string to a stream">write</span> (out,i);
<span class="lineno" id=line5></span> ++i;
<span class="lineno" id=line6></span> <span class="small_keyword" title="end of body">done</span>
<span class="lineno" id=line7></span> }
</pre></p><p>Now we have a simple sink, which just prints everything it reads:
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a procedure, a function with side-effects not returning a value">proc</span> sink (inp: %<<span class="library" title="binding of C int type">int</span>) () {
<span class="lineno" id=line2></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span>
<span class="lineno" id=line3></span> <span class="big_keyword" title="Define a mutable variable">var</span> i = read inp;
<span class="lineno" id=line4></span> <span class="library" title="Print a string to standard output with newline appended">println</span>$ i;
<span class="lineno" id=line5></span> <span class="small_keyword" title="end of body">done</span>
<span class="lineno" id=line6></span> }
</pre></p><p>You should note the extra unit parameter <code>()</code>. After the input is bound, the resulting
procedure will have type
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="library" title="Type with one values (), the empty tuple">unit</span> -> <span class="library" title="Type with one values (), the empty tuple">unit</span>
</pre></p><p>which is the type required to spawn fibre from a coroutine.
</p><p>Now we have a transducer which writes the square of every integer it reads.
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a procedure, a function with side-effects not returning a value">proc</span> squarer (inp: %<<span class="library" title="binding of C int type">int</span>, out: %><span class="library" title="binding of C int type">int</span>) () {
<span class="lineno" id=line2></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span>
<span class="lineno" id=line3></span> <span class="big_keyword" title="Define a mutable variable">var</span> i = read inp;
<span class="lineno" id=line4></span> <span class="library" title="Print a string to a stream">write</span> (out, i * i);
<span class="lineno" id=line5></span> <span class="small_keyword" title="end of body">done</span>
<span class="lineno" id=line6></span> }
</pre></p><p>You should notice the previous three components were all infinite loops.
Since we don't want our demo to run forever we will throw in a limiter chip:
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a procedure, a function with side-effects not returning a value">proc</span> limiter (<span class="big_keyword" title="Define a mutable variable">var</span> limit: <span class="library" title="binding of C int type">int</span>) (inp: %<<span class="library" title="binding of C int type">int</span>, out: %><span class="library" title="binding of C int type">int</span>) () {
<span class="lineno" id=line2></span> <span class="small_keyword" title="while loop">while</span> limit > 0 <span class="small_keyword" title="imperative code begins">do</span>
<span class="lineno" id=line3></span> <span class="big_keyword" title="Define a mutable variable">var</span> i = read inp;
<span class="lineno" id=line4></span> <span class="library" title="Print a string to a stream">write</span> (out, i);
<span class="lineno" id=line5></span> --limit;
<span class="lineno" id=line6></span> <span class="small_keyword" title="end of body">done</span>
<span class="lineno" id=line7></span> };
</pre></p><p>This procedure drops through, but it cannot return control, because
there is nowhere to return it to, so it has, in effect, committed
suicide implicitly.
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> Now we need have four components so we need three channels <span class="small_keyword" title="substring range separator">to</span> connect them:
<span class="lineno" id=line2></span> <span class="big_keyword" title="Define a procedure, a function with side-effects not returning a value">proc</span> run_pipeline() {
<span class="lineno" id=line3></span> <span class="comment">// make channels</span>
<span class="lineno" id=line4></span> <span class="big_keyword" title="Define a mutable variable">var</span> i1,o1 = mk_ioschannel_pair[<span class="library" title="binding of C int type">int</span>]();
<span class="lineno" id=line5></span> <span class="big_keyword" title="Define a mutable variable">var</span> i2,o2 = mk_ioschannel_pair[<span class="library" title="binding of C int type">int</span>]();
<span class="lineno" id=line6></span> <span class="big_keyword" title="Define a mutable variable">var</span> i3,o3 = mk_ioschannel_pair[<span class="library" title="binding of C int type">int</span>]();
<span class="lineno" id=line7></span>
<span class="lineno" id=line8></span> <span class="comment">// make coroutines by binding the channels</span>
<span class="lineno" id=line9></span> <span class="big_keyword" title="Define a mutable variable">var</span> d1 = source(o1);
<span class="lineno" id=line10></span> <span class="big_keyword" title="Define a mutable variable">var</span> d2 = squarer(i1,o2);
<span class="lineno" id=line11></span> <span class="big_keyword" title="Define a mutable variable">var</span> d3 = limiter 8 (i2,o3);
<span class="lineno" id=line12></span> <span class="big_keyword" title="Define a mutable variable">var</span> d4 = sink (i3);
<span class="lineno" id=line13></span>
<span class="lineno" id=line14></span> <span class="comment">// spawn coroutines as fibres</span>
<span class="lineno" id=line15></span> <span class="big_keyword" title="Spawn a cooperative fibre">spawn_fthread</span> d1;
<span class="lineno" id=line16></span> <span class="big_keyword" title="Spawn a cooperative fibre">spawn_fthread</span> d2;
<span class="lineno" id=line17></span> <span class="big_keyword" title="Spawn a cooperative fibre">spawn_fthread</span> d3;
<span class="lineno" id=line18></span> <span class="big_keyword" title="Spawn a cooperative fibre">spawn_fthread</span> d4;
<span class="lineno" id=line19></span>
<span class="lineno" id=line20></span> <span class="comment">// exit</span>
<span class="lineno" id=line21></span> }
</pre></p></div><h1 id='The_concept_of_fibration_h'><img src='/share/src/web/images/minus.gif' id='The concept of fibration' onclick='toggle(this,"The_concept_of_fibration_d")' alt='+'/> 2 The concept of fibration</h1><div id='The_concept_of_fibration_d' style='display:block'>
<p>A <em>coroutine system</em> is a collection of processes called <em>fibres</em>
with these properties:
<ul>
<li>Exactly one process can be <em>running</em> at once, the others are said to be <em>suspended</em></li>
<li>Control cannot be pre-empted, but is yielded voluntarily</li>
</ul>
In our system, there are four principle operations which yield control:
<ol>
<li><em>spawn</em> a new fibre</li>
<li><em>read</em> from a channel</li>
<li><em>write</em> to a channel</li>
<li>Commit <em>suicide</em>
</ol>
A fibre of control can be in one of five states:
<ol>
<li>Running</em>
<li>Active (but not running)</li>
<li>Waiting on read</li>
<li>Waiting on write</ii>
<li>Dead</li>
</ol>
In our system, all the resources associated by an <em>unreachable</em> dead
fibre are automatically reaped by the garbage collector so that in fact
the fibre is not technically dead because it no longer exists.
</p><p>A <em>channel</em> is an object associated with which
set of fibres all waiting to read or all waiting to write.
</p><p>When a write operation is performed on a channel by the running fibre,
if there are fibres on the channel which are waiting to read
then one is selected, the data to be written is tranfered from the writer to the reader,
the fibre is removed from association with the channel,
and both the running and reader fibre are made active.
Otherwise if there is no readers waiting on the channel, the writer is
suspended and put on the channel.
</p><p>When a read operation is performed on a channel by the running fibre,
if there are fibres on the channel which are waiting to write
then one is selected, the data to be written is transfered from the writer to the reader,
fibre, the fibre is removed from association with the channel,
and both the running and reader fibre are made active.
Otherwise if there is no writers waiting on the channel, the writer is
suspended and put on the channel.
</p><p>When a fibre commits suicide, it is removed as the running fibre.
</p><p>When a new fibre is spawned, both the spawner and spawnee are made active.
</p><p>When there is no running fibre, then if an active fibre exists,
an active fibre is selected and promoted to running state
and the thread of control begins executing it.
</p><p>When there is no running fibre, and no active fibres,
the whole system terminates. Any fibres waiting on I/O become dead
</p><p>The description above is a complete account of the abstract semantics
known as <em>Communicating Sequential Coroutines</em> or CSC, it is a
sub system obtain from Tony Hoare's <em>Communicating Sequenmtial Processes</em>
or CSP, in which concurrency is replaced by an indeterminate total ordering.
</p><p>To be precise in CSC all events are totally ordered, however the exact ordering
is not determinate. This is because a scheduler running the system is free
to pick any active fibre to run when one is needed.
</p><p>In the Felix implementation, a spawned fibre runs immediately
if the <code>spawn_fthread</code> procedure is used to launch it, or the
running fibre continues instead, of <code>schedule_fthread</code> is used instead.
</p><p>In addition, I/O transfers always result in the reader proceeding,
to give it a chance to actually fetch the data before the write
might modify it.
</p><h2 id='next_h'><img src='/share/src/web/images/minus.gif' id='next' onclick='toggle(this,"next_d")' alt='+'/> 2.1 next</h2><div id='next_d' style='display:block'>
<p>stuff
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> blah
</pre></p><p>stuff
</p></div></div><h1 id='high_h'><img src='/share/src/web/images/minus.gif' id='high' onclick='toggle(this,"high_d")' alt='+'/> 3 high</h1><div id='high_d' style='display:block'>
<p>blam
</p><h2 id='med1_h'><img src='/share/src/web/images/minus.gif' id='med1' onclick='toggle(this,"med1_d")' alt='+'/> 3.1 med1</h2><div id='med1_d' style='display:block'>
<p>stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
stuff
</p></div><h2 id='med2_h'><img src='/share/src/web/images/minus.gif' id='med2' onclick='toggle(this,"med2_d")' alt='+'/> 3.2 med2</h2><div id='med2_d' style='display:block'>
<p>stuff
</p></div><h2 id='med3_h'><img src='/share/src/web/images/minus.gif' id='med3' onclick='toggle(this,"med3_d")' alt='+'/> 3.3 med3</h2><div id='med3_d' style='display:block'>
<p>stuff <em>inline html works</em>
but we have <code>micros</code> for inline code as well.
<a href= https://www.itkservices2.com/nem_review_1.2>See ITK stuff</a>
</p><h3 id='low_h'><img src='/share/src/web/images/minus.gif' id='low' onclick='toggle(this,"low_d")' alt='+'/> 3.3.1 low</h3><div id='low_d' style='display:block'>
<p>level 3 stuff
</p><p><pre class='flxbg'><span class="lineno" id=line1></span> blah
</pre></p><p>stuff
</p></div></div></div><!--Main Content Body End-->
</div> <!-- rightpanel contents end -->
<hr>
</span> <!-- rightpanel end -->
<span id="panemover" style="cursor:col-resize;"
onmousedown="dragStart(event, 'left', 'right'); return false;"
onmousemove="drag(event, 'left', 'right');"
onmouseout="dragRelease();"
onmouseup="dragRelease();"
>
</span> <!-- panemover end -->
</div> <!-- bottom panel end -->
</div> <!-- container end -->
</body></html>