diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-08-27 20:49:03 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-08-27 20:49:03 -0700 |
commit | cd9bb850caeca88747a25436fc65c67c6d5cd89a (patch) | |
tree | 34ea30beb19b5fafe855b951b9468d2a9e915492 /html/073wait.cc.html | |
parent | e947da75bd926da6d533fd73b352c16c8417b3f6 (diff) | |
download | mu-cd9bb850caeca88747a25436fc65c67c6d5cd89a.tar.gz |
3266
Diffstat (limited to 'html/073wait.cc.html')
-rw-r--r-- | html/073wait.cc.html | 144 |
1 files changed, 125 insertions, 19 deletions
diff --git a/html/073wait.cc.html b/html/073wait.cc.html index 49bdd7d3..847eafa3 100644 --- a/html/073wait.cc.html +++ b/html/073wait.cc.html @@ -21,6 +21,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color .Special { color: #c00000; } .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -68,6 +69,11 @@ waiting_on_location = old_value_of_waiting_location = <span class="Constant">0</ Passed = <span class="Constant">false</span><span class="Delimiter">;</span> raise << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": deadlock!</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(before "End Run Routine")</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>any_routines_waiting<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"deadlock!</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + dump_waiting_routines<span class="Delimiter">();</span> +<span class="Delimiter">}</span> <span class="Delimiter">:(before "End Test Teardown")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Passed && any_routines_with_error<span class="Delimiter">())</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> @@ -81,6 +87,12 @@ waiting_on_location = old_value_of_waiting_location = <span class="Constant">0</ <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Normal">void</span> dump_waiting_routines<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == WAITING<span class="Delimiter">)</span> + cerr << i << <span class="Constant">": "</span> << routine_label<span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> <span class="Comment">//: primitive recipe to put routines in that state</span> @@ -258,26 +270,112 @@ def main [ ] <span class="traceContains">+mem: storing 11 in location 21</span> -<span class="Comment">//: also allow waiting on a routine to stop running</span> +<span class="Comment">//: also allow waiting on a routine to block</span> +<span class="Comment">//: (just for tests; use wait_for_routine below wherever possible)</span> + +<span class="Delimiter">:(scenario wait_for_routine_to_block)</span> +def f1 [ + <span class="Constant">1</span>:number/routine<span class="Special"> <- </span>start-running f2 + wait-<span class="Normal">for</span>-routine-to-block <span class="Constant">1</span>:number/routine + <span class="Comment"># now wait for f2 to run and modify location 10 before using its value</span> + <span class="Constant">11</span>:number<span class="Special"> <- </span>copy <span class="Constant">10</span>:number +] +def f2 [ + <span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> +] +<span class="traceContains">+schedule: f1</span> +<span class="traceContains">+run: waiting for routine 2 to block</span> +<span class="traceContains">+schedule: f2</span> +<span class="traceContains">+schedule: waking up blocked routine 1</span> +<span class="traceContains">+schedule: f1</span> +<span class="Comment"># if we got the synchronization wrong we'd be storing 0 in location 11</span> +<span class="traceContains">+mem: storing 34 in location 11</span> + +<span class="Delimiter">:(before "End routine Fields")</span> +<span class="Comment">// only if state == WAITING</span> +<span class="Normal">int</span> waiting_on_routine_to_block<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End routine Constructor")</span> +waiting_on_routine_to_block = <span class="Constant">0</span><span class="Delimiter">;</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +WAIT_FOR_ROUTINE_TO_BLOCK<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"wait-for-routine-to-block"</span><span class="Delimiter">,</span> WAIT_FOR_ROUTINE_TO_BLOCK<span class="Delimiter">);</span> +<span class="Delimiter">:(before "End Primitive Recipe Checks")</span> +<span class="Normal">case</span> WAIT_FOR_ROUTINE_TO_BLOCK: <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'wait-for-routine-to-block' requires exactly one ingredient, but got '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'wait-for-routine-to-block' should be a routine id generated by 'start-running', but got '"</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +<span class="Normal">case</span> WAIT_FOR_ROUTINE_TO_BLOCK: <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"routine can't wait for itself! '"</span> << to_original_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">())</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span> + Current_routine<span class="Delimiter">-></span>waiting_on_routine_to_block = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for routine "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << <span class="Constant">" to block"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << Current_routine->id << ": waiting for routine " << ingredients.at(0).at(0) << " to block\n";</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Scheduler State Transitions")</span> +<span class="Comment">// Wake up any routines waiting for other routines to stop running.</span> +<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + routine* waiter = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!waiter<span class="Delimiter">-></span>waiting_on_routine_to_block<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + <span class="Normal">int</span> id = waiter<span class="Delimiter">-></span>waiting_on_routine_to_block<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>id != waiter<span class="Delimiter">-></span>id<span class="Delimiter">);</span> <span class="Comment">// routine can't wait on itself</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> routine* waitee = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>waitee<span class="Delimiter">-></span>id == id && waitee<span class="Delimiter">-></span>state != RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// routine is WAITING or COMPLETED or DISCONTINUED</span> + trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up blocked routine "</span> << waiter<span class="Delimiter">-></span>id << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << id << " is now unblocked (" << waitee->state << "); waking up waiting routine " << waiter->id << '\n';</span> + waiter<span class="Delimiter">-></span>state = RUNNING<span class="Delimiter">;</span> + waiter<span class="Delimiter">-></span>waiting_on_routine_to_block = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Comment">//: allow waiting on a routine to complete</span> <span class="Delimiter">:(scenario wait_for_routine)</span> def f1 [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Constant">12</span>:number/routine<span class="Special"> <- </span>start-running f2 - wait-<span class="Normal">for</span>-routine <span class="Constant">12</span>:number/routine - <span class="Comment"># now wait for f2 to run and modify location 1 before using its value</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number + <span class="Comment"># add a few routines to run</span> + <span class="Constant">1</span>:number/routine<span class="Special"> <- </span>start-running f2 + <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running f3 + wait-<span class="Normal">for</span>-routine <span class="Constant">1</span>:number/routine + <span class="Comment"># now wait for f2 to *complete* and modify location 13 before using its value</span> + <span class="Constant">20</span>:number<span class="Special"> <- </span>copy <span class="Constant">13</span>:number ] def f2 [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> + <span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># just padding</span> + <span class="Normal">switch</span> <span class="Comment"># simulate a block; routine f1 shouldn't restart at this point</span> + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> +] +def f3 [ + <span class="Comment"># padding routine just to help simulate the block in f2 using 'switch'</span> + <span class="Constant">11</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> ] <span class="traceContains">+schedule: f1</span> <span class="traceContains">+run: waiting for routine 2</span> <span class="traceContains">+schedule: f2</span> +<span class="traceContains">+schedule: f3</span> +<span class="traceContains">+schedule: f2</span> <span class="traceContains">+schedule: waking up routine 1</span> <span class="traceContains">+schedule: f1</span> -<span class="Comment"># if we got the synchronization wrong we'd be storing 0 in location 3</span> -<span class="traceContains">+mem: storing 34 in location 3</span> +<span class="Comment"># if we got the synchronization wrong we'd be storing 0 in location 20</span> +<span class="traceContains">+mem: storing 34 in location 20</span> <span class="Delimiter">:(before "End routine Fields")</span> <span class="Comment">// only if state == WAITING</span> @@ -310,27 +408,34 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>waiting_on_routine = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for routine "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << Current_routine->id << ": waiting for routine " << ingredients.at(0).at(0) << '\n';</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Scheduler State Transitions")</span> -<span class="Comment">// Wake up any routines waiting for other routines to go to sleep.</span> +<span class="Comment">// Wake up any routines waiting for other routines to complete.</span> <span class="Comment">// Important: this must come after the scheduler loop above giving routines</span> <span class="Comment">// waiting for locations to change a chance to wake up.</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">int</span> id = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<span class="Delimiter">;</span> - assert<span class="Delimiter">(</span>id != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id<span class="Delimiter">);</span> <span class="Comment">// routine can't wait on itself</span> + routine* waiter = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!waiter<span class="Delimiter">-></span>waiting_on_routine<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + <span class="Normal">int</span> id = waiter<span class="Delimiter">-></span>waiting_on_routine<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>id != waiter<span class="Delimiter">-></span>id<span class="Delimiter">);</span> <span class="Comment">// routine can't wait on itself</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>id == id && Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state != RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> - trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine "</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id << end<span class="Delimiter">();</span> - Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span> - Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">const</span> routine* waitee = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>waitee<span class="Delimiter">-></span>id == id && waitee<span class="Delimiter">-></span>state != RUNNING && waitee<span class="Delimiter">-></span>state != WAITING<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// routine is COMPLETED or DISCONTINUED</span> + trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine "</span> << waiter<span class="Delimiter">-></span>id << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << id << " is now done (" << waitee->state << "); waking up waiting routine " << waiter->id << '\n';</span> + waiter<span class="Delimiter">-></span>state = RUNNING<span class="Delimiter">;</span> + waiter<span class="Delimiter">-></span>waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> +<span class="Comment">//: yield voluntarily to let some other routine run</span> + <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> SWITCH<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> @@ -339,17 +444,18 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">case</span> SWITCH: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">//: pick another RUNNING routine at random and wait for it to get a chance</span> +<span class="Comment">//: there might be a better implementation than this</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> SWITCH: <span class="Delimiter">{</span> <span class="Normal">int</span> id = some_other_running_routine<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>id != Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">);</span> Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span> - Current_routine<span class="Delimiter">-></span>waiting_on_routine = id<span class="Delimiter">;</span> + Current_routine<span class="Delimiter">-></span>waiting_on_routine_to_block = id<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Delimiter">:(code)</span> <span class="Normal">int</span> some_other_running_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> |