Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
e173b1d2791d7e39dc7154af483080a49419d9ec
[simgrid.git] / src / java / 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 simgrid.msg;
13
14 import java.lang.Thread;
15 import java.util.*;
16
17 /**
18  * A process may be defined as a code, with some private data, executing 
19  * in a location (host). All the process used by your simulation must be
20  * declared in the deployment file (XML format).
21  * To create your own process you must inherit your own process from this 
22  * class and override the method "main()". For example if you want to use 
23  * a process named Slave proceed as it :
24  *
25  * (1) import the class Process of the package simgrid.msg
26  * import simgrid.msg.Process;
27  * 
28  * public class Slave extends simgrid.msg.Process {
29  *
30  *  (2) Override the method function
31  * 
32  *  \verbatim
33  *      public void main(String[] args) {
34  *              System.out.println("Hello MSG");
35  *      }
36  *  \endverbatim
37  * }
38  * The name of your process must be declared in the deployment file of your simulation.
39  * For the example, for the previous process Slave this file must contains a line :
40  * <process host="Maxims" function="Slave"/>, where Maxims is the host of the process
41  * Slave. All the process of your simulation are automatically launched and managed by Msg.
42  * A process use tasks to simulate communications or computations with another process. 
43  * For more information see Task. For more information on host concept 
44  * see Host.
45  * 
46  */
47
48 public abstract class Process extends Thread {
49         /**
50          * This attribute represents a bind between a java process object and
51          * a native process. Even if this attribute is public you must never
52          * access to it. It is set automatically during the build of the object.
53          */
54         public long bind;
55
56         /**
57          * Even if this attribute is public you must never access to it.
58          * It is used to compute the id of an MSG process.
59          */
60         public static long nextProcessId = 0;
61
62         /**
63          * Even if this attribute is public you must never access to it.
64          * It is compute automatically during the creation of the object. 
65          * The native functions use this identifier to synchronize the process.
66          */
67         public long id;
68
69         public Hashtable<String,String> properties;
70
71         /**
72          * The name of the process.                                                     
73          */
74         protected String name;
75         public String msgName() {
76                 return this.name;
77         }
78         /** The arguments of the method function of the process. */     
79         public Vector<String> args;
80
81         /* process synchronization tools */
82         protected Sem schedBegin, schedEnd;
83
84         /**
85          * Default constructor (used in ApplicationHandler to initialize it)
86          */
87         protected Process() {
88                 super();
89                 this.id = 0;
90                 this.name = null;
91                 this.bind = 0;
92                 this.args = new Vector<String>();
93                 this.properties = null;
94                 schedBegin = new Sem(0);
95                 schedEnd = new Sem(0);
96         }
97
98
99         /**
100          * Constructs a new process from the name of a host and his name. The method
101          * function of the process doesn't have argument.
102          *
103          * @param hostname              The name of the host of the process to create.
104          * @param name                  The name of the process.
105          *
106          * @exception                   HostNotFoundException  if no host with this name exists.
107          *                      NullPointerException if the provided name is null
108          *                      JniException on JNI madness
109          *                      NativeException
110          *
111          */
112         public Process(String hostname, String name)
113         throws NullPointerException, HostNotFoundException, JniException,
114         NativeException {
115                 this(Host.getByName(hostname), name, null);
116         }
117         /**
118          * Constructs a new process from the name of a host and his name. The arguments
119          * of the method function of the process are specified by the parameter args.
120          *
121          * @param hostname              The name of the host of the process to create.
122          * @param name                  The name of the process.
123          * @param args                  The arguments of the main function of the process.
124          *
125          * @exception                   HostNotFoundException  if no host with this name exists.
126          *                              NullPointerException if the provided name is null
127          *                              JniException on JNI madness
128          *
129          */ 
130         public Process(String hostname, String name, String args[])
131         throws NullPointerException, HostNotFoundException, JniException,
132         NativeException {
133                 this(Host.getByName(hostname), name, args);
134         }
135         /**
136          * Constructs a new process from a host and his name. The method function of the 
137          * process doesn't have argument.
138          *
139          * @param host                  The host of the process to create.
140          * @param name                  The name of the process.
141          *
142          * @exception                   NullPointerException if the provided name is null
143          *                              JniException on JNI madness
144          *
145          */
146         public Process(Host host, String name) throws NullPointerException,
147         JniException {
148                 this(host, name, null);
149         }
150         /**
151          * Constructs a new process from a host and his name, the arguments of here method function are
152          * specified by the parameter args.
153          *
154          * @param host                  The host of the process to create.
155          * @param name                  The name of the process.
156          * @param args                  The arguments of main method of the process.
157          *
158          * @exception               NullPointerException if the provided name is null
159          *                              JniException on JNI madness
160          *
161          */
162         public Process(Host host, String name,
163                         String[]args) throws NullPointerException, JniException {
164                 /* This is the constructor called by all others */
165
166                 if (name == null)
167                         throw new NullPointerException("Process name cannot be NULL");
168
169                 this.properties = null;
170
171                 this.args = new Vector<String>();
172
173                 if (null != args)
174                         this.args.addAll(Arrays.asList(args));
175
176                 this.name = name;
177                 this.id = nextProcessId++;
178
179                 schedBegin = new Sem(0);
180                 schedEnd = new Sem(0);
181
182                 MsgNative.processCreate(this, host);
183         }
184
185
186         /**
187          * This method kills all running process of the simulation.
188          *
189          * @param resetPID              Should we reset the PID numbers. A negative number means no reset
190          *                                              and a positive number will be used to set the PID of the next newly
191          *                                              created process.
192          *
193          * @return                              The function returns the PID of the next created process.
194          *                      
195          */ 
196         public static int killAll(int resetPID) {
197                 return MsgNative.processKillAll(resetPID);
198         }
199
200         /**
201          * This method adds an argument in the list of the arguments of the main function
202          * of the process. 
203          *
204          * @param arg                   The argument to add.
205          */
206         protected void addArg(String arg) {
207                 args.add(arg);
208         }
209
210         /**
211          * This method suspends the process by suspending the task on which it was
212          * waiting for the completion.
213          *
214          * @exception                   JniException on JNI madness
215          *                              NativeException on error in the native SimGrid code
216          */
217         public void pause() throws JniException, NativeException {
218                 MsgNative.processSuspend(this);
219         }
220         /**
221          * This method resumes a suspended process by resuming the task on which it was
222          * waiting for the completion.
223          *
224          * @exception                   JniException on JNI madness
225          *                              NativeException on error in the native SimGrid code
226          *
227          */ 
228         public void restart() throws JniException, NativeException {
229                 MsgNative.processResume(this);
230         }
231         /**
232          * This method tests if a process is suspended.
233          *
234          * @return                              The method returns true if the process is suspended.
235          *                                              Otherwise the method returns false.
236          *
237          * @exception                   JniException on JNI madness
238          */ 
239         public boolean isSuspended() throws JniException {
240                 return MsgNative.processIsSuspended(this);
241         }
242         /**
243          * This method returns the host of a process.
244          *
245          * @return                              The host instance of the process.
246          *
247          * @exception                   JniException on JNI madness
248          *                              NativeException on error in the native SimGrid code
249          *
250          */ 
251         public Host getHost() throws JniException, NativeException {
252                 return MsgNative.processGetHost(this);
253         }
254         /**
255          * This static method get a process from a PID.
256          *
257          * @param PID                   The process identifier of the process to get.
258          *
259          * @return                              The process with the specified PID.
260          *
261          * @exception                   NativeException on error in the native SimGrid code
262          */ 
263         public static Process fromPID(int PID) throws NativeException {
264                 return MsgNative.processFromPID(PID);
265         }
266         /**
267          * This method returns the PID of the process.
268          *
269          * @return                              The PID of the process.
270          *
271          * @exception                   JniException on JNI madness
272          *                              NativeException on error in the native SimGrid code
273          */ 
274         public int getPID() throws JniException, NativeException {
275                 return MsgNative.processGetPID(this);
276         }
277         /**
278          * This method returns the PID of the parent of a process.
279          *
280          * @return                              The PID of the parent of the process.
281          *
282          * @exception                   NativeException on error in the native SimGrid code
283          */ 
284         public int getPPID() throws NativeException {
285                 return MsgNative.processGetPPID(this);
286         }
287         /**
288          * This static method returns the currently running process.
289          *
290          * @return                              The current process.
291          *
292          * @exception                   NativeException on error in the native SimGrid code
293          *
294          *
295          */ 
296         public static Process currentProcess() throws NativeException {
297                 return MsgNative.processSelf();
298         }
299         /**
300          * This static method returns the PID of the currently running process.
301          *
302          * @return                              The PID of the current process.         
303          */ 
304         public static int currentProcessPID() {
305                 return MsgNative.processSelfPID();
306         }
307
308         /**
309          * This static method returns the PID of the parent of the currently running process.
310          *
311          * @return                              The PID of the parent of current process.               
312          */
313         public static int currentProcessPPID() {
314                 return MsgNative.processSelfPPID();
315         }
316
317         /**
318          * This function migrates a process to another host.
319          *
320          * @param host                  The host where to migrate the process.
321          *
322          * @exception                   JniException on JNI madness
323          *                              NativeException on error in the native SimGrid code
324          */
325         public void migrate(Host host) throws JniException, NativeException {
326                 MsgNative.processChangeHost(this, host);
327         }
328         /**
329          * This method makes the current process sleep until time seconds have elapsed.
330          *
331          * @param seconds               The time the current process must sleep.
332          *
333          * @exception                   NativeException on error in the native SimGrid code
334          */ 
335         public static void waitFor(double seconds) throws NativeException {
336                 MsgNative.processWaitFor(seconds);
337         } 
338         public void showArgs() {
339                 try {
340                         Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
341                                         this.args.size());
342                         for (int i = 0; i < this.args.size(); i++)
343                                 Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
344                                                 "] args[" + i + "]=" + (String) (this.args.get(i)));
345                 } catch(MsgException e) {
346                         Msg.info("Damn JNI stuff");
347                         e.printStackTrace();
348                         System.exit(1);
349                 }
350         }
351         /**
352          * This method runs the process. Il calls the method function that you must overwrite.
353          */
354         public void run() {
355
356                 String[]args = null;      /* do not fill it before the signal or this.args will be empty */
357
358                 //waitSignal(); /* wait for other people to fill the process in */
359
360
361                 try {
362                         schedBegin.acquire();
363                 } catch(InterruptedException e) {
364                 }
365
366                 try {
367                         args = new String[this.args.size()];
368                         if (this.args.size() > 0) {
369                                 this.args.toArray(args);
370                         }
371
372                         this.main(args);
373                         MsgNative.processExit(this);
374                         schedEnd.release();
375                 } catch(MsgException e) {
376                         e.printStackTrace();
377                         Msg.info("Unexpected behavior. Stopping now");
378                         System.exit(1);
379                 }
380         }
381
382         /**
383          * The main function of the process (to implement).
384          */
385         public abstract void main(String[]args) throws JniException, NativeException;
386
387
388         public void unschedule() {
389                 try {
390                         schedEnd.release();
391                         schedBegin.acquire();
392                 } catch(InterruptedException e) {
393                 }
394         }
395
396         public void schedule() {
397                 try {
398                         schedBegin.release();
399                         schedEnd.acquire();
400                 } catch(InterruptedException e) {
401                 }
402         }
403
404         /** Send the given task in the mailbox associated with the specified alias  (waiting at most given time) */
405         public void taskSend(String mailbox, Task task, double timeout) throws NativeException, JniException {
406                 MsgNative.taskSend(mailbox, task, timeout);
407         }
408
409         /** Send the given task in the mailbox associated with the specified alias*/
410         public void taskSend(String mailbox, Task task) throws NativeException, JniException {
411                 MsgNative.taskSend(mailbox, task, -1);
412         }
413
414         /** Receive a task on mailbox associated with the specified mailbox */
415         public Task taskReceive(String mailbox) throws NativeException, JniException {
416                 return MsgNative.taskReceive(mailbox, -1.0, null);
417         }
418
419         /** Receive a task on mailbox associated with the specified alias (waiting at most given time) */
420         public Task taskReceive(String mailbox, double timeout) throws NativeException, JniException {
421                 return MsgNative.taskReceive(mailbox, timeout, null);
422         }
423
424         /** Receive a task on mailbox associated with the specified alias from given sender */
425         public Task taskReceive(String mailbox, double timeout, Host host) throws NativeException, JniException {
426                 return MsgNative.taskReceive(mailbox, timeout, host);
427         }
428
429         /** Receive a task on mailbox associated with the specified alias from given sender*/
430         public Task taskReceive(String mailbox, Host host) throws NativeException, JniException {
431                 return MsgNative.taskReceive(mailbox, -1.0, host);
432         }
433 }