Logo AND Algorithmique Numérique Distribuée

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