summaryrefslogtreecommitdiff
path: root/ext/-test-
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2022-07-07 15:20:35 +0200
committerJean Boussier <jean.boussier@gmail.com>2022-07-07 17:49:00 +0200
commit587d2d199b3f783d03266d42d066949f8a4824d3 (patch)
tree6977cca9dc954a2fa4a87dc1b7f1f0aa5bc8786b /ext/-test-
parent61c7ae4d27d44b19b39fa240cf7edda2eeefc92d (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.c30
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);