X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/b3d9680ac65d8bdd8e267aed69fc32a5abab12d7..51f5efedb7e873fa0c82bdc8bb0aa78ae3e827c7:/src/bindings/ruby/simgrid.rb diff --git a/src/bindings/ruby/simgrid.rb b/src/bindings/ruby/simgrid.rb index 90b8793591..2cfeacf13c 100644 --- a/src/bindings/ruby/simgrid.rb +++ b/src/bindings/ruby/simgrid.rb @@ -1,52 +1,67 @@ require 'simgrid_ruby' -include MSG require 'thread' -$DEBUG = true # This is a Global Variable Useful for Debugging +$DEBUG = false # This is a Global Variable Useful for MSG::debugging ########################################################################### # Class Semaphore ########################################################################### -class Semaphore - Thread.abort_on_exception = true - attr_accessor :permits - - def initialize ( permits ) - @permits = permits + +class Semaphore + def initialize(initvalue = 0) + @counter = initvalue + @waiting_list = [] 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 - } + def acquire + MSG::debug("Acquire "+self.to_s) + Thread.critical = true + if (@counter -= 1) < 0 + @waiting_list.push(Thread.current) + Thread.stop + end + self + ensure + Thread.critical = false end - - def release(mutex,cv) - mutex.synchronize{ - @permits += 1 - cv.signal - } + + def release + MSG::debug("Release "+self.to_s) + Thread.critical = true + begin + if (@counter += 1) <= 0 + t = @waiting_list.shift + t.wakeup if t + MSG::debug("Wakeup "+t.to_s) + else + MSG::debug("Nobody to wakeup") + end + rescue ThreadError + retry + end + self + ensure + Thread.critical = false end end ######################################################################## -# Class RbProcess +# Class Process ######################################################################## -class RbProcess < Thread +class MSG::Process < Thread @@nextProcessId = 0 + # Attributes - attr_accessor :bind, :id, :properties, :name, - :pargs, :schedBegin, :schedEnd, :mutex, :cv + attr_reader :bind, :id # Read only + attr_accessor :name, :properties, :pargs # R/W # Initialize : Used from ApplicationHandler to fill it in def initialize(*args) + # FIXME: use only one variante (the one with 3 args) and kill the others + @schedBegin = Semaphore.new(0) + @schedEnd = Semaphore.new(0) + @properties = Hash.new() + @id = @@nextProcessId++ argc = args.size @@ -56,16 +71,14 @@ class RbProcess < Thread @bind = 0 @name = "" @pargs = Array.new() - init_var() start() - if $DEBUG - puts "Init Default Initializer...Nothing to do...Bye" - end + MSG::debug "Initializer without any argument" } # 2 arguments: (HostName,Name) Or (Host , Name) elsif argc == 2 super(){ + MSG::debug "Initilize with 2 args" type = args[0].type() if ( type.to_s == "String") host = Host.getByName(args[0]) @@ -83,19 +96,14 @@ class RbProcess < Thread puts @name end @pargs = Array.new() # No Args[] Passed in Arguments - @@nextProcessId += 1 - @id = @@nextProcessId - init_var() 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(){ + MSG::debug "Initilize with 3 args" type = args[0].type() if ( type.to_s == "String") host = Host.getByName(args[0]) @@ -113,110 +121,70 @@ class RbProcess < Thread type = args[2].type() raise "Third argument should be an Array" if type != "Array" @pargs = args[3] - @@nextProcessId +=1 - @id = @@nextProcessId - init_var() createProcess(self,host) - if $DEBUG - puts "Initilize with 3 args" - end - -# sleep #keep the thread running } else - raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc + raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc.to_s end end - - # Init_var Called By Initialize - def init_var() - @proprieties = Hash.new() - @mutex = Mutex.new - @cv = ConditionVariable.new - # Process Synchronization Tools - @schedBegin = Semaphore.new(0) - @schedEnd = Semaphore.new(0) - end - #main - def msg_main(args) - # To Be Implemented within The Process... - # The Main Code of The Process to be Executed ... + # main + def main(args) + # To be overriden by childs + raise("You must define a main() function in your process, containing the code of this process") end - # Start : To keep the Process Alive and waitin' via semaphore + # Start : To keep the process alive and waiting via semaphore def start() - @schedBegin.acquire(@mutex,@cv) - #execute The Main Code of The Process ( Example Master ; Slave ...) - msg_main(@pargs) - processExit(self) #Exite the Native Process - @schedEnd.release(@mutex,@cv) + @schedBegin.acquire + # execute the main code of the process + MSG::debug("Begin execution") + main(@pargs) + processExit(self) # Exit the Native Process + @schedEnd.release end -# NetxId - def nextId () - @@nextProcessId +=1 - return @@nextProcessId - end - - if $DEBUG - #Process List - def processList() - Thread.list.each {|t| p t} - end + def processList() (KILLME?) + Thread.list.each {|t| p t} end - #Get Own ID + #Get Own ID (KILLME?) def getID() return @id end - # set Id - def setID(id) - @id = id - end - - #Get a Process ID + #Get a Process ID (KILLME?) def processID(process) return process.id end - #Get Own Name + #Get Own Name (KILLME?) def getName() return @name end - #Get a Process Name - def processName(process) - return process.name - end - - #Get Bind + #Get Bind (KILLME?) def getBind() return @bind end - #Get Binds + #Get Binds (KILLME?) def setBind(bind) @bind = bind end - def unschedule() - - @schedEnd.release(@mutex,@cv) -# info("@schedEnd.release(@mutex,@cv)") - @schedBegin.acquire(@mutex,@cv) -# info("@schedBegin.acquire(@mutex,@cv)") - + def unschedule() + @schedEnd.release + @schedBegin.acquire end def schedule() - @schedBegin.release(@mutex,@cv) - @schedEnd.acquire(@mutex,@cv) + @schedBegin.release + @schedEnd.acquire end - #C Simualateur Process Equivalent Management + #C Simualator Process Equivalent Management # After Binding Ruby Process to C Process # pause @@ -242,172 +210,44 @@ class RbProcess < Thread # The Rest of Methods !!! To be Continued ... end -######################################################################## -# Class ProcessFactory -######################################################################## - -class ProcessFactory - -# Attributes - attr_accessor :args, :proprieties, :hostName, :function -# Initlialize - def initialize() - - @args = Array.new - @proprieties = Hash.new - @hostName = nil - @function = nil - - end - -# setProcessIdentity - def setProcessIdentity(hostName,function) - @hostName = hostName - @function = function - - if !args.empty? - args.clear - end - - if !proprieties.empty? - proprieties.clear - end - - end - -# RegisterProcess - def registerProcessArg(arg) - - @args.push(arg) - - end - -# CreateProcess - def createProcess() - - process = rubyNewInstance(@function) # process = rubyNewInstanceArgs(@function,@args) # - size = @args.size - for i in 0..size-1 - process.pargs.push(@args[i]) - end - process.name = @function - process.id = process.nextId() # This increment Automaticaly The Static ProcessNextId for The Class RbProces - host = RbHost.getByName(@hostName) - processCreate(process,host) - process.properties = @properties - @proprieties = Hash.new - - end - -# SetProperty - def setProperty(id,value) - @proprieties[id] = value - end -end - ######################################################################### # Class ApplicationHandler ######################################################################### class ApplicationHandler - @processFactory -# Initialize def initialize() - #Nothing todo - end - - # onStartDocument - def onStartDocument() - - @processFactory = ProcessFactory.new - if ($DEBUG) - puts "onStartDocument" - end - + @hostName = nil + @function = nil end -# onBeginProcess def onBeginProcess(hostName,function) + @args = Array.new + @properties = Hash.new - @processFactory.setProcessIdentity(hostName,function) - - if ($DEBUG) - puts "onBeginProcess" - end - - end - -# onProperty - def onProperty(id,value) - - @processFactory.setProperty(id,value) - - if ($DEBUG) - puts "onProperty" - end - - end - -# RegisterProcessArg - def onProcessArg(arg) - - @processFactory.registerProcessArg(arg) + @hostName = hostName + @function = function - if ($DEBUG) - puts "onProcessArg" - end - + MSG::debug("onBeginProcess("+hostName+","+function+")") end -# OnEndProcess - def onEndProcess() - - @processFactory.createProcess() - - if ($DEBUG) - puts "onEndProcess" - end - - end - - # onEndDocument - def onEndDocument() -# Erm... Actually nothing to do !! - - if($DEBUG) - puts "onEndDocument" - end - end - - # End Class - end - -######################### -# Class RbHost -######################### - -class RbHost < Host -# Attributes - attr_accessor :bind, :data - -# Initialize - def initialize() - super() - @bind = 0 - @data = nil + def onProperty(id,value) + @properties[id] = value end -end - -######################### -# Class RbTask -######################### -class RbTask < Task - attr_accessor :bind - - def initialize(name,comp_size,comm_size) - super(name,comp_size,comm_size) + def onProcessArg(arg) + @args.push(arg) end + def onEndProcess() + # must be in C, called from a callback to the FlexML parser + # newInstance must take args and hostname as argument to initialize everything, *and* bind it to C element + # Allows to mark all attributes of process (but properties) to read-only + process = MSG::rubyNewInstance(@function) + process.pargs = @args + process.name = @function + host = MSG::Host.getByName(@hostName) + MSG::processCreate(process,host) + process.properties = @properties + end end #########################