/** * Copyright (c) 2009-2011, The HATS Consortium. All rights reserved. * This file is licensed under the terms of the Modified BSD License. */ package abs.backend.java.lib.runtime; import java.lang.reflect.Constructor; import java.util.logging.Logger; import abs.backend.java.debugging.GraphicalDebugger; import abs.backend.java.lib.runtime.RuntimeOptions.Option; import abs.backend.java.lib.runtime.RuntimeOptions.OptionType; import abs.backend.java.observing.SystemObserver; import abs.backend.java.scheduling.*; /** * Evaluates system properties * * @author Jan Schäfer * */ public class Config { private static final Logger logger = Logging.getLogger(Config.class.getName()); private final ABSRuntime runtime; private final RuntimeOptions options; public Config(ABSRuntime runtime, RuntimeOptions options) { this.runtime = runtime; this.options = options; if (options.help.isTrue()) { printHelp(); System.exit(1); } configureRuntime(); } public void configureRuntime() { setSimpleOptions(); loadSystemObserver(); loadTotalSchedulingStrategy(); loadTaskSchedulingStrategy(); loadGlobalSchedulingStrategy(); loadSchedulerFactory(); loadScheduableTasksFilter(); } private void loadScheduableTasksFilter() { if (options.scheduableTasksFilter.wasSet) { ScheduableTasksFilter filter = loadClassByName(ScheduableTasksFilter.class, options.scheduableTasksFilter.stringValue());; runtime.setScheduableTasksFilter(filter); } } public void loadSystemObserver() { if (options.systemObserver.wasSet()) { for (String s : options.systemObserver.stringArrayValue()) { logger.finest("adding systemobserver "+s); runtime.addSystemObserver(loadClassByName(SystemObserver.class,s)); } } } public void setSimpleOptions() { runtime.enableDebugging(options.debug.isTrue()); runtime.terminateOnException(options.terminateOnException.isTrue()); if (options.graphicalDebug.isTrue()) { runtime.enableDebugging(true); options.totalScheduler.setValue(InteractiveScheduler.class.getName()); options.systemObserver.appendStringValue(GraphicalDebugger.class.getName()); } loadRandomSeed(); } private void loadRandomSeed() { runtime.setRandomSeed(options.randomSeed.longValue()); if (options.printRandomSeed.isTrue()) { System.out.println("random seed="+options.randomSeed.longValue()); } if (options.useRandomScheduler.isTrue()) { options.totalScheduler.setValue(RandomSchedulingStrategy.class.getName()); } } public void printHelp() { System.err.println(" ABS Java Backend - Runtime Configuration Options"); System.err.println(" ================================================"); for (Option o : options.options) { if (o.type != OptionType.BOOLEAN) { System.err.println(String.format("%36s\t%s", "-"+o.name + "=<" + o.type.toString().toLowerCase() + ">", o.description)); } else { System.err.println(String.format("%36s\t%s", "-"+o.name, o.description)); } } } private static <T> T loadClassByName(Class<T> expected, String s, Object...args) { try { Class<?> clazz = Config.class.getClassLoader().loadClass(s); if (!expected.isAssignableFrom(clazz)) { throw new IllegalArgumentException("Can't use "+s+" as an instance for "+expected.getCanonicalName()); } for (Constructor<?> c : clazz.getConstructors()) { if (c.getParameterTypes().length == args.length) { // Safe cast. return (T) c.newInstance(args); } } throw new IllegalArgumentException("Couldn't find a constructor in class "+s+" with "+args.length+" arguments"); } catch (Exception e) { e.printStackTrace(); } return null; } public void loadTotalSchedulingStrategy() { if (options.totalScheduler.wasSet()) { TotalSchedulingStrategy strat = loadClassByName(TotalSchedulingStrategy.class, options.totalScheduler.stringValue(), runtime.getRandom()); if (strat != null) { logger.config("Using total scheduling strategy defined by class " + strat.getClass().getName()); runtime.setTotalSchedulingStrategy(strat); } else { logger.warning("Could not load total scheduler class "+options.totalScheduler.stringValue()); } } } public void loadTaskSchedulingStrategy() { if (options.taskSchedulerStrategy.wasSet()) { TaskSchedulingStrategy strat = loadClassByName(TaskSchedulingStrategy.class, options.taskSchedulerStrategy.stringValue()); if (strat == null) { logger.warning("Could not load task scheduling strategy class "+options.taskSchedulerStrategy.stringValue()); return; } if (strat instanceof RandomSchedulingStrategy) { ((RandomSchedulingStrategy) strat).setRandom(runtime.getRandom()); } logger.config("Using task scheduling strategy defined by class " + strat.getClass().getName()); if (options.recordTaskScheduler.isTrue()) { strat = new RecordingSchedulerStrategy(strat); logger.config("Recording schedule"); } runtime.setTaskSchedulingStrategy(strat); } } public void loadGlobalSchedulingStrategy() { if (options.globalScheduler.wasSet()) { GlobalSchedulingStrategy strat = loadClassByName(GlobalSchedulingStrategy.class, options.globalScheduler.stringValue()); if (strat != null) runtime.setGlobalSchedulingStrategy(strat); else logger.warning("Could not load task global strategy class "+options.globalScheduler.stringValue()); } } private void loadSchedulerFactory() { TaskSchedulerFactory taskSchedulerFactory; // only the SimpleTaskScheduler supports configuring if (options.taskSchedulerStrategy.wasSet() || options.totalScheduler.wasSet()) { logger.config("Using simple task scheduler, because task scheduling is specified"); taskSchedulerFactory = SimpleTaskScheduler.getFactory(); } else { String schedulerName = options.taskScheduler.stringValue(); if (schedulerName.equals("default")) { taskSchedulerFactory = DefaultTaskScheduler.getFactory(); } else if (schedulerName.equals("simple")) { taskSchedulerFactory = SimpleTaskScheduler.getFactory(); } else { logger.warning("The task scheduler " + schedulerName + " does not exist, falling back to the default task scheduler."); taskSchedulerFactory = DefaultTaskScheduler.getFactory(); } logger.config("Using " + schedulerName + " task scheduler"); } runtime.setTaskSchedulerFactory(taskSchedulerFactory); } }