[#15707] Schedule for the 1.8.7 release — "Akinori MUSHA" <knu@...>

Hi, developers,

21 messages 2008/03/01

[#15740] Copy-on-write friendly garbage collector — Hongli Lai <hongli@...99.net>

Hi.

31 messages 2008/03/03
[#15742] Re: Copy-on-write friendly garbage collector — Yukihiro Matsumoto <matz@...> 2008/03/03

Hi,

[#15829] Re: Copy-on-write friendly garbage collector — Daniel DeLorme <dan-ml@...42.com> 2008/03/08

Yukihiro Matsumoto wrote:

[#15756] embedding Ruby 1.9.0 inside pthread — "Suraj Kurapati" <sunaku@...>

Hello,

18 messages 2008/03/03
[#15759] Re: embedding Ruby 1.9.0 inside pthread — Nobuyoshi Nakada <nobu@...> 2008/03/04

Hi,

[#15760] Re: embedding Ruby 1.9.0 inside pthread — Yukihiro Matsumoto <matz@...> 2008/03/04

Hi,

[#15762] Re: embedding Ruby 1.9.0 inside pthread — "Suraj N. Kurapati" <sunaku@...> 2008/03/04

Yukihiro Matsumoto wrote:

[#15783] Adding startup and shutdown to Test::Unit — Daniel Berger <Daniel.Berger@...>

Hi all,

15 messages 2008/03/04

[#15835] TimeoutError in core, timeouts for ConditionVariable#wait — MenTaLguY <mental@...>

I've been reworking JRuby's stdlib to improve performance and fix

10 messages 2008/03/09

[#15990] Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...>

Hi,

35 messages 2008/03/23
[#15991] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/23

[#15993] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/23

Hi Dave,

[#15997] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/23

[#16024] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/26

Hi Dave,

[#16025] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16026] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16027] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16029] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16030] Re: Recent changes in Range#step behavior — Yukihiro Matsumoto <matz@...> 2008/03/26

Hi,

[#16031] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16032] Re: Recent changes in Range#step behavior — "Vladimir Sizikov" <vsizikov@...> 2008/03/26

On Wed, Mar 26, 2008 at 7:01 PM, Dave Thomas <dave@pragprog.com> wrote:

[#16033] Re: Recent changes in Range#step behavior — Dave Thomas <dave@...> 2008/03/26

[#16041] Re: Recent changes in Range#step behavior — David Flanagan <david@...> 2008/03/26

Dave Thomas wrote:

Re: embedding Ruby 1.9.0 inside pthread

From: "Suraj N. Kurapati" <sunaku@...>
Date: 2008-03-14 05:52:27 UTC
List: ruby-core #15895
Hongli Lai wrote:
> This is better, but now your program has a racing condition. Suppose the
> thread finished before your pthread_cond_wait() is called. Now you're
> waiting for a condition that will never be signalled.
> 
> The correct way to wait for a condition is to use the following pattern:

Thanks for the correction.  Below is the revised (and more complex)
example that better shows the Ruby/C interaction of my final program.

Notice how the hello.rb script is able to relay control back to the
C program and vice versa.  This is how my final program works:  it
allows a Ruby script (like hello.rb) to use a C extension (Ruby-VPI)
and relay control back to the C program (a Verilog simulator).
After some time, the C program relays control back to the Ruby script.

One discrepancy I noticed is that this program works correctly with
ruby-1.9.0-0 but crashes with the new ruby-1.9.0-1 release.  For
instance, here is the response when running with ruby-1.9.0-0:

  $ ./main.so
  C program is calling RUBY_INIT_STACK()
  C program is calling ruby_init()
  C program is registering Object#relay_to_c method
  C program is loading file: hello.rb
  Ruby thread has been started, but is paused.
  C program relaying to Ruby thread... 1st time
  Ruby thread is starting interpreter... 1st time
  rubygems OK!
  {:$0=>"hello.rb"}
  {:ARGV=>[]}
  ------------------------------------------------------------
  Hello World! 0
  C program relaying to Ruby thread... 2nd time
  Hello World! 1
  C program relaying to Ruby thread... 3rd time
  Hello World! 2
  C program is back in control, exiting...

And here is the response when running with ruby-1.9.0-1:

  $ ./main.so
  C program is calling RUBY_INIT_STACK()
  C program is calling ruby_init()
  C program is registering Object#relay_to_c method
  C program is loading file: hello.rb
  Ruby thread has been started, but is paused.
  C program relaying to Ruby thread... 1st time
  Ruby thread is starting interpreter... 1st time
  <dummy toplevel>:17: SystemStackError
  C program relaying to Ruby thread... 2nd time
  Ruby thread is starting interpreter... 2nd time
  <dummy toplevel>: [BUG] Segmentation fault
  ruby 1.9.0 (2008-03-01 revision 15664) [i686-linux]

  -- control frame ----------
  c:0001 p:0000 s:0002 b:0002 l:000001 d:000001 TOP
  ---------------------------
  -- backtrace of native function call (Use addr2line) --
  0x80faa1a
  0x805f06c
  0x805f0db
  0x80c9680
  0xffffe440
  0x80fc2c6
  0x8065dbe
  0x8066279
  0x8066462
  0x805b39a
  0xb7f0546b
  0xb7e286de
  -------------------------------------------------------
  Aborted (core dumped)

There do not seem to be any difference between the main.c of these
two Ruby 1.9.0 releases, so is there something extra I must to do
make this example work in the new -1 release?

Thanks for your consideration.

---

The revised example code:

  $ cat hello.rb
  require 'rubygems'
  puts "rubygems OK!"
  p :'$0' => $0
  p :ARGV => ARGV
  puts '-' * 60

  3.times do |i|
    puts "Hello World! #{i}"
    relay_to_c
  end

  $ cat main.c
  #include <stdio.h>
  #include <pthread.h>
  #include <ruby.h>
  #include <stdbool.h>

  pthread_t gRubyThread;
  pthread_mutex_t gRubyLock;
  pthread_cond_t gRubyCond;
  bool gRubyRunning;

  ///
  /// Transfers control from the Ruby script
  /// to the C program and pauses Ruby.
  ///
  VALUE relay_to_c(VALUE);

  ///
  /// Transfers control from the Ruby thread
  /// to the C program and pauses Ruby.
  ///
  void relay_from_ruby_to_c();

  ///
  /// Transfers control from the C program to
  /// the Ruby thread and pauses the C program.
  ///
  void relay_from_c_to_ruby();

  ///
  /// Makes the C program wait until the Ruby
  /// thread finishes running (for now).
  ///
  void wait_for_ruby();

  ///
  /// Tells the C program that the Ruby
  /// thread has finished running (for now).
  ///
  void ruby_is_done();

  ///
  /// Makes the Ruby thread wait until the
  /// C program finishes running (for now).
  ///
  void wait_for_c();

  ///
  /// Tells the Ruby thread that the C
  /// program has finished running (for now).
  ///
  void c_is_done();

  ///
  /// Body of the pthread which hosts the
  /// Ruby interpreter's flow of execution.
  ///
  /// aRubyProgram:: program node for the interpreter to run
  ///
  void* the_ruby_thread(void* aRubyProgram)
  {
      printf("Ruby thread has been started, but is paused.\n");
      relay_from_ruby_to_c();

      printf("Ruby thread is starting interpreter... 1st time\n");
      ruby_run_node(aRubyProgram);
      relay_from_ruby_to_c();

      printf("Ruby thread is starting interpreter... 2nd time\n");
      ruby_run_node(aRubyProgram);
      relay_from_ruby_to_c();

      printf("Ruby thread is starting interpreter... 3rd time\n");
      ruby_run_node(aRubyProgram);
      relay_from_ruby_to_c();

      printf("Ruby thread is done, goodbye C program...\n");
      ruby_is_done();

      pthread_exit(NULL);
  }

  RUBY_GLOBAL_SETUP

  void the_c_program()
  {
      char* file = "hello.rb"; // the file to run
      int fake_argc = 2;
      char* fake_args[fake_argc];
      fake_args[0] = file; // $0 - name of the program
      fake_args[1] = file;
      char** fake_argv = fake_args;

      printf("C program is calling RUBY_INIT_STACK()\n");
      RUBY_INIT_STACK;

      printf("C program is calling ruby_init()\n");
      ruby_init();

      printf("C program is registering Object#relay_to_c method\n");
      rb_define_module_function(rb_cObject, "relay_to_c",
relay_to_c, 0);

      printf("C program is loading file: %s\n", file);
      void* rubyProgram = ruby_options(fake_argc, fake_argv);

      pthread_mutex_init(&gRubyLock, NULL);
      pthread_cond_init(&gRubyCond, NULL);

      gRubyRunning = true;
      pthread_create(&gRubyThread, NULL, the_ruby_thread, rubyProgram);
      wait_for_ruby();

      printf("C program relaying to Ruby thread... 1st time\n");
      relay_from_c_to_ruby(); // C program blocks here

      printf("C program relaying to Ruby thread... 2nd time\n");
      relay_from_c_to_ruby(); // C program blocks here

      printf("C program relaying to Ruby thread... 3rd time\n");
      relay_from_c_to_ruby(); // C program blocks here

      printf("C program is back in control, exiting...\n");
      pthread_mutex_destroy(&gRubyLock);
      pthread_cond_destroy(&gRubyCond);
  }

  int main(int argc, char** argv)
  {
      the_c_program();
      return 0;
  }


  VALUE relay_to_c(VALUE self)
  {
      relay_from_ruby_to_c();
      return self;
  }

  void relay_from_ruby_to_c()
  {
      ruby_is_done();
      wait_for_c();
  }

  void ruby_is_done()
  {
      pthread_mutex_lock(&gRubyLock);
      {
          gRubyRunning = false;
          pthread_cond_signal(&gRubyCond);
      }
      pthread_mutex_unlock(&gRubyLock);
  }

  void wait_for_c()
  {
      pthread_mutex_lock(&gRubyLock);
      {
          while (!gRubyRunning)
          {
              pthread_cond_wait(&gRubyCond, &gRubyLock);
          }
      }
      pthread_mutex_unlock(&gRubyLock);
  }

  void relay_from_c_to_ruby()
  {
      c_is_done();
      wait_for_ruby();
  }

  void c_is_done()
  {
      pthread_mutex_lock(&gRubyLock);
      {
          gRubyRunning = true;
          pthread_cond_signal(&gRubyCond);
      }
      pthread_mutex_unlock(&gRubyLock);
  }

  void wait_for_ruby()
  {
      pthread_mutex_lock(&gRubyLock);
      {
          while (gRubyRunning)
          {
              pthread_cond_wait(&gRubyCond, &gRubyLock);
          }
      }
      pthread_mutex_unlock(&gRubyLock);
  }


In This Thread