Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Renamed basic example to "masterslave" (more accurate)
[simgrid.git] / org / simgrid / msg / Process.java
1 /*
2  * $Id$
3  *
4  * Copyright 2006,2007 Martin Quinson, Malek Cherier           
5  * All right reserved. 
6  *
7  * This program is free software; you can redistribute 
8  * it and/or modify it under the terms of the license 
9  *(GNU LGPL) which comes with this package. 
10  */
11
12 package org.simgrid.msg;
13  
14 import java.util.Arrays;
15 import java.util.Hashtable;
16 import java.util.Vector;
17 import java.lang.Runnable;
18 import java.util.concurrent.Semaphore;
19
20 /**
21  * A process may be defined as a code, with some private data, executing 
22  * in a location (host). All the process used by your simulation must be
23  * declared in the deployment file (XML format).
24  * To create your own process you must inherit your own process from this 
25  * class and override the method "main()". For example if you want to use 
26  * a process named Slave proceed as it :
27  *
28  * (1) import the class Process of the package simgrid.msg
29  * import simgrid.msg.Process;
30  * 
31  * public class Slave extends simgrid.msg.Process {
32  *
33  *  (2) Override the method function
34  * 
35  *  \verbatim
36  *      public void main(String[] args) {
37  *              System.out.println("Hello MSG");
38  *      }
39  *  \endverbatim
40  * }
41  * The name of your process must be declared in the deployment file of your simulation.
42  * For the example, for the previous process Slave this file must contains a line :
43  * <process host="Maxims" function="Slave"/>, where Maxims is the host of the process
44  * Slave. All the process of your simulation are automatically launched and managed by Msg.
45  * A process use tasks to simulate communications or computations with another process. 
46  * For more information see Task. For more information on host concept 
47  * see Host.
48  * 
49  */
50
51 public abstract class Process implements Runnable {
52         /**
53          * This attribute represents a bind between a java process object and
54          * a native process. Even if this attribute is public you must never
55          * access to it. It is set automatically during the build of the object.
56          */
57         public long bind;
58         /**
59          * Indicates if the process is started
60          */
61         boolean started;
62         /**
63          * Even if this attribute is public you must never access to it.
64          * It is used to compute the id of an MSG process.
65          */
66         public static long nextProcessId = 0;
67         
68         /**
69          * Even if this attribute is public you must never access to it.
70          * It is compute automatically during the creation of the object. 
71          * The native functions use this identifier to synchronize the process.
72          */
73         public long id;
74         
75         /**
76          * Start time of the process
77          */
78         public double startTime = 0;
79         /**
80          * Kill time of the process
81          */
82         public double killTime = -1;
83
84     public Hashtable<String,String> properties;
85
86         /**
87          * The name of the process.                                                     
88          */
89         protected String name;
90         /**
91           * The PID of the process
92           */
93         protected int pid = -1;
94         /**
95          * The PPID of the process 
96          */
97         protected int ppid = -1;
98         /**
99          * The host of the process
100          */
101         protected Host host = null;
102
103         /** The arguments of the method function of the process. */     
104         public Vector<String> args;
105
106         
107         /**
108          * Default constructor (used in ApplicationHandler to initialize it)
109          */
110         protected Process() {
111                 this.id = nextProcessId++;
112                 this.name = null;
113                 this.bind = 0;
114                 this.args = new Vector<String>();
115                 this.properties = null;
116         }
117
118
119         /**
120          * Constructs a new process from the name of a host and his name. The method
121          * function of the process doesn't have argument.
122          *
123          * @param hostname              The name of the host of the process to create.
124          * @param name                  The name of the process.
125          *
126          * @exception                   HostNotFoundException  if no host with this name exists.
127          *                      
128          *
129          */
130         public Process(String hostname, String name) throws HostNotFoundException {
131                 this(Host.getByName(hostname), name, null);
132         }
133         /**
134          * Constructs a new process from the name of a host and his name. The arguments
135          * of the method function of the process are specified by the parameter args.
136          *
137          * @param hostname              The name of the host of the process to create.
138          * @param name                  The name of the process.
139          * @param args                  The arguments of the main function of the process.
140          *
141          * @exception                   HostNotFoundException  if no host with this name exists.
142      *                      NativeException
143      * @throws NativeException
144          *
145          */ 
146         public Process(String hostname, String name, String args[]) throws HostNotFoundException, NativeException {
147                 this(Host.getByName(hostname), name, args);
148         }
149         /**
150          * Constructs a new process from a host and his name. The method function of the 
151          * process doesn't have argument.
152          *
153          * @param host                  The host of the process to create.
154          * @param name                  The name of the process.
155          *
156          */
157         public Process(Host host, String name) {
158                 this(host, name, null);
159         }
160         /**
161          * Constructs a new process from a host and his name, the arguments of here method function are
162          * specified by the parameter args.
163          *
164          * @param host                  The host of the process to create.
165          * @param name                  The name of the process.
166          * @param args                  The arguments of main method of the process.
167          */     
168         public Process(Host host, String name, String[]args) {
169                 this();
170                 this.host = host;
171                 if (name == null)
172                         throw new NullPointerException("Process name cannot be NULL");
173                 this.name = name;
174
175                 this.args = new Vector<String>();
176                 if (null != args)
177                         this.args.addAll(Arrays.asList(args));
178                 
179                 this.properties = new Hashtable<String,String>();
180         }       
181         /**
182          * Constructs a new process from a host and his name, the arguments of here method function are
183          * specified by the parameter args.
184          *
185          * @param host                  The host of the process to create.
186          * @param name                  The name of the process.
187          * @param args                  The arguments of main method of the process.
188          * @param startTime             Start time of the process
189          * @param killTime              Kill time of the process
190          *
191          */
192         public Process(Host host, String name, String[]args, double startTime, double killTime) {
193                 this();
194                 this.host = host;
195                 if (name == null)
196                         throw new NullPointerException("Process name cannot be NULL");
197                 this.name = name;
198
199                 this.args = new Vector<String>();
200                 if (null != args)
201                         this.args.addAll(Arrays.asList(args));
202                 
203                 this.properties = new Hashtable<String,String>();
204                 
205                 this.startTime = startTime;
206                 this.killTime = killTime;               
207         }
208         /**
209          * The natively implemented method to create an MSG process.
210          * @param host    A valid (binded) host where create the process.
211          */
212         protected native void create(String hostName) throws HostNotFoundException;
213         /**
214          * This method kills all running process of the simulation.
215          *
216          * @param resetPID              Should we reset the PID numbers. A negative number means no reset
217          *                                              and a positive number will be used to set the PID of the next newly
218          *                                              created process.
219          *
220          * @return                              The function returns the PID of the next created process.
221          *                      
222          */ 
223         public static native int killAll(int resetPID);
224
225         /**
226          * This method kill a process.
227          *
228          */
229         public native void kill();
230         /**
231          * Suspends the process by suspending the task on which it was
232          * waiting for the completion.
233          *
234          */
235         public native void pause();
236         /**
237          * Resumes a suspended process by resuming the task on which it was
238          * waiting for the completion.
239          *
240          *
241          */ 
242         public native void restart();
243         /**
244          * Tests if a process is suspended.
245          *
246          * @return                              The method returns true if the process is suspended.
247          *                                              Otherwise the method returns false.
248          */ 
249         public native boolean isSuspended();
250         /**
251          * Returns the name of the process
252          */
253         public String msgName() {
254                 return this.name;
255         }
256         /**
257          * Returns the host of the process.
258          * @return                              The host instance of the process.
259          */ 
260         public Host getHost() {
261                 return this.host;
262         }
263         /**
264          * This static method gets a process from a PID.
265          *
266          * @param PID                   The process identifier of the process to get.
267          *
268          * @return                              The process with the specified PID.
269          *
270          * @exception                   NativeException on error in the native SimGrid code
271          */ 
272         public static native Process fromPID(int PID) throws NativeException;
273         /**
274          * This method returns the PID of the process.
275          *
276          * @return                              The PID of the process.
277          *
278          */ 
279         public int getPID()  {
280                 return pid;
281         }
282         /**
283          * This method returns the PID of the parent of a process.
284          *
285          * @return                              The PID of the parent of the process.
286          *
287          */ 
288         public int getPPID()  {
289                 return ppid;
290         }
291         /**
292          * Set the kill time of the process
293          * @param killTime the time when the process is killed
294          */
295         public native void setKillTime(double killTime);
296         
297         /**
298          * This static method returns the currently running process.
299          *
300          * @return                              The current process.
301          *
302          */ 
303         public static native Process currentProcess();
304         /**
305          * Migrates a process to another host.
306          *
307          * @param process               The process to migrate.
308          * @param host                  The host where to migrate the process.
309          *
310          */
311         public native void migrate(Host host);  
312         /**
313          * Makes the current process sleep until millis millisecondes have elapsed.
314          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds.
315          * FIXME: Not optimal, maybe we should have two native functions.
316          * @param millis the length of time to sleep in milliseconds.
317          */
318         public static void sleep(long millis) throws HostFailureException  {
319                 sleep(millis,0);
320         }
321         /**
322          * Makes the current process sleep until millis milliseconds and nanos nanoseconds 
323          * have elapsed.
324          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds and nanoseconds.
325          * Overloads Thread.sleep.
326          * @param millis the length of time to sleep in milliseconds.
327          * @param nanos additionnal nanoseconds to sleep.
328          */
329         public native static void sleep(long millis, int nanos) throws HostFailureException;
330         /**
331          * Makes the current process sleep until time seconds have elapsed.
332          * @param seconds               The time the current process must sleep.
333          */ 
334         public native void waitFor(double seconds) throws HostFailureException;    
335         /**
336      *
337      */
338     public void showArgs() {
339                 Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
340                                 this.args.size());
341                 for (int i = 0; i < this.args.size(); i++)
342                         Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
343                                         "] args[" + i + "]=" + (String) (this.args.get(i)));
344         }
345     /**
346      * This method actually creates and run the process.
347      * It is a noop if the process is already launched.
348      * @throws HostNotFoundException
349      */
350     public final void start() throws HostNotFoundException {
351         if (!started) {
352                 started = true;
353                 create(host.getName());
354         }
355     }
356     
357         /**
358          * This method runs the process. Il calls the method function that you must overwrite.
359          */
360         public void run() {
361
362                 String[] args = null;      /* do not fill it before the signal or this.args will be empty */
363                 //waitSignal(); /* wait for other people to fill the process in */
364
365                 try {
366                         args = new String[this.args.size()];
367                         if (this.args.size() > 0) {
368                                 this.args.toArray(args);
369                         }
370
371                         this.main(args);
372                 } catch(MsgException e) {
373                         e.printStackTrace();
374                         Msg.info("Unexpected behavior. Stopping now");
375                         System.exit(1);
376                 }
377                  catch(ProcessKilledError pk) {
378                          
379                  }      
380         }
381
382         /**
383          * The main function of the process (to implement).
384      *
385      * @param args
386      * @throws MsgException
387      */
388         public abstract void main(String[]args) throws MsgException;
389
390     
391         /**
392          * Class initializer, to initialize various JNI stuff
393          */
394         public static native void nativeInit();
395         static {
396                 nativeInit();
397         }
398 }