public static void main(String args[]) { RuntimeConfiguration.get().getOutStream().println("TLC Worker " + TLCGlobals.versionOfTLC); String specFile = null; String configFile = null; String serverName = null; // Must have at least two args: a filename and a hostname. int index = 0; while (index < args.length) { if (args[index].equals("-config")) { index++; if (index < args.length) { configFile = args[index]; int len = configFile.length(); if (configFile.startsWith(".cfg", len - 4)) { configFile = configFile.substring(0, len - 4); } index++; } else { printErrorMsg("Error: configuration file required."); System.exit(0); } } else { if (args[index].charAt(0) == '-') { printErrorMsg("Error: unrecognized option: " + args[index]); System.exit(0); } if (specFile == null) { specFile = args[index++]; int len = specFile.length(); if (specFile.startsWith(".tla", len - 4)) { specFile = specFile.substring(0, len - 4); } } else if (serverName == null) { serverName = args[index++]; } else { printErrorMsg("Error: more than one input files: " + specFile + " and " + args[index]); System.exit(0); } } } if (specFile == null) { printErrorMsg("Error: Missing input TLA+ module."); return; } if (serverName == null) { printErrorMsg("Error: Missing hostname of the TLC server to be contacted."); return; } if (configFile == null) configFile = specFile; String hostname = "Unknown"; try { hostname = InetAddress.getLocalHost().getHostName(); String url = "//" + serverName + ":" + TLCServer.Port + "/TLCServer"; TLCServerRMI server = (TLCServerRMI) Naming.lookup(url); long irredPoly = server.getIrredPolyForFP(); FP64.Init(irredPoly); int lastSep = specFile.lastIndexOf(File.separatorChar); String specDir = (lastSep == -1) ? "" : specFile.substring(0, lastSep + 1); specFile = specFile.substring(lastSep + 1); Object[] appArgs = new Object[5]; appArgs[0] = specDir; appArgs[1] = specFile; appArgs[2] = configFile; appArgs[3] = server.getCheckDeadlock(); appArgs[4] = server.getPreprocess(); String appName = server.getAppName(); Class appClass = Class.forName(appName); Class[] classOfArgs = new Class[appArgs.length]; for (int i = 0; i < classOfArgs.length; i++) { classOfArgs[i] = appArgs[i].getClass(); } Constructor appConstructor = appClass.getDeclaredConstructor(classOfArgs); DistApp work = (DistApp) appConstructor.newInstance(appArgs); UniqueString.setSource((InternRMI) server); FPSetManager fpSetManager = server.getFPSetManager(); TLCWorkerRMI worker = new TLCWorker(work, fpSetManager); server.registerWorker(worker, hostname); RuntimeConfiguration.get().getOutStream().println("TLC worker at " + hostname + " is ready."); } catch (Throwable e) { RuntimeConfiguration.get() .getErrStream() .println( "Error: Failed to start worker at " + hostname + " for server " + serverName + ".\n" + e.getMessage()); } }
/** * CheckImplFile and the simulation engine communicate via files: * * <p>1. The simulation engine stores in files the abstract view of the states it generates during * the simulation run. The abstract view of simulation state is computed by a refinement function. * CheckImplFile checks the abstract states in the files. * * <p>2. CheckImplFile maintains coverage information while doing the checking. It continuously * generates traces to uncovered states, and store the traces in files. The simulation engine uses * the traces in the files to guide the simulation into the parts of the state space that * simulation fails to reach up to that point. * * <p>Usage: java tlc.tool.CheckImplFile [options] spec[.tla] * * <p>Below is a list of the command line options: o -config file: provide the config file. * Defaults to spec.cfg if not provided o -deadlock: do not check for deadlock. Defaults to * checking deadlock if not specified o -recover path: recover from checkpoint in path Defaults to * scratch run if not specified o -workers num: the number of TLC worker threads Defaults to 1 o * -depth num: the depth of the initial (partial) state space Defaults to 20 o -trace filename: * the prefix of the trace file name. o -coverage seconds: collect coverage information on the * spec, print out the information every seconds Defaults to no coverage if not specified */ public static void main(String[] args) { RuntimeConfiguration.get().getOutStream().println("TLC " + TLCGlobals.versionOfTLC); String mainFile = null; String configFile = null; String traceFile = null; boolean deadlock = true; int depth = 20; String fromChkpt = null; int index = 0; while (index < args.length) { if (args[index].equals("-config")) { index++; if (index < args.length) { configFile = args[index++]; int len = configFile.length(); if (configFile.startsWith(".cfg", len - 4)) { configFile = configFile.substring(0, len - 4); } } else { printErrorMsg("Error: expect a file name for -config option."); return; } } else if (args[index].equals("-deadlock")) { index++; deadlock = false; } else if (args[index].equals("-recover")) { index++; if (index < args.length) { fromChkpt = args[index++] + File.separator; } else { printErrorMsg("Error: need to specify the metadata directory for recovery."); return; } } else if (args[index].equals("-workers")) { index++; if (index < args.length) { try { TLCGlobals.setNumWorkers(Integer.parseInt(args[index])); index++; } catch (Exception e) { printErrorMsg("Error: worker number required. But encountered " + args[index]); return; } if (TLCGlobals.getNumWorkers() < 1) { printErrorMsg("Error: at least one worker required."); return; } } else { printErrorMsg("Error: expect an integer for -workers option."); return; } } else if (args[index].equals("-depth")) { index++; if (index < args.length) { try { depth = Integer.parseInt(args[index]); index++; } catch (Exception e) { printErrorMsg("Error: depth must be an integer. But encountered " + args[index]); return; } } else { printErrorMsg("Error: expect an integer for -depth option."); return; } } else if (args[index].equals("-trace")) { index++; if (index < args.length) { traceFile = args[index++]; } else { printErrorMsg("Error: expect a filename for -trace option."); return; } } else if (args[index].equals("-coverage")) { index++; TLCGlobals.coverage = true; if (index < args.length) { try { TLCGlobals.coverageInterval = Integer.parseInt(args[index]) * 1000; index++; } catch (Exception e) { printErrorMsg( "Error: An integer for coverage report interval required." + " But encountered " + args[index]); return; } } else { printErrorMsg("Error: coverage report interval required."); return; } } else { if (args[index].charAt(0) == '-') { printErrorMsg("Error: unrecognized option: " + args[index]); return; } if (mainFile != null) { printErrorMsg("Error: more than one input files: " + mainFile + " and " + args[index]); return; } mainFile = args[index++]; int len = mainFile.length(); if (mainFile.startsWith(".tla", len - 4)) { mainFile = mainFile.substring(0, len - 4); } } } if (mainFile == null) { printErrorMsg("Error: Missing input TLA+ module."); return; } if (configFile == null) configFile = mainFile; if (traceFile == null) traceFile = mainFile + "_trace"; try { // Initialize: if (fromChkpt != null) { // We must recover the intern var table as early as possible UniqueString.internTbl.recover(fromChkpt); } FP64.Init(0); // Start the checker: CheckImplFile checker = new CheckImplFile(mainFile, configFile, deadlock, depth, fromChkpt, traceFile); checker.init(); while (true) { // Get a trace and check it. checker.export(); boolean ok = checker.getTrace(); if (ok) { checker.checkTrace(); } else { synchronized (checker) { checker.wait(WaitForTrace); } } } } catch (Throwable e) { // e.printStackTrace(); RuntimeConfiguration.get() .getErrStream() .println("Error: TLC failed in checking traces. " + e.getMessage()); } System.exit(0); }