import Utilities.*; import Synchronization.*; class Result { public int position; public double value; public Result(int p, double v) { position = p; value = v; } } class Worker extends MyObject implements Runnable { private int id = -1; private int numWorkers = -1; private boolean debug = false; private MessagePassing sync = null; private MessagePassing result = null; private MessagePassing leftIn = null, rightIn = null; private MessagePassing leftOut = null, rightOut = null; public Worker(int id, int numWorkers, boolean debug, MessagePassing sync, MessagePassing leftIn, MessagePassing rightIn, MessagePassing leftOut, MessagePassing rightOut) { this.id = id; this.numWorkers = numWorkers; this.debug = debug; this.sync = sync; this.leftIn = leftIn; this.rightIn = rightIn; this.leftOut = leftOut; this.rightOut = rightOut; (new Thread(this)).start(); } public void run() { double a, b, c, d; a = receiveDouble(leftIn); b = receiveDouble(rightIn); // wait here until all workers have their (a,b) result = (MessagePassing) receive(sync); if (debug) System.out.println("worker " + id + " received " + a + " and " + b); /* You put code for numWorkers iterations of the compare-exchange here. */ /************************************************************************/ // Sorting is now complete. if (debug) System.out.println("worker " + id + " sending " + a + " and " + b); send(result, new Result(2*id, a)); send(result, new Result(2*id+1, b)); } } class CompareExchangeSort extends MyObject { private static final int MAX_PER_LINE = 10; private static void printArray(double[] a) { int count = 0; for (int i = 0; i < a.length; i++) { System.out.print(" " + a[i]); count++; if (count % MAX_PER_LINE == 0) System.out.print("\n"); } if (count % MAX_PER_LINE != 0) System.out.print("\n"); } public static void main(String[] args) { // parse command line options, if any, to override defaults GetOpt go = new GetOpt(args, "Udn:r:"); go.optErr = false; String usage = "Usage: -d -n N -r RANGE" + " nums[i] in [1,RANGE] for i=0,1,...,N"; int ch = -1; boolean debug = false; int N = 10; int RANGE = 100; while ((ch = go.getopt()) != go.optEOF) { if ((char)ch == 'U') { System.out.println(usage); System.exit(0); } else if ((char)ch == 'd') debug = true; else if ((char)ch == 'n') N = go.processArg(go.optArgGet(), N); else if ((char)ch == 'r') RANGE = go.processArg(go.optArgGet(), RANGE); else { System.err.println(usage); System.exit(1); } } if (N <= 0 || N % 2 != 0) { System.out.println("number " + N + " to sort must be >0 and even"); System.exit(1); } else System.out.println("CompareExchange sorting " + N + " numbers between " + (-RANGE) + " and " + RANGE + " (debug=" + debug + ")"); double[] nums = new double[N]; int argNum = go.optIndexGet(); for (int i = 0; i < N; i++) { nums[i] = random(-RANGE, RANGE); nums[i] = go.tryArg(argNum++, nums[i]); } int numWorkers = N/2; // worker i receives left with left[i] and receives right with right[i] AsyncMessagePassing[] left = new AsyncMessagePassing[numWorkers]; AsyncMessagePassing[] right = new AsyncMessagePassing[numWorkers]; AsyncMessagePassing sync = new AsyncMessagePassing(); AsyncMessagePassing result = new AsyncMessagePassing(); for (int i = 0; i < numWorkers; i++) { left[i] = new AsyncMessagePassing(); right[i] = new AsyncMessagePassing(); } for (int i = 0; i < numWorkers; i++) { if (i == 0) { // leftmost worker // leftIn, rightIn, leftOut, rightOut new Worker(i, numWorkers, debug, sync, left[i], right[i], left[i], left[i+1]); } else if (i == numWorkers-1) { // rightmost worker new Worker(i, numWorkers, debug, sync, left[i], right[i], right[i-1], right[i]); } else { // general case new Worker(i, numWorkers, debug, sync, left[i], right[i], right[i-1], left[i+1]); } } // It is necessary for all the workers to receive their initial // two numbers from their leftIn and rightIn channels before they // start sending numbers to each other. for (int i = 0; i < numWorkers; i++) { send(left[i], nums[2*i]); send(right[i], nums[2*i+1]); } // Release workers so they can compare and exchange after getting // their initial two numbers. for (int i = 0; i < numWorkers; i++) send(sync, result); System.out.println("Original numbers:"); printArray(nums); for (int i = 0; i < N; i++) { Result r = (Result) receive(result); nums[r.position] = r.value; } System.out.println("Sorted numbers:"); printArray(nums); System.out.println("age()=" + age() + ", done"); System.exit(0); } }