/* This file is part of JOP, the Java Optimized Processor see <http://www.jopdesign.com/> Copyright (C) 2010, 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 cmpce; /** * @author martin * */ import javax.realtime.RelativeTime; import javax.safetycritical.annotate.SCJAllowed; import com.jopdesign.io.IOFactory; import com.jopdesign.io.SysDevice; import com.jopdesign.sys.Startup; @SCJAllowed public class CyclicSchedule { @SCJAllowed final public static class Frame { Runnable handler; int usDuration; @SCJAllowed public Frame(RelativeTime duration, Runnable handler) { this.handler = handler; usDuration = (int) (duration.getMilliseconds()*1000 + duration.getNanoseconds()/1000); } @SCJAllowed final RelativeTime getDuration() { return null; } final Runnable[] getHandlers() { return null; } } @SCJAllowed public CyclicSchedule(Frame[] frames) { } Frame[][] frames; static SysDevice sys = IOFactory.getFactory().getSysDevice(); /** * Set the cyclic schedule for a multiprocessor version. * * @param frames */ public CyclicSchedule(Frame[][] frames) { int nrCpus = Runtime.getRuntime().availableProcessors(); if (frames.length > nrCpus) { throw new Error("Not enough CPUs for this schedule"); } this.frames = frames; // TODO: check that all cycles are of the same length // anything else to do? } /** * We don't care about the Safelet at the moment. Just start the stuff. */ public void startMission() { for (int i=0; i<frames.length-1; ++i) { Runnable r = new Runnable() { public void run() { executeCycle(); } }; Startup.setRunnable(r, i); } // start the cycle in 1 ms startTime = sys.uscntTimer + 1000; // start the other CPUs sys.signal = 1; // also do a schedule executeCycle(); } int startTime; static boolean frameOverrun; private void executeCycle() { // wait for start time int nextTime = startTime; int next = 0; Frame myFrames[] = frames[sys.cpuId]; // THE endless loop for (;;) { Frame f = myFrames[next]; ++next; if (next==myFrames.length) { next = 0; } // wait for the start while (nextTime-sys.uscntTimer >= 0) { ; } // run the runnable f.handler.run(); // calculate next start time nextTime += f.usDuration; // check for overrun if (nextTime-sys.uscntTimer < 0) { frameOverrun = true; } } } public static int getCurrentProcessor() { return sys.cpuId; } public static boolean isFrameOverrun() { return frameOverrun; } final RelativeTime getCycleDuration() { return null; } protected final Frame[] getFrames() { return null; } }