Logo AND Algorithmique Numérique Distribuée

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