Logo AND Algorithmique Numérique Distribuée

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