@@ -17,7 +17,6 @@ import {SYSTEM_PROCESS_STRING} from './Constants.mjs'
1717
1818import { getCliArgs , TroupeCliArg } from './TroupeCliArgs.mjs' ;
1919const argv = getCliArgs ( ) ;
20- const showStack = argv [ TroupeCliArg . ShowStack ]
2120
2221/** Enum for termination statuses. */
2322enum TerminationStatus {
@@ -247,25 +246,26 @@ export class Scheduler implements SchedulerInterface {
247246 * around 50M on the low points of the wave.
248247 */
249248 loop ( ) {
250- const $$LOOPBOUND = 500000 ;
251- let _FUNLOOP = this . __funloop
252- let _curThread : Thread ;
253- let dest ;
249+ const maxThreadsPerLoop = 500000 ;
250+ const maxKontsPerThread = 1000 ;
251+
252+ let dest : ( ) => any ;
254253 try {
255- for ( let $$loopiter = 0 ; $$loopiter < $$LOOPBOUND && _FUNLOOP . length > 0 ; $$loopiter ++ ) {
256- _curThread = _FUNLOOP . shift ( ) ;
257- this . __currentThread = _curThread ;
258- dest = _curThread . next ;
259- let ttl = 1000 ; // magic constant; 2021-04-29
260- while ( dest && ttl -- ) {
254+ for ( let i = 0 ; i < maxThreadsPerLoop && this . __funloop . length > 0 ; ++ i ) {
255+ // Pop front of function queue and set it to be the next thread.
256+ this . __currentThread = this . __funloop . shift ( ) ;
257+ dest = this . __currentThread . next ;
258+
259+ // Run thread for `maxKontsPerThread` continuations.
260+ for ( let j = 0 ; dest && j < maxKontsPerThread ; ++ j ) {
261261 dest = dest ( ) ;
262262 }
263263
264+ // If not done, push it back into the queue.
264265 if ( dest ) {
265- _curThread . handlerState . checkGuard ( ) ;
266-
267- _curThread . next = dest ;
268- _FUNLOOP . push ( _curThread ) ;
266+ this . __currentThread . handlerState . checkGuard ( ) ;
267+ this . __currentThread . next = dest ;
268+ this . __funloop . push ( this . __currentThread ) ;
269269 }
270270 }
271271 } catch ( e ) {
@@ -276,18 +276,20 @@ export class Scheduler implements SchedulerInterface {
276276 console . log ( "--- The following output may help identify a bug in the runtime ---" ) ;
277277 console . log ( "Destination function\n" , dest ) ;
278278
279- if ( showStack ) {
279+ if ( argv [ TroupeCliArg . ShowStack ] ) {
280280 this . __currentThread . showStack ( ) ;
281281 }
282282 throw e ;
283283 }
284284 }
285285
286- if ( _FUNLOOP . length > 0 ) {
287- // we are not really done, but are just hacking around the V8's memory management
286+ // If more work is to be done, then resume `loop` after the Javascript runtime has been able
287+ // to run other tasks, e.g. garbage collection.
288+ if ( this . __funloop . length > 0 ) {
288289 this . resumeLoopAsync ( ) ;
289290 }
290291
292+ // If everything is done, and the node should not persist, then terminate.
291293 if ( this . __stopWhenAllThreadsAreDone && Object . keys ( this . __alive ) . length == 0 ) {
292294 this . __stopRuntime ( ) ;
293295 }
0 commit comments