/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2009, 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 sp; import com.jopdesign.io.SysDevice; import com.jopdesign.io.IOFactory; /** * The sheduler API for the single-path based CMP system. * * @author Martin Schoeberl (martin@jopdesign.com) Raimund Kirner * (raimund@vmars.tuwien.ac.at) * */ public class STScheduler implements Runnable { int i; public int time = 0; int period = 0; static SysDevice sys = IOFactory.getFactory().getSysDevice(); static final int MEM_TDMA_ROUND = 18; // length of the mem TDA round (= // #Cores * size_of_TDMA_slot) /** * A helper runnable to treat the different task phases in uniform way. * * @author Raimund Kirner (raimund@vmars.tuwien.ac.at) * */ static abstract class Runner implements Runnable { SimpleTask task; int tmeas; public Runner(SimpleTask st) { task = st; } public void measure() { int tstart, tstop; tstart = sys.cntInt; run(); tstop = sys.cntInt; tmeas = tstop-tstart; } public int getMeasResult() { int tstart, tstop; tstart = sys.cntInt; tstop = sys.cntInt; return tmeas - (tstop-tstart); } } /** * A helper runnable for the read phase * * @author Martin Schoeberl (martin@jopdesign.com) * */ static class RRunner extends Runner { public RRunner(SimpleTask st) { super(st); } public void run() { task.read(); } } /** * A helper runnable for the execute phase * * @author Martin Schoeberl (martin@jopdesign.com) * */ static class XRunner extends Runner { public XRunner(SimpleTask st) { super(st); } public void run() { task.execute(); } } /** * A helper runnable for the write phase * * @author Martin Schoeberl (martin@jopdesign.com) * */ static class WRunner extends Runner { public WRunner(SimpleTask st) { super(st); } public void run() { task.write(); } } /** * A table for the cyclic executive... * * @author Raimund Kirner (raimund@vmars.tuwien.ac.at) * */ static class TabCyclicExec { Runner tsk; int tactivation; } public TabCyclicExec[] tabCyclicExec; /* * this table must be filled with the * task schedules */ // Constructor public STScheduler(int maxtask) { tabCyclicExec = new TabCyclicExec[maxtask]; for (i = 0; i < maxtask; i++) { tabCyclicExec[i] = new TabCyclicExec(); } // System.out.println("STScheduler.constructor("+maxtask+")");System.out.flush(); } /** * Get the operating frequency of the processor in clock ticks per * millisecond. * * @return */ public int getMsCycles() { // TODO: add query method to the I/O factory return 60000; } /** * Shall we really provide a wrapper for a standard Java class/method? * * @return */ public int getNrCores() { return Runtime.getRuntime().availableProcessors(); } /** * The major cycle for all cores. * * @param period */ public void setMajorCycle(int period) { this.period = period; } /** * Perform a wait till the begin of the next scheduling cycle * * @return */ public boolean waitForNextPeriod() { time = time + period; // sys.deadLine = time; /* perform the wait */ return true; } /** * Perform a wait till the start of a new round of the TDMA memory arbiter. * This allows to synchronize the start of a task to be allways in the same * sync with the TDMA memory arbiter. Drawback of implementation: is * hardware dependent, as it has to wait longer than the calculation of the * waiting time takes. * * @return */ public static boolean syncWithMEMTDMA() { sys.deadLine = ((sys.cntInt + 2253) /* * 2253 cycles is the determined * WCET of this method */ / MEM_TDMA_ROUND) * MEM_TDMA_ROUND; // + 60000*100; // (mod time + 100ms); return true; } /** * Start the execution of the remaining cores of the JOP * * @return */ public void startCPUs() { sys.signal = 1; } /** * Add a simple task to the static schedule. * * @param task * the task * @param core * the CMP core where it shall run * @param readStart * start time relative to the major frame in clock cycles for the * data read * @param exeStart * start time of the execute phase * @param writeStart * start time for the data write phase */ public void addTask(SimpleTask task, int core, int readStart, int exeStart, int writeStart) { // TODO: insert the task in a runtime data structure } public void genShedule() { // TODO wrap all tasks into lists of runnables for each core } /** * Start the mission phase. All cores execute their static schedule. */ public void startMission() { } /** * Start the cyclic executive.... */ public void run() { waitForNextPeriod(); for (;;) { for (i = 0; i < tabCyclicExec.length; i++) { // System.out.println("STSscheduler.run().i="+i); if (tabCyclicExec[i].tsk != null) { /* wait for the begin of the task activation */ // sys.deadLine = (time + tabCyclicExec[i].tactivation); /* start the task (either read(), execute(), or write()) */ tabCyclicExec[i].tsk.run(); } } waitForNextPeriod(); } } }