Simplify implementation of tracepoint tests

With the latest version of the postponed job patchset merged, we don't
actually need to go through the contortions of keeping the data in a
global variable; we can just update `data` with multiple calls to
rb_postponed_job_preregister.
This commit is contained in:
KJ Tsanaktsidis 2023-12-11 15:09:05 +11:00 committed by KJ Tsanaktsidis
parent 4eefab592a
commit 15d14e2f39

View File

@ -2,11 +2,6 @@
#include "ruby/debug.h" #include "ruby/debug.h"
static int invoking; /* TODO: should not be global variable */ static int invoking; /* TODO: should not be global variable */
static VALUE gc_start_proc;
static VALUE gc_end_proc;
static rb_postponed_job_handle_t invoking_proc_pjob;
static bool pjob_execute_gc_start_proc_p;
static bool pjob_execute_gc_end_proc_p;
static VALUE static VALUE
invoke_proc_ensure(VALUE _) invoke_proc_ensure(VALUE _)
@ -22,35 +17,25 @@ invoke_proc_begin(VALUE proc)
} }
static void static void
invoke_proc(void *unused) invoke_proc(void *data)
{ {
if (pjob_execute_gc_start_proc_p) { VALUE proc = (VALUE)data;
pjob_execute_gc_start_proc_p = false; invoking += 1;
invoking += 1; rb_ensure(invoke_proc_begin, proc, invoke_proc_ensure, 0);
rb_ensure(invoke_proc_begin, gc_start_proc, invoke_proc_ensure, 0);
}
if (pjob_execute_gc_end_proc_p) {
pjob_execute_gc_end_proc_p = false;
invoking += 1;
rb_ensure(invoke_proc_begin, gc_end_proc, invoke_proc_ensure, 0);
}
} }
static void static void
gc_start_end_i(VALUE tpval, void *data) gc_start_end_i(VALUE tpval, void *data)
{ {
rb_trace_arg_t *tparg = rb_tracearg_from_tracepoint(tpval);
if (0) { if (0) {
rb_trace_arg_t *tparg = rb_tracearg_from_tracepoint(tpval);
fprintf(stderr, "trace: %s\n", rb_tracearg_event_flag(tparg) == RUBY_INTERNAL_EVENT_GC_START ? "gc_start" : "gc_end"); fprintf(stderr, "trace: %s\n", rb_tracearg_event_flag(tparg) == RUBY_INTERNAL_EVENT_GC_START ? "gc_start" : "gc_end");
} }
if (invoking == 0) { if (invoking == 0) {
if (rb_tracearg_event_flag(tparg) == RUBY_INTERNAL_EVENT_GC_START) { /* will overwrite the existing handle with new data on the second and subsequent call */
pjob_execute_gc_start_proc_p = true; rb_postponed_job_handle_t h = rb_postponed_job_preregister(0, invoke_proc, data);
} else { rb_postponed_job_trigger(h);
pjob_execute_gc_end_proc_p = true;
}
rb_postponed_job_trigger(invoking_proc_pjob);
} }
} }
@ -71,13 +56,8 @@ set_gc_hook(VALUE module, VALUE proc, rb_event_flag_t event, const char *tp_str,
if (!rb_obj_is_proc(proc)) { if (!rb_obj_is_proc(proc)) {
rb_raise(rb_eTypeError, "trace_func needs to be Proc"); rb_raise(rb_eTypeError, "trace_func needs to be Proc");
} }
if (event == RUBY_INTERNAL_EVENT_GC_START) {
gc_start_proc = proc;
} else {
gc_end_proc = proc;
}
tpval = rb_tracepoint_new(0, event, gc_start_end_i, 0); tpval = rb_tracepoint_new(0, event, gc_start_end_i, (void *)proc);
rb_ivar_set(module, tp_key, tpval); rb_ivar_set(module, tp_key, tpval);
rb_tracepoint_enable(tpval); rb_tracepoint_enable(tpval);
} }
@ -104,10 +84,4 @@ Init_gc_hook(VALUE module)
{ {
rb_define_module_function(module, "after_gc_start_hook=", set_after_gc_start, 1); rb_define_module_function(module, "after_gc_start_hook=", set_after_gc_start, 1);
rb_define_module_function(module, "after_gc_exit_hook=", start_after_gc_exit, 1); rb_define_module_function(module, "after_gc_exit_hook=", start_after_gc_exit, 1);
rb_gc_register_address(&gc_start_proc);
rb_gc_register_address(&gc_end_proc);
invoking_proc_pjob = rb_postponed_job_preregister(0, invoke_proc, NULL);
if (invoking_proc_pjob == POSTPONED_JOB_HANDLE_INVALID) {
rb_raise(rb_eStandardError, "could not preregister invoke_proc");
}
} }