Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
eea2fa917324085338dc93aba854aaa38a5ea6bc
[simgrid.git] / src / bindings / ruby / simgrid.rb
1 #  Task-related bindings to ruby  */
2
3 #  Copyright 2010. The SimGrid Team. All right reserved. */
4
5 # This program is free software; you can redistribute it and/or modify it
6 #  under the terms of the license (GNU LGPL) which comes with this package. */
7 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 
8 require 'simgrid_ruby'
9 require 'thread'
10
11 ##########################################################
12 # Class Semaphore 
13 ##########################################################
14 class MySemaphore
15    Thread.abort_on_exception = true
16     attr_accessor :permits
17
18   def initialize (permits = 0)
19        @permits = permits
20   end
21   
22   def acquire(mutex,cv)
23
24     raise "Interrupted Thread " if (!Thread.current.alive?)
25     mutex.synchronize {
26     while @permits <= 0
27        
28        cv.wait(mutex)
29        
30     end
31     @permits = @permits - 1
32     cv.signal
33     }
34     
35   end
36     
37   def release(mutex,cv)
38     mutex.synchronize{
39       @permits += 1
40       cv.signal
41       }
42   end  
43 end
44 #######################################
45 # Another Semaphore
46 #######################################
47
48 class Semaphore
49   def initialize(initvalue = 0)
50     @counter = initvalue
51     @waiting_list = []
52   end
53
54   def acquire
55     Thread.critical = true
56     if (@counter -= 1) < 0
57       MSG::debug(Thread.current.to_s+" acquires "+self.to_s+". That's blocking.")
58       @waiting_list.push(Thread.current)
59       Thread.stop
60     else
61       MSG::debug(Thread.current.to_s+" acquires "+self.to_s+". It was free.")      
62     end
63     self
64   ensure
65     Thread.critical = false
66   end
67
68   def release
69     Thread.critical = true
70     begin
71       if (@counter += 1) <= 0
72         t = @waiting_list.shift
73         t.wakeup if t
74         MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Wakeup "+t.to_s)
75       else 
76         MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Nobody to wakeup")
77       end
78     rescue ThreadError
79       retry
80     end
81     self
82   ensure
83     Thread.critical = false
84   end
85 end
86
87 ########################################################################
88 # Class Process 
89 ########################################################################
90 class MSG::Process < Thread 
91   @@nextProcessId = 0
92
93 # Attributes
94   attr_reader :name, :pargs ,:properties, :cv, :mutex   # Read only
95   
96     def initialize(*args)
97       super(){
98         
99      raise "Bad number of arguments to create a Ruby process. Expected (name,args,prop) " if args.size < 3
100      
101     @cv = ConditionVariable.new
102     @mutex = Mutex.new
103     @schedBegin = MySemaphore.new(0)
104     @schedEnd = MySemaphore.new(0)    
105     @id = @@nextProcessId
106     @@nextProcessId +=1
107     @name = args[0]
108     @pargs = args[1]
109     @properties = args[2]
110       
111     start()
112       }
113     end
114     
115   def main(args) 
116     # To be overriden by childs
117     raise("You must define a main() function in your process, containing the code of this process")
118   end
119      
120   def start()
121      @schedBegin.acquire(@mutex,@cv)
122
123     MSG::debug("Let's execute the main() of the Ruby process")
124     main(@pargs)
125 <<<<<<< .mine
126 #     processExit(self) # FIXME : Fix the simix_context_ruby_stop to stop context process before quitting
127     @schedEnd.release(@mutex,@cv)
128     
129 =======
130     @schedEnd.release()
131 >>>>>>> .r7205
132     MSG::debug("Released my schedEnd, bailing out")
133     processExit(self) # Exit the Native Process
134   end
135     
136   def getBind()
137     return @bind
138   end
139    
140   def setBind(bind)
141     @bind = bind
142   end
143     
144   def unschedule()
145     @schedEnd.release(@mutex,@cv)
146     @schedBegin.acquire(@mutex,@cv)
147   end
148   
149   def schedule()   
150     @schedBegin.release(@mutex,@cv)
151     @schedEnd.acquire(@mutex,@cv)
152   end
153   
154   def pause()
155     processSuspend(self)
156   end
157   
158   def restart()
159     processResume(self)
160   end
161   
162   def isSuspended()
163     processIsSuspended(self)
164   end
165   
166   def getHost()
167     processGetHost(self)
168   end
169   
170 # The Rest of Methods !!! To be Continued ... FIXME: what's missing?
171 end
172
173 ############################################
174 # Task Extend from the native Class RbTask
175 ############################################
176 class MSG::Task < MSG::RbTask
177
178   def initialize(*args)
179      super()
180   end
181   
182   def name
183      super(self)
184   end
185   
186   def compSize
187      super(self)
188   end
189   
190   def send(mailbox)
191     super(self,mailbox)
192   end
193   
194
195   def source
196     super(self)
197   end
198   
199   def sender
200     super(self)
201   end
202   
203   def listen(t_alias)
204     super(t_alias)
205   end
206   
207   def execute
208     super(self)
209   end
210     
211   def listenFromHost(t_alias,host)
212     super(t_alias,host)
213   end
214 end  
215
216 ####################################################
217 # Host Extend from the native Class RbHost
218 ####################################################
219 class MSG::Host < MSG::RbHost
220
221   def getByName(name)
222     super(name)
223   end
224   
225   def name
226     super(self)
227   end
228   
229   def speed
230     super(self)
231   end
232   
233   def getData
234     super(self)
235   end
236   
237   def setData(data)
238     super(self,data)
239   end
240   
241   def isAvail
242     super(self)
243   end
244   
245   def number
246     super()
247   end
248 end
249
250 #########################
251 # Main chunck 
252 #########################
253 MSG.init(ARGV)