Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c678e6576fd9463303bdedccf192ce1d94530659
[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     /**
73      * The name of the process.                                                 
74      */
75   protected String name;
76   public String msgName() {
77     return this.name;
78   }
79   /*
80    * The arguments of the method function of the process.     
81    */ public Vector args;
82
83   /* process synchronisation tools */
84   protected Sem schedBegin, schedEnd;
85
86     /**
87      * Default constructor. (used in ApplicationHandler to initialize it)
88      */
89   protected Process() {
90     super();
91     this.id = 0;
92     this.name = null;
93     this.bind = 0;
94     this.args = new Vector();
95     schedBegin = new Sem(0);
96     schedEnd = new Sem(0);
97   }
98
99
100     /**
101      * Constructs a new process from the name of a host and his name. The method
102      * function of the process doesn't have argument.
103      *
104      * @param hostName          The name of the host of the process to create.
105      * @param name                      The name of the process.
106      *
107      * @exception                       HostNotFoundException  if no host with this name exists.
108      *                              NullPointerException if the provided name is null
109      *                              JniException on JNI madness
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      */ public Process(String hostname, String name, String args[])
130   throws NullPointerException, HostNotFoundException, JniException,
131     NativeException {
132     this(Host.getByName(hostname), name, args);
133   }
134     /**
135      * Constructs a new process from a host and his name. The method function of the 
136      * process doesn't have argument.
137      *
138      * @param host                      The host of the process to create.
139      * @param name                      The name of the process.
140      *
141      * @exception                       NullPointerException if the provided name is null
142      *                              JniException on JNI madness
143      *
144      */
145     public Process(Host host, String name) throws NullPointerException,
146     JniException {
147     this(host, name, null);
148   }
149     /**
150      * Constructs a new process from a host and his name, the arguments of here method function are
151      * specified by the parameter args.
152      *
153      * @param host                      The host of the process to create.
154      * @param name                      The name of the process.
155      * @param args                      The arguments of main method of the process.
156      *
157      * @exception                   NullPointerException if the provided name is null
158      *                              JniException on JNI madness
159      *
160      */
161     public Process(Host host, String name,
162                      String[]args) throws NullPointerException, JniException {
163     /* This is the constructor called by all others */
164
165     if (name == null)
166       throw new NullPointerException("Process name cannot be NULL");
167
168
169       this.args = new Vector();
170
171     if (null != args)
172         this.args.addAll(Arrays.asList(args));
173
174       this.name = name;
175       this.id = nextProcessId++;
176
177       schedBegin = new Sem(0);
178       schedEnd = new Sem(0);
179
180       MsgNative.processCreate(this, host);
181   }
182     /**
183      * This method kills all running process of the simulation.
184      *
185      * @param resetPID          Should we reset the PID numbers. A negative number means no reset
186      *                                          and a positive number will be used to set the PID of the next newly
187      *                                          created process.
188      *
189      * @return                          The function returns the PID of the next created process.
190      *                  
191      */ public static int killAll(int resetPID) {
192     return MsgNative.processKillAll(resetPID);
193   }
194
195     /**
196      * This method adds an argument in the list of the arguments of the main function
197      * of the process. 
198      *
199      * @param arg                       The argument to add.
200      */
201   protected void addArg(String arg) {
202     args.add(arg);
203   }
204
205     /**
206      * This method suspends the process by suspending the task on which it was
207      * waiting for the completion.
208      *
209      * @exception                       JniException on JNI madness
210      *                              NativeException on error in the native SimGrid code
211      */
212   public void pause() throws JniException, NativeException {
213     MsgNative.processSuspend(this);
214   }
215     /**
216      * This method resumes a suspended process by resuming the task on which it was
217      * waiting for the completion.
218      *
219      * @exception                       JniException on JNI madness
220      *                              NativeException on error in the native SimGrid code
221      *
222      */ public void restart() throws JniException, NativeException {
223     MsgNative.processResume(this);
224   }
225     /**
226      * This method tests if a process is suspended.
227      *
228      * @return                          The method returns true if the process is suspended.
229      *                                          Otherwise the method returns false.
230      *
231      * @exception                       JniException on JNI madness
232      */ public boolean isSuspended() throws JniException {
233     return MsgNative.processIsSuspended(this);
234   }
235     /**
236      * This method returns the host of a process.
237      *
238      * @return                          The host instance of the process.
239      *
240      * @exception                       JniException on JNI madness
241      *                              NativeException on error in the native SimGrid code
242      *
243      */ public Host getHost() throws JniException, NativeException {
244     return MsgNative.processGetHost(this);
245   }
246     /**
247      * This static method get a process from a PID.
248      *
249      * @param PID                       The process identifier of the process to get.
250      *
251      * @return                          The process with the specified PID.
252      *
253      * @exception                       NativeException on error in the native SimGrid code
254      */ public static Process fromPID(int PID) throws NativeException {
255     return MsgNative.processFromPID(PID);
256   }
257     /**
258      * This method returns the PID of the process.
259      *
260      * @return                          The PID of the process.
261      *
262      * @exception                       JniException on JNI madness
263      *                              NativeException on error in the native SimGrid code
264      */ public int getPID() throws JniException, NativeException {
265     return MsgNative.processGetPID(this);
266   }
267     /**
268      * This method returns the PID of the parent of a process.
269      *
270      * @return                          The PID of the parent of the process.
271      *
272      * @exception                       NativeException on error in the native SimGrid code
273      */ public int getPPID() throws NativeException {
274     return MsgNative.processGetPPID(this);
275   }
276     /**
277      * This static method returns the currently running process.
278      *
279      * @return                          The current process.
280      *
281      * @exception                       NativeException on error in the native SimGrid code
282      *
283      *
284      */ public static Process currentProcess() throws NativeException {
285     return MsgNative.processSelf();
286   }
287     /**
288      * This static method returns the PID of the currently running process.
289      *
290      * @return                          The PID of the current process.         
291      */ public static int currentProcessPID() {
292     return MsgNative.processSelfPID();
293   }
294
295     /**
296      * This static method returns the PID of the parent of the currently running process.
297      *
298      * @return                          The PID of the parent of current process.               
299      */
300   public static int currentProcessPPID() {
301     return MsgNative.processSelfPPID();
302   }
303
304     /**
305      * This function migrates a process to another host.
306      *
307      * @parm host                       The host where to migrate the process.
308      *
309      * @exception                       JniException on JNI madness
310      *                              NativeException on error in the native SimGrid code
311      */
312   public void migrate(Host host) throws JniException, NativeException {
313     MsgNative.processChangeHost(this, host);
314   }
315     /**
316      * This method makes the current process sleep until time seconds have elapsed.
317      *
318      * @param seconds           The time the current process must sleep.
319      *
320      * @exception                       NativeException on error in the native SimGrid code
321      */ public static void waitFor(double seconds) throws NativeException {
322     MsgNative.processWaitFor(seconds);
323   } public void showArgs() {
324     try {
325       Msg.info("[" + this.name + "/" + this.getHost().getName() + "] argc=" +
326                this.args.size());
327       for (int i = 0; i < this.args.size(); i++)
328         Msg.info("[" + this.msgName() + "/" + this.getHost().getName() +
329                  "] args[" + i + "]=" + (String) (this.args.get(i)));
330     } catch(MsgException e) {
331       Msg.info("Damn JNI stuff");
332       e.printStackTrace();
333       System.exit(1);
334     }
335   }
336     /**
337      * This method runs the process. Il calls the method function that you must overwrite.
338      */
339   public synchronized void run() {
340
341     try {
342       String[]args = null;      /* do not fill it before the signal or this.args will be empty */
343
344       //waitSignal(); /* wait for other people to fill the process in */
345
346
347       try {
348         schedBegin.acquire();
349       } catch(InterruptedException e) {
350       }
351
352
353
354       if (this.args.size() > 0) {
355
356         args = new String[this.args.size()];
357         this.args.toArray(args);
358       }
359
360       this.main(args);
361       MsgNative.processExit(this);
362       schedEnd.release();
363     }
364     catch(MsgException e) {
365       e.printStackTrace();
366       Msg.info("Unexpected behavior. Stopping now");
367       System.exit(1);
368     }
369   }
370
371     /**
372      * The main function of the process (to implement).
373      */
374   public abstract void main(String[]args)
375   throws JniException, NativeException;
376
377
378   public void unschedule() {
379     try {
380       schedEnd.release();
381       schedBegin.acquire();
382     } catch(InterruptedException e) {
383     }
384   }
385
386   public void schedule() {
387     try {
388       schedBegin.release();
389       schedEnd.acquire();
390     } catch(InterruptedException e) {
391     }
392   }
393
394
395    /** Send the given task to given host on given channel */
396   public void taskSend(Host host, int channel,
397                        Task task) throws NativeException, JniException {
398     MsgNative.hostPut(host, channel, task, -1);
399   }
400    /** Receive a task on given channel */
401     public Task taskReceive(int channel) throws NativeException,
402     JniException {
403     return MsgNative.taskGet(channel, -1, null);
404   }
405    /** Receive a task on given channel (waiting at most given time) */
406     public Task taskReceive(int channel,
407                             double timeout) throws NativeException,
408     JniException {
409     return MsgNative.taskGet(channel, timeout, null);
410   }
411    /** Receive a task on given channel from given sender */
412     public Task taskReceive(int channel, Host host) throws NativeException,
413     JniException {
414     return MsgNative.taskGet(channel, -1, host);
415   }
416    /** Receive a task on given channel from given sender (waiting at most given time) */
417     public Task taskReceive(int channel, double timeout,
418                             Host host) throws NativeException, JniException {
419     return MsgNative.taskGet(channel, timeout, host);
420   }
421 }