зеркало из https://github.com/github/ruby.git
* 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:
Родитель
416aa45918
Коммит
3af5298e8c
|
@ -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
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче