/* * 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.x10rt; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.InputStream; import x10.lang.FinishState; import x10.runtime.impl.java.Runtime; import x10.serialization.X10JavaDeserializer; /** * A class to contain the Java portion of message send/receive pairs. */ public class MessageHandlers { // values set in native method registerHandlers() private static int closureMessageID; private static int simpleAsyncMessageID; /** * Register the native methods that will invoke runClosureAtReceive * and runSimpleAsyncAtReceive as message handlers with the x10rt layer. * The message ids obtained from this registration will be stored * in the static fields closureMessageId and simpleAsyncMessageId. */ public static synchronized native void registerHandlers(); /** * Send an active message. */ private static native void sendMessage(int place, int msg_id, int arraylen, byte[] rawBytes); /* * This send/receive pair is used to serialize a ()=>void closure to * a remote place, which will deserialize the closure object and calls apply on it. * * One important use of this message pair is the non-optimized implementation of * x10.lang.Runtime.runClosureAt and x10.lang.Runtime.runClosureCopyAt. */ public static void runClosureAtSend(int place, int arraylen, byte[] rawBytes) { sendMessage(place, closureMessageID, arraylen, rawBytes); } // Invoked from native code at receiving place // This function gets called by the x10rt callback that is registered to handle // the receipt of general closures. private static void runClosureAtReceive(byte[] args) { try{ if (X10RT.VERBOSE) System.out.println("runClosureAtReceive is called"); java.io.ByteArrayInputStream byteStream = new java.io.ByteArrayInputStream(args); if (X10RT.VERBOSE) System.out.println("runClosureAtReceive: ByteArrayInputStream"); long start = Runtime.PROF_SER ? System.nanoTime() : 0; InputStream objStream = new DataInputStream(byteStream); if (X10RT.VERBOSE) System.out.println("runClosureAtReceive: ObjectInputStream"); X10JavaDeserializer deserializer = new X10JavaDeserializer((DataInputStream) objStream); if (x10.runtime.impl.java.Runtime.TRACE_SER_DETAIL) { System.out.println("Starting deserialization "); } x10.core.fun.VoidFun_0_0 actObj = (x10.core.fun.VoidFun_0_0) deserializer.readRef(); if (Runtime.PROF_SER) { long stop = System.nanoTime(); long duration = stop-start; if (duration >= Runtime.PROF_SER_FILTER) { System.out.println("Deserialization took "+(((double)duration)/1e6)+" ms."); } } if (x10.runtime.impl.java.Runtime.TRACE_SER_DETAIL) { System.out.println("Ending deserialization "); } if (X10RT.VERBOSE) System.out.println("runClosureAtReceive: after cast and deserialization"); actObj.$apply(); if (X10RT.VERBOSE) System.out.println("runClosureAtReceive: after apply"); objStream.close(); if (X10RT.VERBOSE) System.out.println("runClosureAtReceive is done !"); } catch(Exception ex){ System.out.println("runClosureAtReceive error !!!"); ex.printStackTrace(); } } /* * This send/receive pair is used to serialize a simple async * (finish state + async body closure) to * a remote place, which deserializes the two objects and invokes the * async body. * * This is the "normal" case of used to implement a typical X10-level async. */ public static void runSimpleAsyncAtSend(int place, int arraylen, byte[] rawBytes) { sendMessage(place, simpleAsyncMessageID, arraylen, rawBytes); } /** * Receive a simple async */ private static void runSimpleAsyncAtReceive(byte[] args) { try{ if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive is called"); ByteArrayInputStream byteStream = new ByteArrayInputStream(args); if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive: ByteArrayInputStream"); x10.core.fun.VoidFun_0_0 actObj; long start = Runtime.PROF_SER ? System.nanoTime() : 0; InputStream objStream = new DataInputStream(byteStream); if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive: ObjectInputStream"); X10JavaDeserializer deserializer = new X10JavaDeserializer((DataInputStream) objStream); if (x10.runtime.impl.java.Runtime.TRACE_SER_DETAIL) { System.out.println("Starting deserialization "); } FinishState finishState = (FinishState) deserializer.readRef(); actObj = (x10.core.fun.VoidFun_0_0) deserializer.readRef(); if (Runtime.PROF_SER) { long stop = System.nanoTime(); long duration = stop-start; if (duration >= Runtime.PROF_SER_FILTER) { System.out.println("Deserialization took "+(((double)duration)/1e6)+" ms."); } } if (x10.runtime.impl.java.Runtime.TRACE_SER_DETAIL) { System.out.println("Ending deserialization "); } if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive: after cast and deserialization"); x10.lang.Runtime.execute(actObj, finishState); if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive: after apply"); objStream.close(); if (X10RT.VERBOSE) System.out.println("runSimpleAsyncAtReceive is done !"); } catch(Exception ex){ System.out.println("runSimpleAsyncAtReceive error !!!"); ex.printStackTrace(); } } }