From: "Glass_saga (Masaki Matsushita)" Date: 2013-05-22T21:07:12+09:00 Subject: [ruby-core:55117] [ruby-trunk - Feature #3620] Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones Issue #3620 has been updated by Glass_saga (Masaki Matsushita). File patch2.diff added 2013/5/18 nobu (Nobuyoshi Nakada) > You can use rb_funcall2() instead here. I made a patch which use rb_funcall2(). diff from patch.diff to patch2.diff: diff --git a/ext/thread/thread.c b/ext/thread/thread.c index 33365c1..f2d17e9 100644 --- a/ext/thread/thread.c +++ b/ext/thread/thread.c @@ -142,15 +142,17 @@ rb_condvar_initialize(VALUE self) } struct sleep_call { - int argc; - VALUE *argv; + VALUE mutex; + VALUE timeout; }; +static ID id_sleep; + 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_funcall2(p->mutex, id_sleep, 1, &p->timeout); } static VALUE @@ -173,12 +175,16 @@ static VALUE rb_condvar_wait(int argc, VALUE *argv, VALUE self) { VALUE waiters = get_condvar_ptr(self)->waiters; + VALUE mutex, timeout; struct sleep_call args; - args.argc = argc; - args.argv = argv; + rb_scan_args(argc, argv, "11", &mutex, &timeout); + + args.mutex = mutex; + args.timeout = timeout; rb_ary_push(waiters, rb_thread_current()); rb_ensure(do_sleep, (VALUE)&args, delete_current_thread, waiters); + return self; } @@ -607,7 +613,6 @@ static VALUE szqueue_do_push(SizedQueue *szqueue, VALUE obj) { struct waiting_delete args; - VALUE thread; while (queue_length(&szqueue->queue_) >= szqueue->max) { args.waiting = szqueue->queue_wait; @@ -699,6 +704,8 @@ Init_thread(void) VALUE rb_cQueue = DEFINE_CLASS_UNDER_THREAD(Queue, rb_cObject); VALUE rb_cSizedQueue = DEFINE_CLASS_UNDER_THREAD(SizedQueue, rb_cQueue); + id_sleep = rb_intern("sleep"); + rb_define_alloc_func(rb_cConditionVariable, condvar_alloc); rb_define_method(rb_cConditionVariable, "initialize", rb_condvar_initialize, 0); rb_define_method(rb_cConditionVariable, "wait", rb_condvar_wait, -1); ---------------------------------------- Feature #3620: Add Queue, SIzedQueue and ConditionVariable implementations in C in addition to ruby ones https://bugs.ruby-lang.org/issues/3620#change-39486 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/