[#54738] [ruby-trunk - Bug #8358][Open] TestSprintf#test_float test failuer on mingw32 — "phasis68 (Heesob Park)" <phasis@...>

36 messages 2013/05/02

[#54749] [ruby-trunk - Feature #8361][Open] Alternative syntax for block parameter — "alexeymuranov (Alexey Muranov)" <redmine@...>

12 messages 2013/05/02

[#54798] [ruby-trunk - Bug #8370][Open] Constants MAX_MULTIPART_LENGTH in cgi\core.rb — "xibbar (Takeyuki FUJIOKA)" <xibbar@...>

17 messages 2013/05/05

[#54850] [ruby-trunk - Feature #8377][Open] Deprecate :: for method calls in 2.1 — "charliesome (Charlie Somerville)" <charliesome@...>

27 messages 2013/05/07

[#54881] [ruby-trunk - Bug #8384][Open] Cannot build ruby against OpenSSL build with "no-ec2m" — "vo.x (Vit Ondruch)" <v.ondruch@...>

16 messages 2013/05/09

[#54921] [ruby-trunk - Bug #8393][Open] A class who's parent class is in a module can go wrong if files are required in the wrong order — "eLobato (Daniel Lobato Garcia)" <elobatocs@...>

15 messages 2013/05/12

[#54939] [ruby-trunk - Bug #8399][Open] Remove usage of RARRAY_PTR in C extensions when not needed — "dbussink (Dirkjan Bussink)" <d.bussink@...>

32 messages 2013/05/12

[#55053] [ruby-trunk - Feature #8426][Open] Implement class hierarchy method caching — "charliesome (Charlie Somerville)" <charliesome@...>

21 messages 2013/05/19

[#55096] [ruby-trunk - Feature #8430][Open] Rational number literal — "mrkn (Kenta Murata)" <muraken@...>

28 messages 2013/05/21

[#55197] [ruby-trunk - Feature #8461][Open] Easy way to disable certificate checking in XMLRPC::Client — "herwinw (Herwin Weststrate)" <herwin@...>

11 messages 2013/05/29

[ruby-core:55027] [ruby-trunk - Feature #3620] Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones

From: "Glass_saga (Masaki Matsushita)" <glass.saga@...>
Date: 2013-05-17 13:59:45 UTC
List: ruby-core #55027
Issue #3620 has been updated by Glass_saga (Masaki Matsushita).

File patch.diff added

I fixed some bugs:
(1) blocking forever bug pointed out by ko1 in [ruby-core:45950]
(2) SEGV in do_sleep()
(3) SizedQueue's bug which is similar to (1)

Now, the C implementation passes test-all.
Following diff is from final_queue_without_mutex.diff to my patch.

diff --git a/ext/thread/thread.c b/ext/thread/thread.c
index 9aff5e5..33365c1 100644
--- a/ext/thread/thread.c
+++ b/ext/thread/thread.c
@@ -150,7 +150,7 @@ static VALUE
 do_sleep(VALUE args)
 {
     struct sleep_call *p = (struct sleep_call *)args;
-    return rb_funcall(p->argv[0], rb_intern("sleep"), p->argc-1, p->argv+1);
+    return rb_funcall(p->argv[0], rb_intern("sleep"), p->argc-1, p->argv[1]); /* (2) */
 }

 static VALUE
@@ -339,15 +339,31 @@ rb_queue_push(VALUE self, VALUE obj)
     return self;
 }

+struct waiting_delete {
+    VALUE waiting;
+    VALUE th;
+};
+
+static VALUE
+queue_delete_from_waiting(struct waiting_delete *p)
+{
+    rb_ary_delete(p->waiting, p->th);
+    return Qnil;
+}
+
 static VALUE
 queue_do_pop(Queue *queue, VALUE should_block)
 {
-    while (!RARRAY_LEN(queue->que)) {
+    struct waiting_delete args;
+
+    while (RARRAY_LEN(queue->que) == 0) {
        if (!(int)should_block) {
            rb_raise(rb_eThreadError, "queue empty");
        }
-       rb_ary_push(queue->waiting, rb_thread_current());
-       rb_thread_sleep_forever();
+       args.waiting = queue->waiting;
+       args.th      = rb_thread_current();
+       rb_ary_push(args.waiting, args.th);
+       rb_ensure((VALUE (*)())rb_thread_sleep_forever, (VALUE)0, queue_delete_from_waiting, (VALUE)&args); /* (1) */
     }

     return rb_ary_shift(queue->que);
@@ -590,9 +606,14 @@ rb_szqueue_max_set(VALUE self, VALUE vmax)
 static VALUE
 szqueue_do_push(SizedQueue *szqueue, VALUE obj)
 {
+    struct waiting_delete args;
+    VALUE thread;
+
     while (queue_length(&szqueue->queue_) >= szqueue->max) {
-       rb_ary_push(szqueue->queue_wait, rb_thread_current());
-       rb_thread_sleep_forever();
+       args.waiting = szqueue->queue_wait;
+       args.th      = rb_thread_current();
+       rb_ary_push(args.waiting, args.th);
+       rb_ensure((VALUE (*)())rb_thread_sleep_forever, (VALUE)0, queue_delete_from_waiting, (VALUE)&args); /* (3) */
     }
     return queue_do_push(&szqueue->queue_, obj);
 }
----------------------------------------
Feature #3620: Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones
https://bugs.ruby-lang.org/issues/3620#change-39373

Author: panaggio (Ricardo Panaggio)
Status: Assigned
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: ext
Target version: next minor


=begin
 Queue, SizedQueue and ConditionVariable are important synchronization primitives and are nowadays implemented in Ruby.
 
 Attached patch (initiated by myself and heavily enriched by Nobu) contains these sync primitives implemented in C, which makes them faster (see [1] for the benchmark's code):
 
 Rehearsal -------------------------------------------------
 Q#push          1.590000   0.010000   1.600000 (  1.605502)
 T#push          0.600000   0.010000   0.610000 (  0.630444)
 Q#pop           4.390000   0.000000   4.390000 (  4.389781)
 T#pop           0.580000   0.000000   0.580000 (  0.578918)
 Q#empty?        0.480000   0.000000   0.480000 (  0.484305)
 T#empty?        0.360000   0.000000   0.360000 (  0.358559)
 Q#clear         1.210000   0.000000   1.210000 (  1.214494)
 T#clear         0.600000   0.000000   0.600000 (  0.588611)
 Q#size          0.370000   0.000000   0.370000 (  0.365587)
 T#size          0.350000   0.000000   0.350000 (  0.356985)
 Q#num_waiting   0.380000   0.000000   0.380000 (  0.379199)
 T#num_waiting   0.370000   0.000000   0.370000 (  0.368075)
 --------------------------------------- total: 11.300000sec
 
 It has already been discussed on ruby-core (see ruby-core:31100).
 
 This patch is one of the deliverables of my RubySoC project (slot #17): "Improving Ruby's Synchronization Primitives and Core Libraries" [2,3]
 
 [1] http://github.com/panaggio/rubysoc-2010/blob/master/benchmarks/queue.rb
 [2] http://pastebin.com/viSnfqe6
 [3] http://rubysoc.org/projects
=end



-- 
http://bugs.ruby-lang.org/

In This Thread

Prev Next