Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
ea1f275735c741338c04129985870e5ac0466cb3
[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;
79         /**
80          * Kill time of the process
81          */
82         public double killTime;
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, 0, -1);
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, 0, -1);
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, 0, -1);
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          * @param startTime             Start time of the process
168          * @param killTime              Kill time of the process
169          *
170          */
171         public Process(Host host, String name, String[]args, double startTime, double killTime) {
172                 /* This is the constructor called by all others */
173                 this();
174                 this.host = host;
175                 if (name == null)
176                         throw new NullPointerException("Process name cannot be NULL");
177                 this.name = name;
178
179                 this.args = new Vector<String>();
180                 if (null != args)
181                         this.args.addAll(Arrays.asList(args));
182                 
183                 this.properties = new Hashtable<String,String>();
184                 
185                 this.startTime = startTime;
186                 this.killTime = killTime;               
187         }
188         /**
189          * The natively implemented method to create an MSG process.
190          * @param host    A valid (binded) host where create the process.
191          */
192         protected native void create(String hostName, double startTime, double killTime) throws HostNotFoundException;
193         /**
194          * This method kills all running process of the simulation.
195          *
196          * @param resetPID              Should we reset the PID numbers. A negative number means no reset
197          *                                              and a positive number will be used to set the PID of the next newly
198          *                                              created process.
199          *
200          * @return                              The function returns the PID of the next created process.
201          *                      
202          */ 
203         public static native int killAll(int resetPID);
204
205         /**
206          * This method kill a process.
207          * @param process  the process to be killed.
208          *
209          */
210         public native void kill();
211         /**
212          * Suspends the process by suspending the task on which it was
213          * waiting for the completion.
214          *
215          */
216         public native void pause();
217         /**
218          * Resumes a suspended process by resuming the task on which it was
219          * waiting for the completion.
220          *
221          *
222          */ 
223         public native void restart();
224         /**
225          * Tests if a process is suspended.
226          *
227          * @return                              The method returns true if the process is suspended.
228          *                                              Otherwise the method returns false.
229          */ 
230         public native boolean isSuspended();
231         /**
232          * Returns the name of the process
233          */
234         public String msgName() {
235                 return this.name;
236         }
237         /**
238          * Returns the host of the process.
239          * @return                              The host instance of the process.
240          */ 
241         public Host getHost() {
242                 return this.host;
243         }
244         /**
245          * This static method gets a process from a PID.
246          *
247          * @param PID                   The process identifier of the process to get.
248          *
249          * @return                              The process with the specified PID.
250          *
251          * @exception                   NativeException on error in the native SimGrid code
252          */ 
253         public static native Process fromPID(int PID) throws NativeException;
254         /**
255          * This method returns the PID of the process.
256          *
257          * @return                              The PID of the process.
258          *
259          */ 
260         public int getPID()  {
261                 return pid;
262         }
263         /**
264          * This method returns the PID of the parent of a process.
265          *
266          * @return                              The PID of the parent of the process.
267          *
268          */ 
269         public int getPPID()  {
270                 return ppid;
271         }
272         /**
273          * This static method returns the currently running process.
274          *
275          * @return                              The current process.
276          *
277          */ 
278         public static native Process currentProcess();
279         /**
280          * Migrates a process to another host.
281          *
282          * @param process               The process to migrate.
283          * @param host                  The host where to migrate the process.
284          *
285          */
286         public native static void migrate(Process process, Host host);  
287         /**
288          * Makes the current process sleep until millis millisecondes have elapsed.
289          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds.
290          * FIXME: Not optimal, maybe we should have two native functions.
291          * @param millis the length of time to sleep in milliseconds.
292          */
293         public static void sleep(long millis)  {
294                 sleep(millis,0);
295         }
296         /**
297          * Makes the current process sleep until millis milliseconds and nanos nanoseconds 
298          * have elapsed.
299          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds and nanoseconds.
300          * Overloads Thread.sleep.
301          * @param millis the length of time to sleep in milliseconds.
302          * @param nanos additionnal nanoseconds to sleep.
303          */
304         public native static void sleep(long millis, int nanos);
305         /**
306          * Makes the current process sleep until time seconds have elapsed.
307          * @param seconds               The time the current process must sleep.
308          */ 
309         public native void waitFor(double seconds);    
310         /**
311      *
312      */
313     public void showArgs() {
314                 Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
315                                 this.args.size());
316                 for (int i = 0; i < this.args.size(); i++)
317                         Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
318                                         "] args[" + i + "]=" + (String) (this.args.get(i)));
319         }
320     /**
321      * This method actually creates and run the process.
322      * It is a noop if the process is already launched.
323      * @throws HostNotFoundException
324      */
325     public final void start() throws HostNotFoundException {
326         if (!started) {
327                 started = true;
328                 create(host.getName(), startTime, killTime);
329         }
330     }
331     
332         /**
333          * This method runs the process. Il calls the method function that you must overwrite.
334          */
335         public void run() {
336
337                 String[] args = null;      /* do not fill it before the signal or this.args will be empty */
338                 //waitSignal(); /* wait for other people to fill the process in */
339
340                 try {
341                         args = new String[this.args.size()];
342                         if (this.args.size() > 0) {
343                                 this.args.toArray(args);
344                         }
345
346                         this.main(args);
347                 } catch(MsgException e) {
348                         e.printStackTrace();
349                         Msg.info("Unexpected behavior. Stopping now");
350                         System.exit(1);
351                 }
352                  catch(ProcessKilledError pk) {
353                          
354                  }      
355         }
356
357         /**
358          * The main function of the process (to implement).
359      *
360      * @param args
361      * @throws MsgException
362      */
363         public abstract void main(String[]args) throws MsgException;
364
365     
366         /**
367          * Class initializer, to initialize various JNI stuff
368          */
369         public static native void nativeInit();
370         static {
371                 nativeInit();
372         }
373 }