co.turnus.trace.scheduler.devs.DevsTraceScheduler.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.trace.scheduler.devs.DevsTraceScheduler.java

Source

/* 
 * TURNUS, the co-exploration framework
 * 
 * Copyright (C) 2015 EPFL SCI STI MM
 *
 * This file is part of TURNUS.
 *
 * TURNUS 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.
 *
 * TURNUS 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 TURNUS.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Additional permission under GNU GPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or combining it
 * with Eclipse (or a modified version of Eclipse or an Eclipse plugin or 
 * an Eclipse library), containing parts covered by the terms of the 
 * Eclipse Public License (EPL), the licensors of this Program grant you 
 * additional permission to convey the resulting work.  Corresponding Source 
 * for a non-source form of such a combination shall include the source code 
 * for the parts of Eclipse libraries used as well as that of the  covered work.
 * 
 */
package co.turnus.trace.scheduler.devs;

import static co.turnus.trace.scheduler.devs.DevsTraceSchedulerOptions.EXPORT_GANTT;
import static co.turnus.trace.scheduler.devs.DevsTraceSchedulerOptions.SIMULATION_ID;

import java.util.UUID;

import org.apache.commons.configuration.Configuration;

import adevs.Simulator;
import co.turnus.TurnusRuntimeException;
import co.turnus.dataflow.Action;
import co.turnus.dataflow.Actor;
import co.turnus.gantt.GanttChartBuilder;
import co.turnus.generic.AbstractConfigurable;
import co.turnus.mapping.Mapping;
import co.turnus.trace.Step;
import co.turnus.trace.TraceProject;
import co.turnus.trace.scheduler.devs.model.DevsActor;
import co.turnus.trace.scheduler.devs.model.DevsActor.State;
import co.turnus.trace.scheduler.devs.model.DevsModel;
import co.turnus.trace.scheduler.devs.util.DevsModelBuilder;
import co.turnus.trace.weighter.TraceWeighter;
import co.turnus.util.SimpleTimer;
import co.turnus.util.TurnusLogger;

public class DevsTraceScheduler extends AbstractConfigurable {

    private DevsModel model;
    private TraceProject traceProject;
    private Mapping mapping;
    private TraceWeighter weighter;

    private String simulationId;

    private GanttChartBuilder ganttBuilder;

    private long scaledTime = 0;

    private boolean exportGantt;

    public DevsTraceScheduler(TraceProject traceProject, Mapping mapping, TraceWeighter weighter) {
        this.traceProject = traceProject;
        this.mapping = mapping;
        this.weighter = weighter;
    }

    public void setConfiguration(Configuration configuration) {
        super.setConfiguration(configuration);

        simulationId = getOption(SIMULATION_ID, UUID.randomUUID().toString());
        model = new DevsModelBuilder(traceProject, weighter, simulationId).build();

        exportGantt = getOption(EXPORT_GANTT, false);
        if (exportGantt) {
            ganttBuilder = new GanttChartBuilder(traceProject.getNetwork(), simulationId);
            ganttBuilder.setConfiguration(configuration);
        }
    }

    public void run() {
        if (simulationId == null) {
            throw new TurnusRuntimeException("DEVS Trace scheduler not configured!");
        }

        TurnusLogger.info("Starting simulation \"" + simulationId + "\"");

        // set remaining parameters and variables
        Simulator sim = new Simulator(model);
        double t = sim.nextEventTime();
        double simTimer = -Double.MIN_VALUE;
        SimpleTimer cpuClock = new SimpleTimer();
        cpuClock.reset();

        // simulate
        while (t < Double.MAX_VALUE) {

            if (exportGantt) {
                long scaledT = getGanttTime(t);
                if (scaledT != scaledTime) {
                    scaledTime = scaledT;
                    logStatus(scaledTime);
                }
            }

            simTimer = t;

            sim.execNextEvent();
            t = sim.nextEventTime();
        }

        logStatus(getGanttTime(simTimer));

        boolean deadlock = checkDeadlock();

        TurnusLogger.info("Simulation \"%s\" done (deadlock: %b)", simulationId, deadlock);
        TurnusLogger.info("Throughput: " + simTimer);
        TurnusLogger.info("CPU timer : " + cpuClock.getElapsedTime());

        if (exportGantt) {
            TurnusLogger.info("Finalizing gantt chart...");
            ganttBuilder.end(getGanttTime(simTimer));
        }
    }

    private boolean checkDeadlock() {

        boolean deadlock = false;

        TurnusLogger.debug("CHECK ENDING STATUS");
        for (DevsActor dactor : model.getActors()) {
            State status = dactor.getCurrentState();
            TurnusLogger.debug("Actor %s : %s", dactor.getActor().getId(), status);
            deadlock |= status != State.FINISHED;
        }
        return deadlock;
    }

    private void logStatus(long newCycleTime) {

        for (DevsActor dactor : model.getActors()) {
            Actor actor = dactor.getActor();
            String status = dactor.getCurrentState().toString();
            ganttBuilder.log(actor, status);

            Step step = dactor.getCurrentStep();
            if (step != null) {
                long stepId = step.getID();
                Action action = traceProject.getTraceDecorator().getAction(step);
                ganttBuilder.log(actor, action, status, stepId);
            }

        }

        ganttBuilder.startNewCycle(newCycleTime);

    }

    private static long getGanttTime(double simTime) {
        return Math.round(simTime * 1000);
    }
}