Created
August 5, 2011 13:24
-
-
Save DmitrySoshnikov/1127536 to your computer and use it in GitHub Desktop.
Simple (cooperative) processes with the Scheduler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The simplest processes (cooperative tasks) with Scheduler | |
* (sort of Erlang's processes but without messages yet) | |
* See also: http://www.dabeaz.com/coroutines/index.html | |
* | |
* Deps: JS 1.7 with generators (yield) | |
* | |
* by Dmitry Soshnikov <[email protected]> | |
* MIT Style License | |
*/ | |
var Scheduler = (function initScheduler() { | |
var | |
/** | |
* run queue; processes | |
* ready to be executed | |
*/ | |
runQueue = [], | |
/** | |
* processes map -- all | |
* currently alive processes | |
*/ | |
processes = {}, | |
/** | |
* to track count of | |
* alive processes | |
*/ | |
processesCount = 0, | |
/** | |
* Autoinc process id, which is | |
* assigned to newborn process | |
*/ | |
pid = 1; | |
return { | |
/** | |
* Currently running process, | |
* used in self() function | |
*/ | |
runningProcess: null, | |
/** | |
* Sheduling is just putting a | |
* process to the run queue; it will be | |
* executed on next iteration of the handle loop | |
*/ | |
schedule: function (process) { | |
runQueue.push(process); | |
}, | |
/** | |
* Creates new process and | |
* automatically schedules it | |
*/ | |
spawn: function (processLoop) { | |
var process = typeof processLoop == "function" ? processLoop() : processLoop; | |
process.pid = pid++; | |
processes[process.pid] = process; | |
processesCount++; | |
console.log("* Spawning new process with pid #" + process.pid); | |
this.schedule(process); | |
return process.pid; | |
}, | |
/** | |
* Terminates a process by pid | |
* or the process itself parameter | |
*/ | |
terminate: function (process) { | |
var pid = typeof process == "number" ? process : process.pid; | |
console.log("* Process #" + pid + " is terminated"); | |
delete processes[pid]; | |
processesCount--; | |
return pid; | |
}, | |
/** | |
* Main scheduling loop: simply retrive a current process | |
* from the run queue, execute it, and schedule back | |
*/ | |
handleLoop: function () { | |
console.log("* Scheduler loop started"); | |
while (processesCount) { | |
try { | |
// get the next process in the run queue | |
var process = runQueue.shift(); | |
// if there is something | |
if (process) { | |
// then run it | |
Scheduler.runningProcess = process; | |
process.next(); // execute the next "reductions" part (upto the next "yield" statement inside) | |
// and schedule back for next iteration | |
this.schedule(process); | |
} | |
} catch (e if (e instanceof StopIteration)) { | |
// if the process finishes, | |
// just remove it from the prcesses map | |
this.terminate(process); | |
} | |
} | |
console.log("* Scheduler loop stopped"); | |
} | |
}; | |
})(); | |
// creates new process | |
function spawn(process) { | |
return Scheduler.spawn(process); | |
} | |
// helper function to get | |
// the pid of currently running process | |
function self() { | |
return Scheduler.runningProcess.pid; | |
} | |
// spawn 3 processes | |
for (var k = 3; k--;) { | |
spawn(function () { | |
console.log("Process #" + self() + " first entry"); | |
yield; | |
console.log("Process #" + self() + " second entry"); | |
}); | |
} | |
// start main scheduling loop | |
Scheduler.handleLoop(); | |
// Results: | |
// * Spawning new process with pid #1 | |
// * Spawning new process with pid #2 | |
// * Spawning new process with pid #3 | |
// * Scheduler loop started | |
// Process #1 first entry | |
// Process #2 first entry | |
// Process #3 first entry | |
// Process #1 second entry | |
// * Process #1 is terminated | |
// Process #2 second entry | |
// * Process #2 is terminated | |
// Process #3 second entry | |
// * Process #3 is terminated | |
// * Scheduler loop stopped |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment