X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/51f5efedb7e873fa0c82bdc8bb0aa78ae3e827c7..3c67cbdbcd451a8059eba237a886c19faa0f4ebe:/src/bindings/ruby/simgrid.rb diff --git a/src/bindings/ruby/simgrid.rb b/src/bindings/ruby/simgrid.rb index 2cfeacf13c..67c7e1ccd3 100644 --- a/src/bindings/ruby/simgrid.rb +++ b/src/bindings/ruby/simgrid.rb @@ -1,11 +1,45 @@ +# FIXME: add license like in C files + require 'simgrid_ruby' require 'thread' -$DEBUG = false # This is a Global Variable Useful for MSG::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) @@ -14,11 +48,13 @@ class Semaphore end def acquire - MSG::debug("Acquire "+self.to_s) 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 @@ -26,15 +62,14 @@ class Semaphore end 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) + MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Wakeup "+t.to_s) else - MSG::debug("Nobody to wakeup") + MSG::debug(Thread.current.to_s+" releases "+self.to_s+". Nobody to wakeup") end rescue ThreadError retry @@ -52,204 +87,164 @@ class MSG::Process < Thread @@nextProcessId = 0 # Attributes - attr_reader :bind, :id # Read only - attr_accessor :name, :properties, :pargs # R/W + attr_reader :bind, :id, :name, :pargs ,:properties# Read only -# 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 + 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() - 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]) - 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) - } - - # 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]) - 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) - - } - else - raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc.to_s - end + start() + } end - - # 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 waiting via semaphore def start() - @schedBegin.acquire - # execute the main code of the process - MSG::debug("Begin execution") + @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() (KILLME?) - Thread.list.each {|t| p t} - end - - #Get Own ID (KILLME?) - def getID() - return @id - end - - #Get a Process ID (KILLME?) - def processID(process) - return process.id - end - - #Get Own Name (KILLME?) - def getName() - return @name - end - - #Get Bind (KILLME?) + + # FIXME: useless, there is an attribute for bind (or the attribute is useless) + # Get Bind def getBind() return @bind end - #Get Binds (KILLME?) + # 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 ApplicationHandler -######################################################################### -class ApplicationHandler - def initialize() - @hostName = nil - @function = nil +############################################ +# Task Extend from the native Class RbTask +############################################ +class MSG::Task < MSG::RbTask + + 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 onBeginProcess(hostName,function) - @args = Array.new - @properties = Hash.new + def execute + super(self) + end - @hostName = hostName - @function = function - - MSG::debug("onBeginProcess("+hostName+","+function+")") + def listenFromHost(t_alias,host) + super(t_alias,host) end +end - def onProperty(id,value) - @properties[id] = value +############################################ +# Host Extend from the native Class RbHost +############################################ +class MSG::Host < MSG::RbHost + + def getByName(name) + super(name) end - def onProcessArg(arg) - @args.push(arg) + def name + super(self) 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 + + def speed + super(self) + end + + def getData + super(self) + end + + def setData(data) + super(self,data) + end + + def isAvail + super(self) + end + + def number + super() end end - + ######################### # Main chunck #########################