Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
further simplifications to ruby: kill useless ProcessFactory (should to the same...
[simgrid.git] / src / bindings / ruby / simgrid.rb
1 require 'simgrid_ruby'
2 include MSG
3 require 'thread'
4
5 $DEBUG = false  # This is a Global Variable Useful for Debugging
6
7 ###########################################################################
8 # Class Semaphore 
9 ###########################################################################
10
11 class Semaphore
12   def initialize(initvalue = 0)
13     @counter = initvalue
14     @waiting_list = []
15   end
16
17   def acquire
18     Thread.critical = true
19     if (@counter -= 1) < 0
20       @waiting_list.push(Thread.current)
21       Thread.stop
22     end
23     self
24   ensure
25     Thread.critical = false
26   end
27
28   def release
29     Thread.critical = true
30     begin
31       if (@counter += 1) <= 0
32   t = @waiting_list.shift
33   t.wakeup if t
34       end
35     rescue ThreadError
36       retry
37     end
38     self
39   ensure
40     Thread.critical = false
41   end
42 end
43
44 ########################################################################
45 # Class Process 
46 ########################################################################
47 class MsgProcess < Thread 
48   @@nextProcessId = 0
49
50 # Attributes
51   attr_reader :bind, :id, :pargs    # Read only
52   attr_accessor :name, :properties  # R/W
53   
54 # Initialize : Used from ApplicationHandler to fill it in
55   def initialize(*args)
56     @schedBegin = Semaphore.new(0)
57     @schedEnd = Semaphore.new(0)    
58     @properties = Hash.new()
59     @id = @@nextProcessId++
60     
61     argc = args.size
62
63     if argc == 0 # Default initializer
64       super() {
65         @id = 0
66         @bind = 0
67         @name = ""
68         @pargs = Array.new()
69         start()
70         if $DEBUG
71                 puts "Init Default Initializer...Nothing to do...Bye"
72         end  
73       }
74        
75     # 2 arguments: (HostName,Name) Or (Host , Name)
76     elsif argc == 2   
77       super(){
78         type = args[0].type()
79         if ( type.to_s == "String")
80           host = Host.getByName(args[0])
81         elsif ( type.to_s == "MSG::Host")
82           host = args[0]
83         else 
84           raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
85         end
86         if $DEBUG
87           puts host
88         end
89         raise "Process name cannot be null" if args[1].empty?
90         @name = args[1] 
91         if $DEBUG
92           puts @name
93         end
94         @pargs = Array.new()    # No Args[] Passed in Arguments
95         start()
96         createProcess(self,host)
97               if $DEBUG
98                 puts "Initilize with 2 args"
99         end
100       }
101        
102     # 3 arguments: (hostName,Name,args[]) or (Host,Name,args[])
103     elsif argc == 3  
104       super(){
105         type = args[0].type()
106         if ( type.to_s == "String")
107           host = Host.getByName(args[0])
108         elsif ( type.to_s == "MSG::Host")
109           host = args[0]
110         else 
111           raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
112         end
113         if $DEBUG
114           puts host
115         end
116       
117         raise "Process name cannot be null" if args[1].empty?
118         @name = args[1]
119         type = args[2].type()
120         raise "Third argument should be an Array" if type != "Array"
121         @pargs = args[3]
122         createProcess(self,host)  
123         
124       if $DEBUG
125         puts "Initilize with 3 args"
126       end      
127            }
128   else 
129     raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc
130   end
131     end
132   
133   # main
134   def msg_main(args) 
135     # To be overriden by childs
136     raise("You must define a msg_main() function in your process, containing the code of this process")
137   end
138      
139   # Start : To keep the process alive and waiting via semaphore
140   def start()
141     @schedBegin.acquire
142     # execute the main code of the process     
143     debug("Begin execution")
144     msg_main(@pargs)
145     processExit(self) # Exit the Native Process
146     @schedEnd.release
147   end
148     
149   def processList()
150     Thread.list.each {|t| p t}
151   end
152   
153   #Get Own ID
154   def getID()
155     return @id
156   end
157   
158   #Get a Process ID
159   def processID(process)
160     return process.id
161   end
162   
163   #Get Own Name
164   def getName()
165     return @name
166   end
167   
168   #Get a Process Name
169   def processName(process)
170     return process.name
171   end
172   
173   #Get Bind
174   def getBind()
175     return @bind
176   end
177   
178   #Get Binds
179   def setBind(bind)
180     @bind = bind
181   end
182     
183   def unschedule()
184     @schedEnd.release
185     @schedBegin.acquire
186   end
187   
188   def schedule()
189     @schedBegin.release
190     @schedEnd.acquire
191   end
192   
193    #C Simualator Process Equivalent  Management
194   # After Binding Ruby Process to C Process
195   
196 #   pause
197   def pause()
198     processSuspend(self)
199   end
200   
201 #   restart
202   def restart()
203     processResume(self)
204   end
205   
206 #   isSuspended
207   def isSuspended()
208     processIsSuspended(self)
209   end
210   
211 #   getHost
212   def getHost()
213     processGetHost(self)
214   end
215   
216 # The Rest of Methods !!! To be Continued ...
217 end
218
219 #########################################################################
220 # Class ApplicationHandler
221 #########################################################################
222 class ApplicationHandler
223   def initialize()
224     @hostName = nil
225     @function = nil
226   end
227   
228   def onBeginProcess(hostName,function)
229     @args = Array.new
230     @properties = Hash.new
231     
232     @hostName = hostName
233     @function = function
234       
235     debug("onBeginProcess("+hostName+","+function+")")
236   end
237
238   def onProperty(id,value)
239     @properties[id] = value
240   end
241   
242   def onProcessArg(arg)
243     @args.push(arg)
244   end
245
246   def onEndProcess()
247     process = rubyNewInstance(@function) 
248     size = @args.size
249     for i in 0..size-1
250       process.pargs.push(@args[i]) 
251     end
252     process.name = @function
253     host = Host.getByName(@hostName)
254     processCreate(process,host)
255     process.properties = @properties
256   end
257 end
258  
259 #########################
260 # Main chunck 
261 #########################
262 MSG.init(ARGV)