#!/usr/bin/env ruby require 'fiber' require 'benchmark' DEBUG=false class FiberRing attr_reader :id def initialize(id) @id = id DEBUG and puts "Creating ring #{@id}" @fiber = Fiber.new do pass_msg end end def |(nxt) DEBUG and puts "attaching #{@id} to #{nxt.id}" @next = nxt nxt end def resume @fiber.resume end def pass_msg DEBUG and puts "#{@id} pass_msg called" while msg = msg_in DEBUG and puts "#{@id} received \"#{msg}\"" msg_out msg end end def msg_in DEBUG and puts "#{@id} msg_in called" unless @next.nil? DEBUG and puts "#{@id} resuming #{@next.id}" @next.resume DEBUG and puts "#{@id} returned from #{@next.id}.resume" end DEBUG and puts "#{@id} msg_in returning \"#{@id} message\"" "#{@id} message" end def msg_out msg DEBUG and puts "#{@id} msg_out called" DEBUG and puts "#{@id} calling Fiber.yield(#{msg})" Fiber.yield msg end end n=ARGV[0].to_i m=ARGV[1].to_i tm = Benchmark.measure do #build chain f0 = f = FiberRing.new(0) 1.upto(n-1) { |i| f = f | FiberRing.new(i) } #run chain m times m.times { |j| DEBUG and puts "--- #{j} ---"; f0.resume } end puts "#{n}, #{m}, #{tm}"