Skip to content

Instantly share code, notes, and snippets.

@kixxauth
Created March 30, 2010 18:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kixxauth/349379 to your computer and use it in GitHub Desktop.
Save kixxauth/349379 to your computer and use it in GitHub Desktop.
/**
* A simple parallel program in JavaScript for the Rhino JavaScript engine.
*/
// Set up the globals.
//
// While JavaScript allows all values and references in the global scope to be
// dynamic, only objects (JavaScript arrays and object natives) are mutable "in
// place". It is up to the programmer to keep the global namespace clear in a
// multithreaded environment. Because this is a simple program, I didn't do
// that at all.
// In case we're running in a CommonJS complient environment we attempt to
// import the `system` module. If not, we still need the `arguments` global
// given to us by Rhino to get the command line arguments.
var sys = typeof require === "function" ? require("system") : {args: arguments},
// Performance mode; a boolean flag.
// If true it silences the output (no print statements).
PERF,
// The number of random numbers for the main thread to generate.
RND_NUMS,
// The number of threads to run.
NUM_THREADS,
// An indexed list of observer functions (1 for each thread).
// This is the only globally shared, mutable data structure.
observers = [],
// The start time (UTC timestamp to millisecond resolution.
start;
// Create a function that will become the last thread.
// Param n is the thread id number.
function last_thread(n) {
return function () {
// The number of messages this thread has recieved.
count = 0;
// Register the observer for this thread.
observers[n] = function (x) {
var fin = x + n; // Add the passed number to the thread id number,
count += 1; // Advance the count.
if (!PERF) {
// If we're not running in perfomance mode, print the result.
print(" + "+ NUM_THREADS +" = "+ fin);
}
if (count === RND_NUMS) {
// If this is the last generated number,
// print out perfomance results.
print(" ### performance: "+ ((new Date().getTime()) - start) +" ms");
}
};
};
}
// Create a function to spawn a generic thread.
// Param n is the thread id number.
function generic_thread(n) {
return function () {
// Register the observer for this thread.
observers[n] = function (x) {
// Add the passed number to the thread id number,
// and broadcast it to the sibling thread.
observers[n +1](x + n);
};
}
}
// Create a function for spawning a new thread.
function make_thread(n) {
return n === NUM_THREADS ? last_thread : generic_thread;
}
function main() {
var n, i, y;
// The first cl arg should be the number of threads to run.
// If not given, the default is 1.
NUM_THREADS = sys.args[1] !== undefined ? +sys.args[1] : 1;
// The second cl arg should be the number of random numbers to generate.
// If not given, the default is 10000.
RND_NUMS = sys.args[2] !== undefined ? +sys.args[2] : 10000;
// The third cl arg will set the boolean perfomance mode.
// If not given, the default is false.
PERF = (sys.args[3] === "false") ? false : (sys.args[3] || false);
// Set the start global.
start = new Date().getTime();
// Spinn off the threads.
for(n = 1; n <= NUM_THREADS; n += 1) {
// If this is the last thread to generate, return a last_thread function,
// else return a generic_thread function.
spawn((n === NUM_THREADS) ? last_thread(n) : generic_thread(n));
}
// We need this to give the threads all a chance to
// register their observer functions.
java.lang.Thread.sleep(0);
// Generate and broadcast random numbers > 1 and < 20;
for (i = 0; i < RND_NUMS; i++) {
y = 2+ (Math.random() *19) | 0;
if (!PERF) {
// If not in performance mode, print the yeilded number.
print("yield: "+ y);
}
// Broadcast the number to the first thread.
observers[1](y);
}
}
// Gitterdone.
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment