diff options
author | Jean Boussier <jean.boussier@gmail.com> | 2022-07-07 15:20:35 +0200 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2022-07-07 17:49:00 +0200 |
commit | 587d2d199b3f783d03266d42d066949f8a4824d3 (patch) | |
tree | 6977cca9dc954a2fa4a87dc1b7f1f0aa5bc8786b /ext/-test- | |
parent | 61c7ae4d27d44b19b39fa240cf7edda2eeefc92d (diff) |
thread_pthread.c: call SUSPENDED event when entering native_sleep
[Bug #18900]
Thread#join and a few other codepaths are using native sleep as
a way to suspend the current thread. So we should call the relevant
hook when this happen, otherwise some thread may transition
directly from `RESUMED` to `READY`.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6101
Diffstat (limited to 'ext/-test-')
-rw-r--r-- | ext/-test-/thread/instrumentation/instrumentation.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/ext/-test-/thread/instrumentation/instrumentation.c b/ext/-test-/thread/instrumentation/instrumentation.c index 517af7e339..2bbce1179a 100644 --- a/ext/-test-/thread/instrumentation/instrumentation.c +++ b/ext/-test-/thread/instrumentation/instrumentation.c @@ -8,6 +8,19 @@ static rb_atomic_t resumed_count = 0; static rb_atomic_t suspended_count = 0; static rb_atomic_t exited_count = 0; +#if __STDC_VERSION__ >= 201112 + #define RB_THREAD_LOCAL_SPECIFIER _Thread_local +#elif defined(__GNUC__) && !defined(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED) + /* note that ICC (linux) and Clang are covered by __GNUC__ */ + #define RB_THREAD_LOCAL_SPECIFIER __thread +#else + #define RB_THREAD_LOCAL_SPECIFIER +#endif + +static RB_THREAD_LOCAL_SPECIFIER unsigned int local_ready_count = 0; +static RB_THREAD_LOCAL_SPECIFIER unsigned int local_resumed_count = 0; +static RB_THREAD_LOCAL_SPECIFIER unsigned int local_suspended_count = 0; + void ex_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *user_data) { @@ -17,12 +30,15 @@ ex_callback(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_ break; case RUBY_INTERNAL_THREAD_EVENT_READY: RUBY_ATOMIC_INC(ready_count); + local_ready_count++; break; case RUBY_INTERNAL_THREAD_EVENT_RESUMED: RUBY_ATOMIC_INC(resumed_count); + local_resumed_count++; break; case RUBY_INTERNAL_THREAD_EVENT_SUSPENDED: RUBY_ATOMIC_INC(suspended_count); + local_suspended_count++; break; case RUBY_INTERNAL_THREAD_EVENT_EXITED: RUBY_ATOMIC_INC(exited_count); @@ -45,6 +61,16 @@ thread_counters(VALUE thread) } static VALUE +thread_local_counters(VALUE thread) +{ + VALUE array = rb_ary_new2(3); + rb_ary_push(array, UINT2NUM(local_ready_count)); + rb_ary_push(array, UINT2NUM(local_resumed_count)); + rb_ary_push(array, UINT2NUM(local_suspended_count)); + return array; +} + +static VALUE thread_reset_counters(VALUE thread) { RUBY_ATOMIC_SET(started_count, 0); @@ -52,6 +78,9 @@ thread_reset_counters(VALUE thread) RUBY_ATOMIC_SET(resumed_count, 0); RUBY_ATOMIC_SET(suspended_count, 0); RUBY_ATOMIC_SET(exited_count, 0); + local_ready_count = 0; + local_resumed_count = 0; + local_suspended_count = 0; return Qtrue; } @@ -104,6 +133,7 @@ Init_instrumentation(void) VALUE mBug = rb_define_module("Bug"); VALUE klass = rb_define_module_under(mBug, "ThreadInstrumentation"); rb_define_singleton_method(klass, "counters", thread_counters, 0); + rb_define_singleton_method(klass, "local_counters", thread_local_counters, 0); rb_define_singleton_method(klass, "reset_counters", thread_reset_counters, 0); rb_define_singleton_method(klass, "register_callback", thread_register_callback, 0); rb_define_singleton_method(klass, "unregister_callback", thread_unregister_callback, 0); |