mepython
3/3/2005 6:00:00 PM
I need some help with callcc function. In a simulation world, I want to
hold a process until resource is available. I can not make process to
hold (simulation class starts a process and i want hold it until
resource is available, hence resource will restart hold process.
My apology for callcc syntax. It is totally wrong. Should I use yield?
if so, how?
Attach is a code and output: Since I am new to ruby, please feel free
to give me your comments on alternate approach.
Thanks in advance
*******************************************************************
#!/usr/bin/env ruby
require 'rbtree'
require 'pp'
class Simulation
attr_accessor :events, :t
def initialize
@events = MultiRBTree.new
@t = 0.0
end
def run(timeLimit=5000)
while @events.length > 0 and @events.first[0] < timeLimit
@t, obj = @events.shift
obj.simulate
end
end
end
#sEvents: Schedule events, Initialize will add start time event
class SimProcess
attr_accessor :name, :afterHold
@@sim = nil
def SimProcess.setSim(sim)
@@sim = sim
end
def initialize(name=nil, startTime=0.0, sEvents=[])
@name = name
@sEvents = [['IN', startTime]]
@sEvents.push(sEvents)
p [self.class.name, self.name, startTime, sEvents]
@@sim.events[startTime] = self
end
def simulate
eventType, val, resource = @sEvents.shift #Don't use val it can
be function
nextEventType, nextVal, nextResource = @sEvents.first
p [eventType, @@sim.t]
if nextEventType == nil
p self.name + ' Terminated'
elsif nextEventType == 'USE'
if nextResource
getResource = nextResource.get(self)
if getResource == nil #resource not available yield
p "Holding: #{object_id} #{@name}"
########### Needs to hold this process, NOT WORKING ###################
#### Will restart by Resource when it is available #####
callcc {|afterHold| afterHold}
#####################################################################
p 'After block'
end
@@sim.events[@@sim.t + nextVal] = self
else #Unlimited use of resources
@@sim.events[@@sim.t + nextVal] = self
end
end
if resource
resource.release
end
end
end
class SimResource
@@sim = nil
def SimResource.setSim(sim)
@@sim = sim
end
def initialize(capacity=1,name=nil)
@name = name
@capacity=capacity # resource units in this resource
@n=capacity # uncommitted resource units
@waitQ=[]
@priority_default=0
@t = 0
@process = nil
end
def inspect
"#{@name}"
end
def get(proc)
if @n > 0
@n -= 1
@process = proc
return self
else
@waitQ.push proc
return nil
end
end
def release
@n += 1
if @waitQ.length > 0
proc = @waitQ.shift
p ['HOLD', @@sim.t]
get(proc)
########### call to restart process ###################
if @process.afterHold
@process.afterHold.call
else
p 'SHOULD NOT BE HERE'
end
end
end
end
sim = Simulation.new
SimProcess.setSim sim
SimResource.setSim sim
counter = SimResource.new(1, "Server")
SimProcess.new("Bob", 0.0, ['USE', 3.0, counter]) #Use counter resource
for 3.0, terminates at 3.0
SimProcess.new("John", 2.0, ['USE', 5.0, counter]) #Should wait until
3.0 and then use couter resource for 5 min, terminates at 8.0
sim.run(100)
************* Output*****************
Note that John should be terminated at 8.0 not 7.0 if process holding
for resources is working
**********************************************
[spatel@taamportable simprocess]$ ruby x3.rb
["SimProcess", "Bob", 0.0, ["USE", 3.0, Server]]
["SimProcess", "John", 2.0, ["USE", 5.0, Server]]
["IN", 0.0]
["IN", 2.0]
"Holding: -605465924 John"
"After block"
["USE", 3.0]
"Bob Terminated"
["HOLD", 3.0]
"SHOULD NOT BE HERE"
["USE", 7.0]
"John Terminated"