ruby-changes:39571
From: ko1 <ko1@a...>
Date: Fri, 21 Aug 2015 18:51:13 +0900 (JST)
Subject: [ruby-changes:39571] ko1:r51652 (trunk): * include/ruby/ruby.h, cont.c, vm_trace.c: add a new event
ko1 2015-08-21 18:51:01 +0900 (Fri, 21 Aug 2015) New Revision: 51652 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51652 Log: * 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. Modified files: trunk/ChangeLog trunk/cont.c trunk/include/ruby/ruby.h trunk/test/ruby/test_settracefunc.rb trunk/vm_trace.c Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 51651) +++ include/ruby/ruby.h (revision 51652) @@ -1825,6 +1825,7 @@ int ruby_native_thread_p(void); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1825 #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 */ Index: ChangeLog =================================================================== --- ChangeLog (revision 51651) +++ ChangeLog (revision 51652) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Aug 21 18:49:22 2015 Koichi Sasada <ko1@a...> + + * 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 <ko1@a...> * vm_insnhelper.c (vm_invoke_block): we should not expect ci->argc is Index: vm_trace.c =================================================================== --- vm_trace.c (revision 51651) +++ vm_trace.c (revision 51652) @@ -595,6 +595,7 @@ get_event_id(rb_event_flag_t event) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L595 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) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L701 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) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L1447 * +: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); Index: cont.c =================================================================== --- cont.c (revision 51651) +++ cont.c (revision 51652) @@ -1260,8 +1260,9 @@ rb_fiber_start(void) https://github.com/ruby/ruby/blob/trunk/cont.c#L1260 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, https://github.com/ruby/ruby/blob/trunk/cont.c#L1452 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; } Index: test/ruby/test_settracefunc.rb =================================================================== --- test/ruby/test_settracefunc.rb (revision 51651) +++ test/ruby/test_settracefunc.rb (revision 51652) @@ -1349,4 +1349,55 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ruby/test_settracefunc.rb#L1349 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/