/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.runtime.impl.java; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.lang.reflect.InvocationTargetException; import java.util.Map; import x10.io.Reader; import x10.io.Writer; import x10.lang.FinishState; import x10.rtt.RuntimeType; import x10.rtt.Type; import x10.rtt.Types; import x10.serialization.X10JavaDeserializer; import x10.serialization.X10JavaSerializable; import x10.serialization.X10JavaSerializer; import x10.x10rt.X10RT; public abstract class Runtime implements x10.core.fun.VoidFun_0_0 { private static final long serialVersionUID = 1L; public RuntimeType<?> $getRTT() { return null; } public Type<?> $getParam(int i) { return null; } protected String[] args; // not used // // constructor just for allocation // public Runtime(java.lang.System[] $dummy) { // // TODO // // super($dummy); // } // // public Runtime $init() { // return this; // } public Runtime() {} /** * Body of main java thread * (only called in non-library mode) */ protected void start(final String[] args) { this.args = args; // load libraries String property = System.getProperty("x10.LOAD"); if (null != property) { String[] libs = property.split(":"); for (int i = libs.length - 1; i >= 0; i--) System.loadLibrary(libs[i]); } X10RT.init(); x10.lang.Runtime.get$staticMonitor(); x10.lang.Runtime.get$STRICT_FINISH(); x10.lang.Runtime.get$NTHREADS(); x10.lang.Runtime.get$MAX_THREADS(); x10.lang.Runtime.get$STATIC_THREADS(); x10.lang.Runtime.get$WARN_ON_THREAD_CREATION(); x10.lang.Runtime.get$BUSY_WAITING(); java.lang.Runtime.getRuntime().addShutdownHook(new java.lang.Thread() { public void run() { System.out.flush(); } }); // start and join main x10 thread in place 0 x10.lang.Runtime.Worker worker = new x10.lang.Runtime.Worker(0); worker.body = this; worker.start(); try { worker.join(); } catch (java.lang.InterruptedException e) { // Note: since this isn't user visible, java.lang.InterruptedException is used. } // shutdown X10RT.X10_EXITING_NORMALLY = true; System.exit(exitCode); } // body of main activity static class $Closure$Main implements x10.core.fun.VoidFun_0_0 { private static final long serialVersionUID = 1L; private final Runtime out$; private final x10.array.Array<String> aargs; public void $apply() { // catch and rethrow checked exceptions (closures cannot throw // checked exceptions) try { // execute root x10 activity out$.runtimeCallback(aargs); } catch (java.lang.RuntimeException e) { throw e; } catch (java.lang.Error e) { throw e; } catch (java.lang.Throwable t) { throw new x10.lang.WrappedThrowable(t); } } $Closure$Main(Runtime out$, x10.array.Array<String> aargs) { this.out$ = out$; this.aargs = aargs; } public RuntimeType<?> $getRTT() { return $RTT; } public Type<?> $getParam(int i) { return null; } public void $_serialize(X10JavaSerializer $serializer) throws java.io.IOException { throw new java.lang.UnsupportedOperationException("Serialization not supported for " + getClass()); } public short $_get_serialization_id() { throw new java.lang.UnsupportedOperationException("Serialization not supported for " + getClass()); } } public void $apply() { // x10rt-level registration of MessageHandlers if (X10RT.numPlaces() > 1) { x10.x10rt.MessageHandlers.registerHandlers(); } // build up Array[String] for args final x10.array.Array<String> aargs = new x10.array.Array<String>((java.lang.System[]) null, Types.STRING).x10$array$Array$$init$S((args == null)?0:args.length); if (args != null) { for (int i = 0; i < args.length; i++) { aargs.$set__1x10$array$Array$$T$G(i, args[i]); } } // execute root x10 activity try { // start xrx x10.lang.Runtime.start( // body of main activity new $Closure$Main(this, aargs)); } catch (java.lang.Throwable t) { // XTENLANG=2686: Unwrap UnknownJavaThrowable to get the original Throwable object if (t instanceof x10.lang.WrappedThrowable) t = t.getCause(); t.printStackTrace(); setExitCode(1); } } /** * User code provided by Main template - start xrx runtime - run main * activity */ public abstract void runtimeCallback(x10.array.Array<java.lang.String> args) throws java.lang.Throwable; /** * Application exit code */ private static int exitCode = 0; /** * Set the application exit code */ public static void setExitCode(int code) { exitCode = code; } /** * The number of places in the system */ public static int MAX_PLACES = 0; // updated in initialization /** * Disable Assertions */ public static final boolean DISABLE_ASSERTIONS = Boolean.getBoolean("x10.DISABLE_ASSERTIONS"); /** * Trace serialization */ public static final boolean TRACE_SER = Boolean.getBoolean("x10.TRACE_SER"); /** * Trace static init */ public static final boolean TRACE_STATIC_INIT = Boolean.getBoolean("X10_TRACE_STATIC_INIT"); /** * Emit detail serialization traces for java serialization. Using for debugging in preliminary stage */ public static final boolean TRACE_SER_DETAIL = Boolean.getBoolean("x10.TRACE_SER_DETAIL"); public static final boolean X10_TRACE_ANSI_COLORS = Boolean.getBoolean("X10_TRACE_ANSI_COLORS"); public static final String ANSI_RESET = X10_TRACE_ANSI_COLORS? "\u001b[1;0m" :""; public static final String ANSI_BOLD = X10_TRACE_ANSI_COLORS? "\u001b[1;1m" :""; public static final String ANSI_CYAN = X10_TRACE_ANSI_COLORS? "\u001b[1;36m" :""; public static final String TRACE_MESSAGE = "SS"; public static final String STATIC_INIT_MESSAGE = "SI"; public static void printTraceMessage(String message) { print(TRACE_MESSAGE, ANSI_CYAN, message); } public static void printStaticInitMessage(String message) { print(STATIC_INIT_MESSAGE, ANSI_CYAN, message); } private static void print(String type, String col, String message) { System.out.println(ANSI_BOLD + X10RT.here() + ": " + col + type + ": " + ANSI_RESET + message); } public static void runAsyncAt(int place, x10.core.fun.VoidFun_0_0 body, FinishState finishState, x10.lang.Runtime.Profile prof, int endpoint) { runAsyncAt(place, body, finishState, prof); } public static void runAsyncAt(int place, x10.core.fun.VoidFun_0_0 body, FinishState finishState, x10.lang.Runtime.Profile prof) { try { byte[] bytes = serialize(body, finishState, prof); long start = prof!=null ? System.nanoTime() : 0; x10.x10rt.MessageHandlers.runSimpleAsyncAtSend(place, bytes.length, bytes); if (prof!=null) { prof.communicationNanos += System.nanoTime() - start; } } catch (java.io.IOException e) { java.lang.RuntimeException xe = x10.runtime.impl.java.ThrowableUtils.ensureX10Exception(e); xe.printStackTrace(); throw xe; } } /** * Synchronously executes body at place(id) */ public static void runClosureAt(int place, x10.core.fun.VoidFun_0_0 body, x10.lang.Runtime.Profile prof) { runAt(place, body, prof); } /** * Synchronously executes body at place(id) */ public static void runClosureCopyAt(int place, x10.core.fun.VoidFun_0_0 body, x10.lang.Runtime.Profile prof) { runAt(place, body, prof); } /** * Copy body (same place) */ @SuppressWarnings("unchecked") public static <T> T deepCopy(T body, x10.lang.Runtime.Profile prof) { try { if (TRACE_SER_DETAIL) { System.out.println("Starting deepCopy of " + body.getClass()); } long start = prof!=null ? System.nanoTime() : 0; byte[] ba = serialize(body, null); DataInputStream ois = new DataInputStream(new ByteArrayInputStream(ba)); X10JavaDeserializer deserializer = new X10JavaDeserializer(ois); body = (T) deserializer.readRef(); if (prof!=null) { long stop = System.nanoTime(); long duration = stop-start; prof.bytes += ba.length; prof.serializationNanos += duration; } if (TRACE_SER_DETAIL) { System.out.println("Done with deserialization for deepCopy of " + body.getClass()); } return body; } catch (java.io.IOException e) { java.lang.RuntimeException xe = x10.runtime.impl.java.ThrowableUtils.ensureX10Exception(e); xe.printStackTrace(); throw xe; } } public static <T> byte[] serialize(T body, x10.lang.Runtime.Profile prof) throws java.io.IOException { if (TRACE_SER_DETAIL) { System.out.println("Starting serialization for runAtAll " + body.getClass()); } long start = prof!=null ? System.nanoTime() : 0; X10JavaSerializer serializer = new X10JavaSerializer(); if (body instanceof X10JavaSerializable) { serializer.write((X10JavaSerializable) body); } else { serializer.write(body); } byte[] ba = serializer.toMessage(); if (prof != null) { long stop = System.nanoTime(); long duration = stop-start; prof.bytes += ba.length; prof.serializationNanos += duration; } if (TRACE_SER_DETAIL) { System.out.println("Done with serialization for runAtAll " + body.getClass()); } return ba; } private static Class<? extends Object> hadoopWritableClass = getHadoopClass(); private static Class<? extends Object> getHadoopClass() { try { return Class.forName("org.apache.hadoop.io.Writable"); } catch (ClassNotFoundException e) { return null; } } public static boolean implementsHadoopWritable(Class<? extends Object> clazz) { if(hadoopWritableClass == null) { return false; } return hadoopWritableClass.isAssignableFrom(clazz); } private static byte[] serialize(x10.core.fun.VoidFun_0_0 body, FinishState finishState, x10.lang.Runtime.Profile prof) throws java.io.IOException { if (TRACE_SER_DETAIL) { System.out.println("Starting serialization for runAtAll " + body.getClass()); } long start = prof!=null ? System.nanoTime() : 0; X10JavaSerializer serializer = new X10JavaSerializer(); serializer.write(finishState); long before_bytes = serializer.numBytesWritten(); serializer.write(body); long ser_bytes = serializer.numBytesWritten() - before_bytes; byte[] ba = serializer.toMessage(); if (prof != null) { long stop = System.nanoTime(); long duration = stop-start; prof.bytes += ser_bytes; prof.serializationNanos += duration; } if (TRACE_SER_DETAIL) { System.out.println("Done with serialization for runAtAll " + body.getClass()); } return ba; } public static void runAt(int place, x10.core.fun.VoidFun_0_0 body, x10.lang.Runtime.Profile prof) { try { if (TRACE_SER_DETAIL) { System.out.println("Starting serialization for runAtAll " + body.getClass()); } long start = prof!=null ? System.nanoTime() : 0; X10JavaSerializer serializer = new X10JavaSerializer(); serializer.write(body); byte[] msgBody = serializer.toMessage(); if (prof!=null) { long stop = System.nanoTime(); long duration = stop-start; prof.bytes += msgBody.length; prof.serializationNanos += duration; } if (TRACE_SER_DETAIL) { System.out.println("Done with serialization for runAtAll " + body.getClass()); } int msgLen = msgBody.length; if (X10RT.VERBOSE) System.out.println("@MultiVM: sendJavaRemote"); if (prof!=null) { start = System.nanoTime(); } x10.x10rt.MessageHandlers.runClosureAtSend(place, msgLen, msgBody); if (prof!=null) { prof.communicationNanos += System.nanoTime() - start; } } catch (java.io.IOException e) { e.printStackTrace(); throw new x10.lang.WrappedThrowable(e); } finally { if (X10RT.VERBOSE) System.out.println("@MultiVM: finally section"); } } // Special version of runAt for broadcast type communication // (Serialize once, run everywhere) public static void runAtAll(boolean includeHere, byte[] msg) { int hereId = X10RT.here(); for (int place = hereId + 1; place < Runtime.MAX_PLACES; ++place) { x10.x10rt.MessageHandlers.runClosureAtSend(place, msg.length, msg); } int endPlace = includeHere ? hereId : hereId - 1; for (int place = 0; place <= endPlace; ++place) { x10.x10rt.MessageHandlers.runClosureAtSend(place, msg.length, msg); } } /** * @MultiVM: Return true if place(id) is local to this node */ public static boolean local(int id) { int hereId = X10RT.here(); return (hereId == id); } /** * @MultiVM: mapped to Runtime.x10 -> event_probe(): void */ public static void eventProbe() { X10RT.probe(); } /** * @MultiVM: mapped to Runtime.x10 -> blocking_probe(): void */ public static void blockingProbe() { X10RT.blockingProbe(); } /** * Load environment variables. */ public static x10.util.HashMap<String, String> loadenv() { Map<String, String> env = System.getenv(); x10.util.HashMap<String, String> map = new x10.util.HashMap<String, String>((java.lang.System[]) null, Types.STRING, Types.STRING).x10$util$HashMap$$init$S(); for (Map.Entry<String, String> e : env.entrySet()) { map.put__0x10$util$HashMap$$K__1x10$util$HashMap$$V(e.getKey(), e.getValue()); } return map; } public static Reader execForRead(String command) { try { Process proc = java.lang.Runtime.getRuntime().exec(command); return new x10.io.InputStreamReader(new x10.core.io.InputStream(proc.getInputStream())); } catch (java.io.IOException e) { java.lang.RuntimeException xe = x10.runtime.impl.java.ThrowableUtils.ensureX10Exception(e); xe.printStackTrace(); throw xe; } } public static Writer execForWrite(String command) { try { Process proc = java.lang.Runtime.getRuntime().exec(command); return new x10.io.OutputStreamWriter(new x10.core.io.OutputStream(proc.getOutputStream())); } catch (java.io.IOException e) { java.lang.RuntimeException xe = x10.runtime.impl.java.ThrowableUtils.ensureX10Exception(e); xe.printStackTrace(); throw xe; } } /** * Redirect to the specified user class's main(). */ public static void main(String[] args) throws Throwable { boolean verbose = false; String className = null; for (int i = 0; i < args.length; i++) { String arg = args[i]; if (arg.equals("-v") || arg.equals("-verbose") || arg.equals("--verbose")) { verbose = true; } else if (arg.charAt(0) == '-') { int eq = arg.indexOf('='); String key = "x10." + (eq < 0 ? arg.substring(1) : arg.substring(1, eq)); String value = eq < 0 ? "true" : arg.substring(eq + 1); System.setProperty(key, value); } else { int dotx10 = arg.indexOf(".x10"); className = (dotx10 < 0 ? arg : arg.substring(0, dotx10)) + "$$Main"; int len = args.length - i - 1; System.arraycopy(args, i + 1, args = new String[len], 0, len); } } if (verbose) { System.err.println("Invoking user class: " + className + " with classpath '" + System.getProperty("java.class.path") + "'"); } try { Class.forName(className).getMethod("main", String[].class).invoke(null, (Object) args); } catch (ClassNotFoundException e) { System.err.println("Class not found: " + className); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { System.err.println("Unable to invoke user program: " + e); if (verbose) e.printStackTrace(); } } public short $_get_serialization_id() { throw new java.lang.UnsupportedOperationException("Cannot serialize " + getClass()); } public void $_serialize(X10JavaSerializer $serializer) throws java.io.IOException { throw new java.lang.UnsupportedOperationException("Cannot serialize " + getClass()); } /** * Time serialization/deserialization operations. */ public static final boolean PROF_SER = Boolean.getBoolean("x10.PROF_SER"); /** * Minimum threshold in for reporting serialization/deserialization times. * The property is a value in milliseconds, we convert to nanoSeconds for efficiency when using System.nanoTime. * The default value is 10ms. */ public static final long PROF_SER_FILTER = 1000 * 1000 * Long.getLong("x10.PROF_SER_FILTER", 10); }