Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Try to fix the finalization process of ruby simulations. THE REST WORKS, yuhu
[simgrid.git] / src / bindings / ruby / simgrid.rb
index 9d0b847..67c7e1c 100644 (file)
@@ -1,12 +1,45 @@
+# FIXME: add license like in C files
+
 require 'simgrid_ruby'
-include MSG
 require 'thread'
 
-$DEBUG = false  # This is a Global Variable Useful for Debugging
-
 ###########################################################################
 # Class Semaphore 
 ###########################################################################
+class MySemaphore
+   Thread.abort_on_exception = true
+    attr_accessor :permits
+
+   
+  def initialize (permits = 0)
+       @permits = permits
+  end
+  
+  def acquire(mutex,cv)
+
+    raise "Interrupted Thread " if (!Thread.current.alive?)
+    mutex.synchronize {
+    while @permits <= 0
+       
+       cv.wait(mutex)
+       
+    end
+    @permits = @permits - 1
+    cv.signal
+    }
+    
+  end
+    
+  def release(mutex,cv)
+    mutex.synchronize{
+      @permits += 1
+      cv.signal
+      }
+  end  
+end
+#######################################
+# Another Semaphore
+#######################################
 
 class Semaphore
   def initialize(initvalue = 0)
@@ -17,8 +50,11 @@ class Semaphore
   def acquire
     Thread.critical = true
     if (@counter -= 1) < 0
+      MSG::debug(Thread.current.to_s+" acquires "+self.to_s+". That's blocking.")
       @waiting_list.push(Thread.current)
       Thread.stop
+    else
+      MSG::debug(Thread.current.to_s+" acquires "+self.to_s+". It was free.")      
     end
     self
   ensure
@@ -29,8 +65,11 @@ class Semaphore
     Thread.critical = true
     begin
       if (@counter += 1) <= 0
-  t = @waiting_list.shift
-  t.wakeup if t
+        t = @waiting_list.shift
+        t.wakeup if t
+        MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Wakeup "+t.to_s)
+      else 
+        MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Nobody to wakeup")
       end
     rescue ThreadError
       retry
@@ -44,265 +83,168 @@ end
 ########################################################################
 # Class Process 
 ########################################################################
-class MsgProcess < Thread 
+class MSG::Process < Thread 
   @@nextProcessId = 0
 
 # Attributes
-  attr_reader :bind, :id, :pargs    # Read only
-  attr_accessor :name, :properties  # R/W
+  attr_reader :bind, :id, :name, :pargs ,:properties# Read only
   
-# Initialize : Used from ApplicationHandler to fill it in
-  def initialize(*args)
+    def initialize(*args)
+      super(){
+       
+     raise "Bad number of arguments to create a Ruby process. Expected (name,args,prop) " if args.size < 3
+     
+#     @cv = ConditionVariable.new
+#     @mutex = Mutex.new
     @schedBegin = Semaphore.new(0)
     @schedEnd = Semaphore.new(0)    
-    @properties = Hash.new()
-    @id = @@nextProcessId++
-    
-    argc = args.size
-
-    if argc == 0 # Default initializer
-      super() {
-        @id = 0
-        @bind = 0
-        @name = ""
-        @pargs = Array.new()
-        start()
-        if $DEBUG
-               puts "Init Default Initializer...Nothing to do...Bye"
-        end  
-      }
-       
-    # 2 arguments: (HostName,Name) Or (Host , Name)
-    elsif argc == 2   
-      super(){
-        type = args[0].type()
-        if ( type.to_s == "String")
-          host = Host.getByName(args[0])
-        elsif ( type.to_s == "MSG::Host")
-          host = args[0]
-        else 
-          raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
-        end
-        if $DEBUG
-          puts host
-        end
-        raise "Process name cannot be null" if args[1].empty?
-        @name = args[1] 
-        if $DEBUG
-          puts @name
-        end
-        @pargs = Array.new()    # No Args[] Passed in Arguments
-        start()
-        createProcess(self,host)
-             if $DEBUG
-               puts "Initilize with 2 args"
-        end
-      }
-       
-    # 3 arguments: (hostName,Name,args[]) or (Host,Name,args[])
-    elsif argc == 3  
-      super(){
-        type = args[0].type()
-        if ( type.to_s == "String")
-          host = Host.getByName(args[0])
-        elsif ( type.to_s == "MSG::Host")
-          host = args[0]
-        else 
-          raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
-        end
-        if $DEBUG
-          puts host
-        end
+    @id = @@nextProcessId
+    @@nextProcessId +=1
+    @name = args[0]
+    @pargs = args[1]
+    @properties = args[2]
       
-        raise "Process name cannot be null" if args[1].empty?
-        @name = args[1]
-        type = args[2].type()
-        raise "Third argument should be an Array" if type != "Array"
-        @pargs = args[3]
-        createProcess(self,host)  
-        
-      if $DEBUG
-       puts "Initilize with 3 args"
-      end      
-          }
-  else 
-    raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc
-  end
+    start()
+      }
     end
-  
-  # main
-  def msg_main(args) 
+    
+  def main(args) 
     # To be overriden by childs
-    raise("You must define a msg_main() function in your process, containing the code of this process")
+    raise("You must define a main() function in your process, containing the code of this process")
   end
      
-  # Start : To keep the process alive and waiting via semaphore
   def start()
-    @schedBegin.acquire
-    # execute the main code of the process     
-    debug("Begin execution")
-    msg_main(@pargs)
+    @schedBegin.acquire()
+    MSG::debug("Let's execute the main() of the Ruby process")
+    main(@pargs)
+    @schedEnd.release()
+    MSG::debug("Released my schedEnd, bailing out")
     processExit(self) # Exit the Native Process
-    @schedEnd.release
   end
     
-  def processList()
-    Thread.list.each {|t| p t}
-  end
-  
-  #Get Own ID
-  def getID()
-    return @id
-  end
-  
-  #Get a Process ID
-  def processID(process)
-    return process.id
-  end
-  
-  #Get Own Name
-  def getName()
-    return @name
-  end
-  
-  #Get a Process Name
-  def processName(process)
-    return process.name
-  end
-  
-  #Get Bind
+
+  # FIXME: useless, there is an attribute for bind (or the attribute is useless)
+  # Get Bind
   def getBind()
     return @bind
   end
   
-  #Get Binds
+  # Set Binds FIXME: same
   def setBind(bind)
     @bind = bind
   end
     
   def unschedule()
-    @schedEnd.release
-    @schedBegin.acquire
+    @schedEnd.release()
+    @schedBegin.acquire()
   end
   
   def schedule()
-    @schedBegin.release
-    @schedEnd.acquire
+    @schedBegin.release()
+    @schedEnd.acquire()
   end
   
-   #C Simualator Process Equivalent  Management
-  # After Binding Ruby Process to C Process
-  
-#   pause
   def pause()
     processSuspend(self)
   end
   
-#   restart
   def restart()
     processResume(self)
   end
   
-#   isSuspended
   def isSuspended()
     processIsSuspended(self)
   end
   
-#   getHost
   def getHost()
     processGetHost(self)
   end
   
-# The Rest of Methods !!! To be Continued ...
+# The Rest of Methods !!! To be Continued ... FIXME: what's missing?
 end
 
-########################################################################
-# Class ProcessFactory
-########################################################################
-
-class ProcessFactory 
+############################################
+# Task Extend from the native Class RbTask
+############################################
+class MSG::Task < MSG::RbTask
 
-#     Attributes
-   attr_accessor :args, :properties, :hostName, :function
-#    Initialize
-    def initialize()
-    
-    @args = Array.new
-    @properties = Hash.new
-    @hostName = nil
-    @function = nil
-    
-    end
-    
-#     setProcessIdentity
-    def setProcessIdentity(hostName,function)
-      @hostName = hostName
-      @function = function
-      
-      if !args.empty?
-              args.clear
-      end
-      
-      if !properties.empty?
-       properties.clear   
-      end
+  def initialize(*args)
+     super()
+  end
+  
+  def name
+     super(self)
+  end
+  
+  def compSize
+     super(self)
+  end
+  
+  def send(mailbox)
+    super(self,mailbox)
+  end
+  
+#   FIXME : this method should be associated to the class !! it return a task
+# FIXME: simply killing this adapter method should do the trick 
+  def receive(mailbox)
+    super(self,mailbox)
+  end
+  
+  def source
+    super(self)
+  end
+  
+  def sender
+    super(self)
+  end
+  
+  def listen(t_alias)
+    super(t_alias)
+  end
+  
+  def execute
+    super(self)
+  end
     
-    end
-
-    def registerProcessArg(arg)
-      @args.push(arg)
-    end
+  def listenFromHost(t_alias,host)
+    super(t_alias,host)
+  end
+end  
 
-#     CreateProcess
-    def createProcess()
-      process = rubyNewInstance(@function) 
-      size = @args.size
-      for i in 0..size-1
-       process.pargs.push(@args[i]) 
-      end
-      process.name = @function
-      host = Host.getByName(@hostName)
-      processCreate(process,host)
-      process.properties = @properties
-      @properties = Hash.new
-      
-    end
-    
-#     SetProperty
-    def setProperty(id,value)
-      @properties[id] = value
-    end
-end
+############################################
+# Host Extend from the native Class RbHost
+############################################
+class MSG::Host < MSG::RbHost
 
-#########################################################################
-# Class ApplicationHandler
-#########################################################################
-class ApplicationHandler
-  @processFactory  
+  def getByName(name)
+    super(name)
+  end
   
-  def initialize()
-    @processFactory = ProcessFactory.new
+  def name
+    super(self)
   end
   
-  def onBeginProcess(hostName,function)
-    @processFactory.setProcessIdentity(hostName,function)
-    debug("onBeginProcess("+hostName+","+function+")")
+  def speed
+    super(self)
   end
-
-  def onProperty(id,value)
-    @processFactory.setProperty(id,value)
+  
+  def getData
+    super(self)
   end
   
-  def onProcessArg(arg)
-    @processFactory.registerProcessArg(arg)
+  def setData(data)
+    super(self,data)
   end
-
-  def onEndProcess()
-   @processFactory.createProcess()
-   debug("onEndProcess")
+  
+  def isAvail
+    super(self)
+  end
+  
+  def number
+    super()
   end
 end
+
 #########################
 # Main chunck 
 #########################