Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Massive cleanups in ruby. Not yet working (segfault on task reception)
[simgrid.git] / src / bindings / ruby / simgrid.rb
1 require 'simgrid_ruby'
2 include MSG
3 require 'thread'
4
5 $DEBUG = true  # This is a Global Variable Useful for Debugging
6
7 ###########################################################################
8 # Class Semaphore 
9 ###########################################################################
10 class Semaphore 
11   Thread.abort_on_exception = true
12   attr_accessor :permits
13  
14   def initialize ( permits )
15        @permits = permits
16   end
17    
18
19   def acquire(mutex,cv)
20     raise "Interrupted Thread " if (!Thread.current.alive?)
21     mutex.synchronize {
22       while @permits <= 0 
23         cv.wait(mutex)       
24       end
25     
26       @permits = @permits - 1
27       cv.signal    
28     }    
29   end
30     
31   def release(mutex,cv)
32     mutex.synchronize{
33       @permits += 1
34       cv.signal
35     }
36   end
37 end
38
39 ########################################################################
40 # Class RbProcess 
41 ########################################################################
42 class RbProcess < Thread 
43   @@nextProcessId = 0
44 # Attributes
45   attr_accessor :bind, :id, :properties, :name,
46       :pargs, :schedBegin, :schedEnd, :mutex, :cv
47   
48 # Initialize : Used from ApplicationHandler to fill it in
49   def initialize(*args)
50     
51     argc = args.size
52
53     if argc == 0 # Default initializer
54       super() {
55         @id = 0
56         @bind = 0
57         @name = ""
58         @pargs = Array.new()
59         init_var()
60         start()
61         if $DEBUG
62                 puts "Init Default Initializer...Nothing to do...Bye"
63         end  
64       }
65        
66     # 2 arguments: (HostName,Name) Or (Host , Name)
67     elsif argc == 2   
68       super(){
69         type = args[0].type()
70         if ( type.to_s == "String")
71           host = Host.getByName(args[0])
72         elsif ( type.to_s == "MSG::Host")
73           host = args[0]
74         else 
75           raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
76         end
77         if $DEBUG
78           puts host
79         end
80         raise "Process name cannot be null" if args[1].empty?
81         @name = args[1] 
82         if $DEBUG
83           puts @name
84         end
85         @pargs = Array.new()    # No Args[] Passed in Arguments
86         @@nextProcessId += 1
87         @id = @@nextProcessId
88         init_var()
89         start()
90         createProcess(self,host)
91               if $DEBUG
92                 puts "Initilize with 2 args"
93         end
94       }
95        
96     # 3 arguments: (hostName,Name,args[]) or (Host,Name,args[])
97     elsif argc == 3  
98       super(){
99         type = args[0].type()
100         if ( type.to_s == "String")
101           host = Host.getByName(args[0])
102         elsif ( type.to_s == "MSG::Host")
103           host = args[0]
104         else 
105           raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
106         end
107         if $DEBUG
108           puts host
109         end
110       
111         raise "Process name cannot be null" if args[1].empty?
112         @name = args[1]
113         type = args[2].type()
114         raise "Third argument should be an Array" if type != "Array"
115         @pargs = args[3]
116         @@nextProcessId +=1
117         @id = @@nextProcessId
118         init_var()
119         createProcess(self,host)  
120         
121       if $DEBUG
122         puts "Initilize with 3 args"
123       end
124       
125 #       sleep #keep the thread running
126            }
127   else 
128     raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc
129   end
130     end
131
132   # Init_var Called By Initialize  
133   def init_var()  
134     @proprieties = Hash.new()
135     @mutex = Mutex.new
136     @cv = ConditionVariable.new
137     # Process Synchronization Tools
138     @schedBegin = Semaphore.new(0)
139     @schedEnd = Semaphore.new(0)    
140   end
141   
142   #main
143   def msg_main(args)
144     # To Be Implemented within The Process...
145     # The Main Code of The Process to be Executed ...
146   end
147      
148   # Start : To keep the Process Alive and waitin' via semaphore
149   def start()
150     @schedBegin.acquire(@mutex,@cv)
151     #execute The Main Code of The Process ( Example Master ; Slave ...)     
152     msg_main(@pargs)
153     processExit(self) #Exite the Native Process
154     @schedEnd.release(@mutex,@cv)
155   end
156     
157 #   NetxId
158   def nextId ()
159     @@nextProcessId +=1
160     return @@nextProcessId
161   end
162
163   if $DEBUG
164     #Process List
165     def processList()
166       Thread.list.each {|t| p t}
167     end
168   end
169   
170   #Get Own ID
171   def getID()
172     return @id
173   end
174   
175   # set Id
176   def setID(id)
177     @id = id
178   end
179   
180   #Get a Process ID
181   def processID(process)
182     return process.id
183   end
184   
185   #Get Own Name
186   def getName()
187     return @name
188   end
189   
190   #Get a Process Name
191   def processName(process)
192     return process.name
193   end
194   
195   #Get Bind
196   def getBind()
197     return @bind
198   end
199   
200   #Get Binds
201   def setBind(bind)
202     @bind = bind
203   end
204     
205   def unschedule() 
206     
207     @schedEnd.release(@mutex,@cv)
208 #     info("@schedEnd.release(@mutex,@cv)")
209     @schedBegin.acquire(@mutex,@cv)
210 #     info("@schedBegin.acquire(@mutex,@cv)")
211      
212   end
213   
214   def schedule()
215     @schedBegin.release(@mutex,@cv)
216     @schedEnd.acquire(@mutex,@cv)
217   end
218   
219    #C Simualateur Process Equivalent  Management
220   # After Binding Ruby Process to C Process
221   
222 #   pause
223   def pause()
224     processSuspend(self)
225   end
226   
227 #   restart
228   def restart()
229     processResume(self)
230   end
231   
232 #   isSuspended
233   def isSuspended()
234     processIsSuspended(self)
235   end
236   
237 #   getHost
238   def getHost()
239     processGetHost(self)
240   end
241   
242 # The Rest of Methods !!! To be Continued ...
243 end
244
245 ########################################################################
246 # Class ProcessFactory
247 ########################################################################
248
249 class ProcessFactory 
250
251 #     Attributes
252    attr_accessor :args, :proprieties, :hostName, :function
253 #    Initlialize
254     def initialize()
255     
256     @args = Array.new
257     @proprieties = Hash.new
258     @hostName = nil
259     @function = nil
260     
261     end
262     
263 #     setProcessIdentity
264     def setProcessIdentity(hostName,function)
265       @hostName = hostName
266       @function = function
267       
268       if !args.empty?
269         args.clear
270       end
271       
272       if !proprieties.empty?
273         proprieties.clear   
274       end
275     
276     end
277
278 #     RegisterProcess  
279     def registerProcessArg(arg)
280       
281       @args.push(arg)
282       
283     end
284
285 #     CreateProcess
286     def createProcess()
287       
288       process = rubyNewInstance(@function) # process = rubyNewInstanceArgs(@function,@args) #
289       size = @args.size
290       for i in 0..size-1
291         process.pargs.push(@args[i]) 
292       end
293       process.name = @function
294       process.id = process.nextId() # This increment Automaticaly  The Static ProcessNextId for The Class RbProces
295       host = RbHost.getByName(@hostName)
296       processCreate(process,host)
297       process.properties = @properties
298       @proprieties = Hash.new
299       
300     end
301     
302 #     SetProperty
303     def setProperty(id,value)
304       @proprieties[id] = value
305     end
306 end
307
308 #########################################################################
309 # Class ApplicationHandler
310 #########################################################################
311 class ApplicationHandler
312   @processFactory  
313 #   Initialize
314   def initialize()
315      #Nothing todo
316   end
317   
318     #  onStartDocument
319   def onStartDocument()
320     
321     @processFactory = ProcessFactory.new
322     if ($DEBUG)
323       puts "onStartDocument"
324     end
325       
326   end
327   
328 #   onBeginProcess
329   def onBeginProcess(hostName,function)
330     
331     @processFactory.setProcessIdentity(hostName,function)
332     
333      if ($DEBUG)
334       puts "onBeginProcess"
335      end
336     
337   end
338
339 #   onProperty
340     def onProperty(id,value)
341     
342     @processFactory.setProperty(id,value)
343     
344      if ($DEBUG)
345       puts "onProperty"
346      end
347     
348   end
349   
350 #   RegisterProcessArg
351     def onProcessArg(arg)
352     
353     @processFactory.registerProcessArg(arg)
354       
355       if ($DEBUG)
356       puts "onProcessArg"
357       end
358     
359   end
360
361 #   OnEndProcess
362    def onEndProcess()
363    
364    @processFactory.createProcess()
365    
366    if ($DEBUG)
367       puts "onEndProcess"
368    end
369       
370  end
371
372  #  onEndDocument
373   def onEndDocument()  
374 #    Erm... Actually nothing to do !!
375    
376    if($DEBUG)
377    puts "onEndDocument"
378    end
379  end
380  
381  #  End Class
382  end
383  
384 #########################
385 # Class RbHost 
386 #########################
387
388 class RbHost < Host
389 # Attributes
390   attr_accessor :bind, :data 
391   
392 # Initialize
393   def initialize()
394     super()
395     @bind = 0
396     @data = nil
397   end
398   
399 end
400
401 #########################
402 # Class RbTask 
403 #########################
404 class RbTask < Task  
405   attr_accessor :bind 
406   
407   def initialize(name,comp_size,comm_size)
408     super(name,comp_size,comm_size)
409   end
410
411 end
412  
413 #########################
414 # Main chunck 
415 #########################
416 MSG.init(ARGV)