Logo AND Algorithmique Numérique Distribuée

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