Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c690faec123c3a6ef4d44c741550599ca81e5540
[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 ouwn process you must inherite 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 exemple, for the previouse 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 automaticaly 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  * @author  Abdelmalek Cherier
47  * @author  Martin Quinson
48  * @since SimGrid 3.3
49  */
50
51 public abstract class Process extends Thread {
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 automaticatly 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 automaticaly 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 properties;
73
74     /**
75      * The name of the process.                                                 
76      */
77   protected String name;
78   public String msgName() {
79     return this.name;
80   }
81   /*
82    * The arguments of the method function of the process.     
83    */ public Vector args;
84
85   /* process synchronisation tools */
86   protected Sem schedBegin, schedEnd;
87
88     /**
89      * Default constructor. (used in ApplicationHandler to initialize it)
90      */
91   protected Process() {
92     super();
93     this.id = 0;
94     this.name = null;
95     this.bind = 0;
96     this.args = new Vector();
97     this.properties = null;
98     schedBegin = new Sem(0);
99     schedEnd = new Sem(0);
100   }
101
102
103     /**
104      * Constructs a new process from the name of a host and his name. The method
105      * function of the process doesn't have argument.
106      *
107      * @param hostName          The name of the host of the process to create.
108      * @param name                      The name of the process.
109      *
110      * @exception                       HostNotFoundException  if no host with this name exists.
111      *                              NullPointerException if the provided name is null
112      *                              JniException on JNI madness
113      *
114      */
115   public Process(String hostname, String name)
116   throws NullPointerException, HostNotFoundException, JniException,
117     NativeException {
118     this(Host.getByName(hostname), name, null);
119   }
120     /**
121      * Constructs a new process from the name of a host and his name. The arguments
122      * of the method function of the process are specified by the parameter args.
123      *
124      * @param hostName          The name of the host of the process to create.
125      * @param name                      The name of the process.
126      * @param args                      The arguments of the main function of the process.
127      *
128      * @exception                       HostNotFoundException  if no host with this name exists.
129      *                              NullPointerException if the provided name is null
130      *                              JniException on JNI madness
131      *
132      */ public Process(String hostname, String name, String args[])
133   throws NullPointerException, HostNotFoundException, JniException,
134     NativeException {
135     this(Host.getByName(hostname), name, args);
136   }
137     /**
138      * Constructs a new process from a host and his name. The method function of the 
139      * process doesn't have argument.
140      *
141      * @param host                      The host of the process to create.
142      * @param name                      The name of the process.
143      *
144      * @exception                       NullPointerException if the provided name is null
145      *                              JniException on JNI madness
146      *
147      */
148     public Process(Host host, String name) throws NullPointerException,
149     JniException {
150     this(host, name, null);
151   }
152     /**
153      * Constructs a new process from a host and his name, the arguments of here method function are
154      * specified by the parameter args.
155      *
156      * @param host                      The host of the process to create.
157      * @param name                      The name of the process.
158      * @param args                      The arguments of main method of the process.
159      *
160      * @exception                   NullPointerException if the provided name is null
161      *                              JniException on JNI madness
162      *
163      */
164     public Process(Host host, String name,
165                      String[]args) throws NullPointerException, JniException {
166     /* This is the constructor called by all others */
167
168     if (name == null)
169       throw new NullPointerException("Process name cannot be NULL");
170
171           this.properties = null;
172           
173       this.args = new Vector();
174
175     if (null != args)
176         this.args.addAll(Arrays.asList(args));
177
178       this.name = name;
179       this.id = nextProcessId++;
180
181       schedBegin = new Sem(0);
182       schedEnd = new Sem(0);
183
184       MsgNative.processCreate(this, host);
185   }
186   
187  
188     /**
189      * This method kills all running process of the simulation.
190      *
191      * @param resetPID          Should we reset the PID numbers. A negative number means no reset
192      *                                          and a positive number will be used to set the PID of the next newly
193      *                                          created process.
194      *
195      * @return                          The function returns the PID of the next created process.
196      *                  
197      */ public static int killAll(int resetPID) {
198     return MsgNative.processKillAll(resetPID);
199   }
200
201     /**
202      * This method adds an argument in the list of the arguments of the main function
203      * of the process. 
204      *
205      * @param arg                       The argument to add.
206      */
207   protected void addArg(String arg) {
208     args.add(arg);
209   }
210
211     /**
212      * This method suspends the process by suspending the task on which it was
213      * waiting for the completion.
214      *
215      * @exception                       JniException on JNI madness
216      *                              NativeException on error in the native SimGrid code
217      */
218   public void pause() throws JniException, NativeException {
219     MsgNative.processSuspend(this);
220   }
221     /**
222      * This method resumes a suspended process by resuming the task on which it was
223      * waiting for the completion.
224      *
225      * @exception                       JniException on JNI madness
226      *                              NativeException on error in the native SimGrid code
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      */ public boolean isSuspended() throws JniException {
239     return MsgNative.processIsSuspended(this);
240   }
241     /**
242      * This method returns the host of a process.
243      *
244      * @return                          The host instance of the process.
245      *
246      * @exception                       JniException on JNI madness
247      *                              NativeException on error in the native SimGrid code
248      *
249      */ public Host getHost() throws JniException, NativeException {
250     return MsgNative.processGetHost(this);
251   }
252     /**
253      * This static method get a process from a PID.
254      *
255      * @param PID                       The process identifier of the process to get.
256      *
257      * @return                          The process with the specified PID.
258      *
259      * @exception                       NativeException on error in the native SimGrid code
260      */ public static Process fromPID(int PID) throws NativeException {
261     return MsgNative.processFromPID(PID);
262   }
263     /**
264      * This method returns the PID of the process.
265      *
266      * @return                          The PID of the process.
267      *
268      * @exception                       JniException on JNI madness
269      *                              NativeException on error in the native SimGrid code
270      */ public int getPID() throws JniException, NativeException {
271     return MsgNative.processGetPID(this);
272   }
273     /**
274      * This method returns the PID of the parent of a process.
275      *
276      * @return                          The PID of the parent of the process.
277      *
278      * @exception                       NativeException on error in the native SimGrid code
279      */ public int getPPID() throws NativeException {
280     return MsgNative.processGetPPID(this);
281   }
282     /**
283      * This static method returns the currently running process.
284      *
285      * @return                          The current process.
286      *
287      * @exception                       NativeException on error in the native SimGrid code
288      *
289      *
290      */ public static Process currentProcess() throws NativeException {
291     return MsgNative.processSelf();
292   }
293     /**
294      * This static method returns the PID of the currently running process.
295      *
296      * @return                          The PID of the current process.         
297      */ public static int currentProcessPID() {
298     return MsgNative.processSelfPID();
299   }
300
301     /**
302      * This static method returns the PID of the parent of the currently running process.
303      *
304      * @return                          The PID of the parent of current process.               
305      */
306   public static int currentProcessPPID() {
307     return MsgNative.processSelfPPID();
308   }
309
310     /**
311      * This function migrates a process to another host.
312      *
313      * @parm host                       The host where to migrate the process.
314      *
315      * @exception                       JniException on JNI madness
316      *                              NativeException on error in the native SimGrid code
317      */
318   public void migrate(Host host) throws JniException, NativeException {
319     MsgNative.processChangeHost(this, host);
320   }
321     /**
322      * This method makes the current process sleep until time seconds have elapsed.
323      *
324      * @param seconds           The time the current process must sleep.
325      *
326      * @exception                       NativeException on error in the native SimGrid code
327      */ public static void waitFor(double seconds) throws NativeException {
328     MsgNative.processWaitFor(seconds);
329   } public void showArgs() {
330     try {
331       Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
332                this.args.size());
333       for (int i = 0; i < this.args.size(); i++)
334         Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
335                  "] args[" + i + "]=" + (String) (this.args.get(i)));
336     } catch(MsgException e) {
337       Msg.info("Damn JNI stuff");
338       e.printStackTrace();
339       System.exit(1);
340     }
341   }
342     /**
343      * This method runs the process. Il calls the method function that you must overwrite.
344      */
345   public synchronized void run() {
346
347       String[]args = null;      /* do not fill it before the signal or this.args will be empty */
348
349       //waitSignal(); /* wait for other people to fill the process in */
350
351
352      try {
353         schedBegin.acquire();
354      } catch(InterruptedException e) {
355      }
356
357
358
359     try {
360       args = new String[this.args.size()];
361       if (this.args.size() > 0) {
362         this.args.toArray(args);
363       }
364
365       this.main(args);
366       MsgNative.processExit(this);
367       schedEnd.release();
368     }
369     catch(MsgException e) {
370       e.printStackTrace();
371       Msg.info("Unexpected behavior. Stopping now");
372       System.exit(1);
373     }
374   }
375
376     /**
377      * The main function of the process (to implement).
378      */
379   public abstract void main(String[]args)
380   throws JniException, NativeException;
381
382
383   public void unschedule() {
384     try {
385       schedEnd.release();
386       schedBegin.acquire();
387     } catch(InterruptedException e) {
388     }
389   }
390
391   public void schedule() {
392     try {
393       schedBegin.release();
394       schedEnd.acquire();
395     } catch(InterruptedException e) {
396     }
397   }
398   
399   /** Send the given task to given host on given channel */
400   public void taskPut(Host host, int channel,
401                        Task task) throws NativeException, JniException {
402     MsgNative.hostPut(host, channel, task, -1);
403   }
404   
405    /** Send the given task to given host on given channel (waiting at most given time)*/
406    public void taskPut(Host host, int channel,
407                        Task task, double timeout) throws NativeException, JniException {
408     MsgNative.hostPut(host, channel, task, timeout);
409   }
410    /** Receive a task on given channel */
411     public Task taskGet(int channel) throws NativeException,
412     JniException {
413     return MsgNative.taskGet(channel, -1, null);
414   }
415    /** Receive a task on given channel (waiting at most given time) */
416     public Task taskGet(int channel,
417                             double timeout) throws NativeException,
418     JniException {
419     return MsgNative.taskGet(channel, timeout, null);
420   }
421    /** Receive a task on given channel from given sender */
422     public Task taskGet(int channel, Host host) throws NativeException,
423     JniException {
424     return MsgNative.taskGet(channel, -1, host);
425   }
426    /** Receive a task on given channel from given sender (waiting at most given time) */
427     public Task taskGet(int channel, double timeout,
428                             Host host) throws NativeException, JniException {
429     return MsgNative.taskGet(channel, timeout, host);
430   }
431   
432   /** Send the given task in the mailbox associated with the specified alias  (waiting at most given time) */
433   public void taskSend(String alias,
434                        Task task, double timeout) throws NativeException, JniException {
435     MsgNative.taskSend(alias, task, timeout);
436   }
437   
438   /** Send the given task in the mailbox associated with the specified alias*/
439   public void taskSend(String alias,
440                        Task task) throws NativeException, JniException {
441     MsgNative.taskSend(alias, task, -1);
442   }
443   
444   /** Send the given task in the mailbox associated with the default alias  (defaultAlias = "hostName:processName") */
445   public void taskSend(Task task) throws NativeException, JniException {
446         
447         String alias = Host.currentHost().getName() + ":" + this.msgName();
448     MsgNative.taskSend(alias, task, -1);
449   }
450   
451   /** Send the given task in the mailbox associated with the default alias (waiting at most given time) */
452   public void taskSend(Task task, double timeout) throws NativeException, JniException {
453         
454         String alias = Host.currentHost().getName() + ":" + this.msgName();
455     MsgNative.taskSend(alias, task, timeout);
456   }
457   
458   
459    /** Receive a task on mailbox associated with the specified alias */
460     public Task taskReceive(String alias) throws NativeException,
461     JniException {
462     return MsgNative.taskReceive(alias, -1.0, null);
463   }
464   
465   /** Receive a task on mailbox associated with the default alias */
466    public Task taskReceive() throws NativeException,
467     JniException {
468     String alias = Host.currentHost().getName() + ":" + this.msgName();
469     return MsgNative.taskReceive(alias, -1.0, null);
470   }
471   
472   /** Receive a task on mailbox associated with the specified alias (waiting at most given time) */
473     public Task taskReceive(String alias,
474                             double timeout) throws NativeException,
475     JniException {
476     return MsgNative.taskReceive(alias, timeout, null);
477   }
478   
479   /** Receive a task on mailbox associated with the default alias (waiting at most given time) */
480    public Task taskReceive(double timeout) throws NativeException,
481     JniException {
482     String alias = Host.currentHost().getName() + ":" + this.msgName();
483     return MsgNative.taskReceive(alias, timeout, null);
484   }
485   
486    /** Receive a task on mailbox associated with the specified alias from given sender */
487     public Task taskReceive(String alias,
488                             double timeout, Host host) throws NativeException,
489     JniException {
490     return MsgNative.taskReceive(alias, timeout, host);
491   }
492   
493   /** Receive a task on mailbox associated with the default alias from given sender  (waiting at most given time) */
494   public Task taskReceive(double timeout, Host host) throws NativeException,
495     JniException {
496     String alias = Host.currentHost().getName() + ":" + this.msgName();
497     return MsgNative.taskReceive(alias, timeout, host);
498   }
499   
500    /** Receive a task on mailbox associated with the specified alias from given sender*/
501      public Task taskReceive(String alias,
502                             Host host) throws NativeException,
503     JniException {
504     return MsgNative.taskReceive(alias, -1.0, host);
505   }
506    /** Receive a task on mailbox associated with the default alias from given sender */
507    public Task taskReceive( Host host) throws NativeException,
508     JniException {
509         String alias = Host.currentHost().getName() + ":" + this.msgName();
510     return MsgNative.taskReceive(alias, -1.0, host);
511   }
512 }