From 3af5298e8cc9d88fb0c763fb623b722a97912877 Mon Sep 17 00:00:00 2001 From: ko1 Date: Fri, 21 Aug 2015 09:51:01 +0000 Subject: [PATCH] * include/ruby/ruby.h, cont.c, vm_trace.c: add a new event fiber_switch. We need more discussion about this feature so that I don't write it on NEWS. [Feature #11348] * test/ruby/test_settracefunc.rb: add tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 ++++++ cont.c | 5 +++- include/ruby/ruby.h | 1 + test/ruby/test_settracefunc.rb | 51 ++++++++++++++++++++++++++++++++++ vm_trace.c | 3 ++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index f06c010eab..162112f41d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Fri Aug 21 18:49:22 2015 Koichi Sasada + + * include/ruby/ruby.h, cont.c, vm_trace.c: add a new event + fiber_switch. We need more discussion about this feature + so that I don't write it on NEWS. + [Feature #11348] + + * test/ruby/test_settracefunc.rb: add tests. + Fri Aug 21 17:32:42 2015 Koichi Sasada * vm_insnhelper.c (vm_invoke_block): we should not expect ci->argc is diff --git a/cont.c b/cont.c index fc0cf53655..774a026bd5 100644 --- a/cont.c +++ b/cont.c @@ -1260,8 +1260,9 @@ rb_fiber_start(void) th->errinfo = Qnil; th->root_lep = rb_vm_ep_local_ep(proc->block.ep); th->root_svar = Qfalse; - fib->status = RUNNING; + + EXEC_EVENT_HOOK(th, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, Qnil); cont->value = rb_vm_invoke_proc(th, proc, argc, argv, 0); } TH_POP_TAG(); @@ -1451,6 +1452,8 @@ fiber_switch(rb_fiber_t *fib, int argc, const VALUE *argv, int is_resume) value = fiber_store(fib, th); RUBY_VM_CHECK_INTS(th); + EXEC_EVENT_HOOK(th, RUBY_EVENT_FIBER_SWITCH, th->self, 0, 0, Qnil); + return value; } diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index f0d53b3e11..515a27aa0b 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1825,6 +1825,7 @@ int ruby_native_thread_p(void); #define RUBY_EVENT_B_RETURN 0x0200 #define RUBY_EVENT_THREAD_BEGIN 0x0400 #define RUBY_EVENT_THREAD_END 0x0800 +#define RUBY_EVENT_FIBER_SWITCH 0x1000 #define RUBY_EVENT_TRACEPOINT_ALL 0xffff /* special events */ diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 916705f7c8..8308f31f55 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -1349,4 +1349,55 @@ class TestSetTraceFunc < Test::Unit::TestCase assert_equal([:call, :return], evs) end + + require 'fiber' + def test_fiber_switch + # test for resume/yield + evs = [] + TracePoint.new(:fiber_switch){|tp| + next unless target_thread? + evs << tp.event + }.enable{ + f = Fiber.new{ + Fiber.yield + Fiber.yield + Fiber.yield + } + f.resume + f.resume + f.resume + f.resume + begin + f.resume + rescue FiberError + end + } + assert_equal 8, evs.size + evs.each{|ev| + assert_equal ev, :fiber_switch + } + + # test for transfer + evs = [] + TracePoint.new(:fiber_switch){|tp| + next unless target_thread? + evs << tp.event + }.enable{ + f1 = f2 = nil + f1 = Fiber.new{ + f2.transfer + f2.transfer + Fiber.yield :ok + } + f2 = Fiber.new{ + f1.transfer + f1.transfer + } + assert_equal :ok, f1.resume + } + assert_equal 6, evs.size + evs.each{|ev| + assert_equal ev, :fiber_switch + } + end end diff --git a/vm_trace.c b/vm_trace.c index 529cb720df..1ce11f9548 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -595,6 +595,7 @@ get_event_id(rb_event_flag_t event) C(b_return, B_RETURN); C(thread_begin, THREAD_BEGIN); C(thread_end, THREAD_END); + C(fiber_switch, FIBER_SWITCH); C(specified_line, SPECIFIED_LINE); case RUBY_EVENT_LINE | RUBY_EVENT_SPECIFIED_LINE: CONST_ID(id, "line"); return id; #undef C @@ -700,6 +701,7 @@ symbol2event_flag(VALUE v) C(b_return, B_RETURN); C(thread_begin, THREAD_BEGIN); C(thread_end, THREAD_END); + C(fiber_switch, FIBER_SWITCH); C(specified_line, SPECIFIED_LINE); C(a_call, A_CALL); C(a_return, A_RETURN); @@ -1445,6 +1447,7 @@ Init_vm_trace(void) * +:b_return+:: event hook at block ending * +:thread_begin+:: event hook at thread beginning * +:thread_end+:: event hook at thread ending + * +:fiber_siwtch+:: event hook at fiber switch * */ rb_cTracePoint = rb_define_class("TracePoint", rb_cObject);