Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
9d0b84789833c647049ef231bfc23ec33a923b8e
[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 ProcessFactory
221 ########################################################################
222
223 class ProcessFactory 
224
225 #     Attributes
226    attr_accessor :args, :properties, :hostName, :function
227 #    Initialize
228     def initialize()
229     
230     @args = Array.new
231     @properties = Hash.new
232     @hostName = nil
233     @function = nil
234     
235     end
236     
237 #     setProcessIdentity
238     def setProcessIdentity(hostName,function)
239       @hostName = hostName
240       @function = function
241       
242       if !args.empty?
243                args.clear
244       end
245       
246       if !properties.empty?
247         properties.clear   
248       end
249     
250     end
251
252     def registerProcessArg(arg)
253       @args.push(arg)
254     end
255
256 #     CreateProcess
257     def createProcess()
258       process = rubyNewInstance(@function) 
259       size = @args.size
260       for i in 0..size-1
261         process.pargs.push(@args[i]) 
262       end
263       process.name = @function
264       host = Host.getByName(@hostName)
265       processCreate(process,host)
266       process.properties = @properties
267       @properties = Hash.new
268       
269     end
270     
271 #     SetProperty
272     def setProperty(id,value)
273       @properties[id] = value
274     end
275 end
276
277 #########################################################################
278 # Class ApplicationHandler
279 #########################################################################
280 class ApplicationHandler
281   @processFactory  
282   
283   def initialize()
284     @processFactory = ProcessFactory.new
285   end
286   
287   def onBeginProcess(hostName,function)
288     @processFactory.setProcessIdentity(hostName,function)
289     debug("onBeginProcess("+hostName+","+function+")")
290   end
291
292   def onProperty(id,value)
293     @processFactory.setProperty(id,value)
294   end
295   
296   def onProcessArg(arg)
297     @processFactory.registerProcessArg(arg)
298   end
299
300   def onEndProcess()
301    @processFactory.createProcess()
302    debug("onEndProcess")
303   end
304 end
305  
306 #########################
307 # Main chunck 
308 #########################
309 MSG.init(ARGV)