Hello,

When I was playing around with synchronization options in various 
dynamic languages I came across a problem in the Ruby VM accidentally.

I try to run 2 different barriers for a given number of times. I use 2 
barriers cause I want to use the simplest barrier implementation 
possible to avoid other sources of deadlocks.
When I run this code the Ruby interpreter reports an error from time to 
time (it doesn't always occur). The error differs from Ruby version to 
Ruby version and also depends on the processor architecture (x86, ia64). 
Ruby may throw a 'deadlock error' and crashes with segmentation fault.

Running gdb doesn't help much. The segmentation fault occurs in 
different parts of the eval.c code (of course on different architectures 
and with different compilers).

I would appreciate if could comment on this. Do you see any problem in 
my test code?

Best regards,

Sascha

---------------------------------------------------------------------------------------

# @author Sascha Hunold
#
# command line arguments
# 1 : number of iterations
# 2 : number of threads

require 'thread'

class BarrierTest

    def initialize(reps, threadnum)
        @reps = reps
        @threadnum = threadnum

        @cond1  = ConditionVariable.new
        @lock1  = Mutex.new
        @count1 = 0
        
        @cond2  = ConditionVariable.new
        @lock2  = Mutex.new
        @count2 = 0
    end
    
    def test()
      @reps.times do
        barrier1()
        barrier2()
      end
    end
   
    def barrier1()       
        @lock1.synchronize {
          @count1 += 1
          if @count1 == @threadnum
              @cond1.broadcast
          else
              @cond1.wait(@lock1)
          end
          @count1 -= 1
        }
    end

    def barrier2()       
        @lock2.synchronize {
          @count2 += 1
          if @count2 == @threadnum
              @cond2.broadcast
          else
              @cond2.wait(@lock2)  
          end
          @count2 -= 1
        }
    end

end

reps  = ARGV[0].to_i
tnum  = ARGV[1].to_i
threads = []
barrier_test = BarrierTest.new(reps, tnum)

tnum.times do |i|
    threads[i] = Thread.new {
              barrier_test.test()
    }
end

threads.each { |t| t.join }

-----------------------------------------------------------------------------------------------

test output

system 1 - Linux 2.6.13-15.10-smp (x86)
---------------------------------------

ruby 1.8.2 (2004-12-25) [i586-linux]

$ ruby barrier_test.rb 10000 16
deadlock 0x4029f280: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f3fc: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f578: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f6f4: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f870: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f9ec: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x402b4798: sleep:J(0x4029f9ec) (main) - barrier_test.rb:63
deadlock 0x4029e3a8: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029e524: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029e6a0: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029e81c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029e998: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029eb14: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029ec90: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029ee0c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029ef88: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
deadlock 0x4029f104: sleep:-  - /usr/lib/ruby/1.8/thread.rb:195
/usr/lib/ruby/1.8/thread.rb:195: Thread(0x4029f104): deadlock (fatal)
        from barrier_test.rb:63:in `each'
        from barrier_test.rb:63

ruby 1.8.4 (2005-12-24) [i686-linux]

$ ~/tmp/test/ruby-1.8.4/bin/ruby  barrier_test.rb 10000 16
deadlock 0x401e413c: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e42b8: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e4434: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e45b0: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e472c: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e48a8: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e4a24: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e4ba0: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e4d1c: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e4e98: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e5014: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e5190: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e530c: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e5488: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401fa748: sleep:J(0x401e5488) (main) - barrier_test.rb:63
deadlock 0x401e3e44: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
deadlock 0x401e3fc0: sleep:-  - 
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203
/home/hunold/tmp/test/ruby-1.8.4/lib/ruby/1.8/thread.rb:203: 
Thread(0x401e3fc0): deadlock (fatal)
        from barrier_test.rb:63


ruby 1.9.0 (2006-08-13) [i686-linux]

$ ~/tmp/test/ruby-snap/bin/ruby barrier_test.rb 10000 16
deadlock 0x401d1d30: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1e98: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d2000: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d2168: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d22d0: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401e7748: sleep:J(0x401d22d0) (main) - barrier_test.rb:63
deadlock 0x401d0db8: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d0f20: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1088: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d11f0: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1358: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d14c0: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1628: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1790: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d18f8: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1a60: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
deadlock 0x401d1bc8: sleep:-  - 
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:206
/home/hunold/tmp/test/ruby-snap/lib/ruby/1.9/thread.rb:204: [BUG] 
Segmentation fault
ruby 1.9.0 (2006-08-13) [i686-linux]

-------------------------------------------------------------------------------

system 2 Linux 2.6.17.6 Intel(R) Pentium(R) 4 CPU 3.06GHz GNU/Linux

ruby 1.8.4 (2005-12-24) [i686-linux]

$ ruby barrier_test.rb 1000 16
deadlock 0xb7d642b8: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d64434: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d645b0: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d6472c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d648a8: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d64a24: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d64ba0: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d64d1c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d64e98: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d65014: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d65190: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d6530c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d65488: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d7a748: sleep:J(0xb7d65488) (main) - barrier_test.rb:63
deadlock 0xb7d63e44: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d63fc0: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
deadlock 0xb7d6413c: sleep:-  - /usr/lib/ruby/1.8/thread.rb:203
/usr/lib/ruby/1.8/thread.rb:35: [BUG] Segmentation fault
ruby 1.8.4 (2005-12-24) [i686-linux]