/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2008, Martin Schoeberl (martin@jopdesign.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package rttm.jsim; import com.jopdesign.io.IOFactory; import com.jopdesign.io.SysDevice; import com.jopdesign.sys.Const; import com.jopdesign.sys.Native; import com.jopdesign.sys.Startup; /** * each core reads the current global increment value and tries to write * the sum of its own id and this value into a global array. * additionally each core saves the array indices it has written to. * after the array has been filled, each core indice list is compared to * the real written values and any inconsistency is reported * * @author michael muck * simple increment test */ public class IncrementTest { static SysDevice sys = IOFactory.getFactory().getSysDevice(); static final int SIZE = 1000; static final int EMPTY = -1; static int[] ia = new int[SIZE]; static int incrementVar = 0; /** * @param args */ public static void main(String[] args) { Incrementer r[] = new Incrementer[sys.nrCpu]; for (int i=0; i<sys.nrCpu; ++i) { if(i<sys.nrCpu-1) { r[i] = new Incrementer(i+1); Startup.setRunnable(r[i], i); } else { r[i] = new Incrementer(0); } } // reset array for(int i=0; i<SIZE; ++i) { ia[i] = EMPTY; } // time measurement int startTime, endTime; startTime = Native.rd(Const.IO_US_CNT); // start the other CPUs sys.signal = 1; // start my work r[sys.nrCpu-1].run(); // wait for other CPUs to finish boolean allDone = false; while (!allDone) { allDone = true; for (int i=0; i<sys.nrCpu-1; ++i) { allDone &= r[i].finished; } } endTime = Native.rd(Const.IO_US_CNT); System.out.print("Time: "); System.out.print(endTime-startTime); System.out.println("\n"); // verify for(int i=0; i<sys.nrCpu; ++i) { r[i].verify(); } // print array System.out.println("Raw output: "); String space = " "; for(int i=0; i<SIZE; ++i) { System.out.print(ia[i]); System.out.print(space); } // wipe off cpuid from the numbers for(int i=0; i<sys.nrCpu; ++i) { r[i].clean(); } // print array System.out.println("\nWithout cpuid: "); for(int i=0; i<SIZE; ++i) { System.out.print(ia[i]); System.out.print(space); } } static class Incrementer implements Runnable { public boolean finished; private static final int MAGIC = -10000; private boolean[] writtenPosition = new boolean[SIZE]; private int cpuid; public Incrementer(int id) { cpuid = id; for(int i=0; i<SIZE; ++i) { writtenPosition[i] = false; } } public void run() { boolean ok = true; while(ok) { Native.wrMem(1, MAGIC); // start transaction if(incrementVar < SIZE) { if(ia[incrementVar] == EMPTY) { ia[incrementVar] = incrementVar + cpuid; writtenPosition[incrementVar] = true; incrementVar++; } } else { ok = false; } Native.wrMem(0, MAGIC); // end transaction } finished = true; } public void verify() { boolean good = true; for(int i=0; i<SIZE; ++i) { if(writtenPosition[i] == true) { if(ia[i]-i != cpuid) { System.out.println("Read/Write error at position " + i + " from cpu" + cpuid); good = false; } } } if(good) { System.out.println("cpu" + cpuid + ": verify ok!"); } } public void clean() { for(int i=0; i<SIZE; ++i) { if(writtenPosition[i] == true) { if(ia[i]-i == cpuid) { // remove cpuid from numbers ia[i] = ia[i] - cpuid; } } } } } }