Skip to content

Instantly share code, notes, and snippets.

@banderson623
Last active December 14, 2015 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save banderson623/5010787 to your computer and use it in GitHub Desktop.
Save banderson623/5010787 to your computer and use it in GitHub Desktop.
My dirty cpu simulator. Comment out debug lines at the bottom for displaying cool things
# Consider a system running ten I/O-bound tasks and one CPU-bound task.
# Assume that the I/O-bound tasks issue an I/O operation once for every millisecond of CPU computing and that each I/O operation takes 10 milliseconds to complete; the CPU-bound task performs only computations.
# Also assume that the context-switching overhead is 0.1 milli-second and that all processes are long-running tasks.
#
# Find out the CPU utilization for a round-robin scheduler when:
#
# a. The time quantum is 1 millisecond
#
# b. The time quantum is 10 milliseconds
class Proccess
attr_reader :name
attr_accessor :debug
def initialize(name)
@name = name
@type = "cpu"
@operatingSum = 0
@waitingSum = 0
@isWaiting = 0;
@waiting = 0;
@debug = false
end
def do(available_time)
did_run = 0
print "#{@name.downcase.ljust(3)}" if @debug
while(available_time > 0) do
if(canRun?)
print("x") if @debug
did_run += 1
@operatingSum +=1
_privateDo
else
print("-") if @debug
@waitingSum += 1
@isWaiting = @isWaiting - 1;
@isWaiting = 0 if(@isWaiting < 0.0) # cleanup
end
available_time = available_time - 1
end
print "| " if @debug
return did_run
end
def canRun?
@isWaiting == 0
end
def _privateDo
end
def to_s
"#{@name} (#{@type.downcase})"
end
def summary
"#{@name.ljust(10)} [#{@type.ljust(10)} waited: #{@waitingSum.to_s.ljust(10)} cpu: #{@operatingSum.to_s.ljust(10)}]"
end
def get_type
@type
end
end
class IOBound < Proccess
def initialize(name)
super(name)
@waiting = 10;
@type = "i/o"
end
def _privateDo
if(@isWaiting == 0 )
@isWaiting += @waiting
end
end
end
class Processor
attr_accessor :switch_time, :quantum
def initialize(quantum = 1)
@queue = []
@switch_time = 0.1
@quantum = quantum
@totalTime = 0.0
@utilizedTime = 0.0
end
def add(task)
@queue << task
end
def to_s
@queue.inspect
end
def run(runs=100)
index = 0;
puts "Running #{runs} times >> quantum: #{@quantum}, context switch expense: #{@switch_time} \nProcesses" + @queue.collect{|i| i.to_s}.join(", ")
while(@queue.size > 0 && index < runs)
item = @queue.shift
runTime = item.do(@quantum)
@totalTime += @switch_time + runTime
@utilizedTime += runTime
@queue << item
if(index % 5 == 0)
puts "\n" if item.debug
end
index += 1
end
end
def summary
return "CPUTime: #{@utilizedTime.round}ms | TotalTime: #{@totalTime.round}ms | Utilization: #{((@utilizedTime/@totalTime)*100).round}%"
end
end
puts "Round Robin: 1 ms Quantum"
cpu = Processor.new(1)
# cpu.debug = true
cpu.add(Proccess.new("p0"))
(1..10).each do |i|
p = IOBound.new("p#{i}")
# p.debug = true
cpu.add(p)
end
cpu.run(500)
puts cpu.summary
puts "\n\n\nRound Robin: 10 ms Quantum"
cpu = Processor.new(10)
# cpu.debug = true
cpu.add(Proccess.new("p0"))
(1..10).each do |i|
p = IOBound.new("p#{i}")
# p.debug = true
cpu.add(p)
end
cpu.run(5000)
puts cpu.summary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment