* 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
This commit is contained in:
ko1 2015-08-21 09:51:01 +00:00
Родитель 416aa45918
Коммит 3af5298e8c
5 изменённых файлов: 68 добавлений и 1 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Fri Aug 21 18:49:22 2015 Koichi Sasada <ko1@atdot.net>
* 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@atdot.net>
* vm_insnhelper.c (vm_invoke_block): we should not expect ci->argc is

5
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;
}

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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

Просмотреть файл

@ -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);