Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
dc50455e7cd92901c7de653f891e5690a7a4aaab
[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         /**
60          * Even if this attribute is public you must never access to it.
61          * It is used to compute the id of an MSG process.
62          */
63         public static long nextProcessId = 0;
64
65         /**
66          * Even if this attribute is public you must never access to it.
67          * It is compute automatically during the creation of the object. 
68          * The native functions use this identifier to synchronize the process.
69          */
70         public long id;
71
72     public Hashtable<String,String> properties;
73
74         /**
75          * The name of the process.                                                     
76          */
77         protected String name;
78         /**
79           * The PID of the process
80           */
81         protected int pid = -1;
82         /**
83          * The PPID of the process 
84          */
85         protected int ppid = -1;
86         /**
87          * The host of the process
88          */
89         protected Host host = null;
90
91         /** The arguments of the method function of the process. */     
92         public Vector<String> args;
93
94         /* process synchronization tools */
95         
96     private boolean nativeStop = false;
97
98         /**
99          * Default constructor (used in ApplicationHandler to initialize it)
100          */
101         protected Process() {
102                 this.id = nextProcessId++;
103                 this.name = null;
104                 this.bind = 0;
105                 this.args = new Vector<String>();
106                 this.properties = null;
107         }
108
109
110         /**
111          * Constructs a new process from the name of a host and his name. The method
112          * function of the process doesn't have argument.
113          *
114          * @param hostname              The name of the host of the process to create.
115          * @param name                  The name of the process.
116          *
117          * @exception                   HostNotFoundException  if no host with this name exists.
118          *                      
119          *
120          */
121         public Process(String hostname, String name) throws HostNotFoundException {
122                 this(Host.getByName(hostname), name, null);
123         }
124         /**
125          * Constructs a new process from the name of a host and his name. The arguments
126          * of the method function of the process are specified by the parameter args.
127          *
128          * @param hostname              The name of the host of the process to create.
129          * @param name                  The name of the process.
130          * @param args                  The arguments of the main function of the process.
131          *
132          * @exception                   HostNotFoundException  if no host with this name exists.
133      *                      NativeException
134      * @throws NativeException
135          *
136          */ 
137         public Process(String hostname, String name, String args[]) throws HostNotFoundException, NativeException {
138                 this(Host.getByName(hostname), name, args);
139         }
140         /**
141          * Constructs a new process from a host and his name. The method function of the 
142          * process doesn't have argument.
143          *
144          * @param host                  The host of the process to create.
145          * @param name                  The name of the process.
146          *
147          */
148         public Process(Host host, String name) {
149                 this(host, name, null);
150         }
151         /**
152          * Constructs a new process from a host and his name, the arguments of here method function are
153          * specified by the parameter args.
154          *
155          * @param host                  The host of the process to create.
156          * @param name                  The name of the process.
157          * @param args                  The arguments of main method of the process.
158          *
159          */
160         public Process(Host host, String name, String[]args) {
161                 /* This is the constructor called by all others */
162                 this();
163                 this.host = host;
164                 if (name == null)
165                         throw new NullPointerException("Process name cannot be NULL");
166                 this.name = name;
167
168                 this.args = new Vector<String>();
169                 if (null != args)
170                         this.args.addAll(Arrays.asList(args));
171                 
172                 this.properties = new Hashtable<String,String>();
173                 
174         }
175         /**
176          * The natively implemented method to create an MSG process.
177          * @param host    A valid (binded) host where create the process.
178          */
179         protected native void create(String hostName) throws HostNotFoundException;
180         /**
181          * This method kills all running process of the simulation.
182          *
183          * @param resetPID              Should we reset the PID numbers. A negative number means no reset
184          *                                              and a positive number will be used to set the PID of the next newly
185          *                                              created process.
186          *
187          * @return                              The function returns the PID of the next created process.
188          *                      
189          */ 
190         public static native int killAll(int resetPID);
191         /**
192          * This method sets a flag to indicate that this thread must be killed. End user must use static method kill
193          *
194          * @return                              
195          *                      
196          */ 
197         public void nativeStop() {
198                 nativeStop = true;
199         }
200         /**
201          * getter for the flag that indicates that this thread must be killed
202          *
203          * @return                              
204          *                      
205          */ 
206         public boolean getNativeStop() {
207                 return nativeStop;
208         }
209
210         /**
211          * This method kill a process.
212          * @param process  the process to be killed.
213          *
214          */
215         public void kill() {
216                  nativeStop();
217                  Msg.info("Process " + msgName() + " will be killed.");                                                  
218         }
219
220         /**
221          * Suspends the process by suspending the task on which it was
222          * waiting for the completion.
223          *
224          */
225         public native void pause();
226         /**
227          * Resumes a suspended process by resuming the task on which it was
228          * waiting for the completion.
229          *
230          *
231          */ 
232         public native void restart();
233         /**
234          * Tests if a process is suspended.
235          *
236          * @return                              The method returns true if the process is suspended.
237          *                                              Otherwise the method returns false.
238          */ 
239         public native boolean isSuspended();
240         /**
241          * Returns the name of the process
242          */
243         public String msgName() {
244                 return this.name;
245         }
246         /**
247          * Returns the host of the process.
248          * @return                              The host instance of the process.
249          */ 
250         public Host getHost() {
251                 return this.host;
252         }
253         /**
254          * This static method gets a process from a PID.
255          *
256          * @param PID                   The process identifier of the process to get.
257          *
258          * @return                              The process with the specified PID.
259          *
260          * @exception                   NativeException on error in the native SimGrid code
261          */ 
262         public static native Process fromPID(int PID) throws NativeException;
263         /**
264          * This method returns the PID of the process.
265          *
266          * @return                              The PID of the process.
267          *
268          */ 
269         public int getPID()  {
270                 return pid;
271         }
272         /**
273          * This method returns the PID of the parent of a process.
274          *
275          * @return                              The PID of the parent of the process.
276          *
277          */ 
278         public int getPPID()  {
279                 return ppid;
280         }
281         /**
282          * This static method returns the currently running process.
283          *
284          * @return                              The current process.
285          *
286          */ 
287         public static native Process currentProcess();
288         /**
289          * Kills a MSG process
290          * @param process Valid java process to kill
291          */
292         final static native void kill(Process process); 
293         /**
294          * Migrates a process to another host.
295          *
296          * @param process               The process to migrate.
297          * @param host                  The host where to migrate the process.
298          *
299          */
300         public native static void migrate(Process process, Host host);  
301         /**
302          * Makes the current process sleep until millis millisecondes have elapsed.
303          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds.
304          * FIXME: Not optimal, maybe we should have two native functions.
305          * @param millis the length of time to sleep in milliseconds.
306          */
307         public static void sleep(long millis)  {
308                 sleep(millis,0);
309         }
310         /**
311          * Makes the current process sleep until millis milliseconds and nanos nanoseconds 
312          * have elapsed.
313          * You should note that unlike "waitFor" which takes seconds, this method takes milliseconds and nanoseconds.
314          * Overloads Thread.sleep.
315          * @param millis the length of time to sleep in milliseconds.
316          * @param nanos additionnal nanoseconds to sleep.
317          */
318         public native static void sleep(long millis, int nanos);
319         /**
320          * Makes the current process sleep until time seconds have elapsed.
321          * @param seconds               The time the current process must sleep.
322          */ 
323         public native void waitFor(double seconds);    
324         /**
325      *
326      */
327     public void showArgs() {
328                 Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
329                                 this.args.size());
330                 for (int i = 0; i < this.args.size(); i++)
331                         Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
332                                         "] args[" + i + "]=" + (String) (this.args.get(i)));
333         }
334     /**
335      * This method actually creates and run the process.
336      * @throws HostNotFoundException
337      */
338     public void start() throws HostNotFoundException {
339         create(host.getName());
340     }
341     
342         /**
343          * This method runs the process. Il calls the method function that you must overwrite.
344          */
345         public void run() {
346
347                 String[] args = null;      /* do not fill it before the signal or this.args will be empty */
348                 //waitSignal(); /* wait for other people to fill the process in */
349
350                 try {
351                         args = new String[this.args.size()];
352                         if (this.args.size() > 0) {
353                                 this.args.toArray(args);
354                         }
355
356                         this.main(args);
357                 } catch(MsgException e) {
358                         e.printStackTrace();
359                         Msg.info("Unexpected behavior. Stopping now");
360                         System.exit(1);
361                 }
362                  catch(ProcessKilled pk) {
363                         if (nativeStop) {
364
365                         }
366                         else {
367                                 pk.printStackTrace();
368                                 Msg.info("Unexpected behavior. Stopping now");
369                                 System.exit(1);
370                         }
371                 }       
372         }
373
374         /**
375          * The main function of the process (to implement).
376      *
377      * @param args
378      * @throws MsgException
379      */
380         public abstract void main(String[]args) throws MsgException;
381
382     
383         /**
384          * Class initializer, to initialize various JNI stuff
385          */
386         public static native void nativeInit();
387         static {
388                 nativeInit();
389         }
390 }