gvltools 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42d6e3f8ea2cc420e17a413a62fba51ccb6c2b90dac11138186e9f4d203bed51
4
- data.tar.gz: 97576f44774bb991699152d36140714b792e17ced8a7ea48d1210f0c8d94b1df
3
+ metadata.gz: 5ffb320bec5fdc8a0d4940d8b370af1607a20383e1a9a8f939cc759588ca6627
4
+ data.tar.gz: 223bee0c124c17296b8386bbdda94406f91b84ad0adcf3acd09921424bb8eaf8
5
5
  SHA512:
6
- metadata.gz: ae23c00ab1f94c2af17753f5ba847690ebea31cb0d3f23134080ad34a475686ac0d9872fa56025a1fab8135c5ee57c58e19675bbc08160c9444a8d30edb847db
7
- data.tar.gz: 54e1694fd5d16935c98a6b838fdf188427cf645f0fe00ac08a7323609c70f01721d9836b80c6bdf2096ee7341d4d39a44f713b20a770470072c72c48887564c3
6
+ metadata.gz: 1c988c2e9d2c17925b178e4201f99530e75328cda648b3e3b50664e1d751ff5ad086139293a22dab5a54ae18e86bdd7d6e14064f4a4833eae18d3d948f134f20
7
+ data.tar.gz: 3b56ad91bf7784d0c61e4d321964eeaaae8ca97ec6c6c86c1934e8e95ad9d720b00933a7b0f7e91ec45e7ffd2a07665800c6f616250b7251318dc889a5ba94ca
data/.rubocop.yml CHANGED
@@ -22,6 +22,15 @@ Style/GlobalVars:
22
22
  Exclude:
23
23
  - ext/**/extconf.rb
24
24
 
25
+ Style/EmptyMethod:
26
+ Enabled: false
27
+
28
+ Style/IfUnlessModifier:
29
+ Enabled: false
30
+
31
+ Style/GuardClause:
32
+ Enabled: false
33
+
25
34
  Style/Documentation:
26
35
  Enabled: false
27
36
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.3.0] - 2023-04-11
4
+
5
+ - Automatically reset the `WaitingThreads` counter when enabling it (#7).
6
+ - Disallow resetting the `WaitingThreads` counter when it is active (#7).
7
+
8
+ ## [0.2.0] - 2023-03-28
9
+
10
+ - Use C11 atomics instead of MRI's `rb_atomic_t`.
11
+
3
12
  ## [0.1.0] - 2022-06-14
4
13
 
5
14
  - Initial release
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gvltools (0.1.0)
4
+ gvltools (0.3.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -32,6 +32,7 @@ GEM
32
32
  unicode-display_width (2.1.0)
33
33
 
34
34
  PLATFORMS
35
+ aarch64-linux
35
36
  arm64-darwin-21
36
37
  arm64-darwin-22
37
38
  x86_64-linux
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "mkmf"
4
- if RUBY_ENGINE == "ruby" && have_func("rb_internal_thread_add_event_hook", ["ruby/thread.h"])
4
+ if RUBY_ENGINE == "ruby" &&
5
+ have_header("stdatomic.h") &&
6
+ have_func("rb_internal_thread_add_event_hook", ["ruby/thread.h"])
7
+
5
8
  $CFLAGS << " -O3 -Wall "
6
9
  create_makefile("gvltools/instrumentation")
7
10
  else
@@ -1,7 +1,9 @@
1
1
  #include <time.h>
2
2
  #include <ruby.h>
3
3
  #include <ruby/thread.h>
4
- #include <ruby/atomic.h>
4
+ #include <stdatomic.h>
5
+
6
+ typedef unsigned long long counter_t;
5
7
 
6
8
  // Metrics
7
9
  static rb_internal_thread_event_hook_t *gt_hook = NULL;
@@ -31,8 +33,8 @@ static inline void gt_gettime(struct timespec *time) {
31
33
  }
32
34
  }
33
35
 
34
- static inline rb_atomic_t gt_time_diff_ns(struct timespec before, struct timespec after) {
35
- rb_atomic_t total = 0;
36
+ static inline counter_t gt_time_diff_ns(struct timespec before, struct timespec after) {
37
+ counter_t total = 0;
36
38
  total += (after.tv_nsec - before.tv_nsec);
37
39
  total += (after.tv_sec - before.tv_sec) * SECONDS_TO_NANOSECONDS;
38
40
  return total;
@@ -67,16 +69,16 @@ static VALUE gt_disable_metric(VALUE module, VALUE metric) {
67
69
  }
68
70
 
69
71
  // GVLTools::LocalTimer and GVLTools::GlobalTimer
70
- static rb_atomic_t global_timer_total = 0;
71
- static THREAD_LOCAL_SPECIFIER uint64_t local_timer_total = 0;
72
+ static _Atomic counter_t global_timer_total = 0;
73
+ static THREAD_LOCAL_SPECIFIER counter_t local_timer_total = 0;
72
74
  static THREAD_LOCAL_SPECIFIER struct timespec timer_ready_at = {0};
73
75
 
74
76
  static VALUE global_timer_monotonic_time(VALUE module) {
75
- return UINT2NUM(global_timer_total);
77
+ return ULL2NUM(global_timer_total);
76
78
  }
77
79
 
78
80
  static VALUE global_timer_reset(VALUE module) {
79
- RUBY_ATOMIC_SET(global_timer_total, 0);
81
+ global_timer_total = 0;
80
82
  return Qtrue;
81
83
  }
82
84
 
@@ -90,14 +92,17 @@ static VALUE local_timer_reset(VALUE module) {
90
92
  }
91
93
 
92
94
  // Thread counts
93
- static rb_atomic_t waiting_threads_total = 0;
95
+ static _Atomic counter_t waiting_threads_total = 0;
96
+ static _Atomic counter_t waiting_threads_current_generation = 1;
97
+ static THREAD_LOCAL_SPECIFIER counter_t waiting_threads_ready_generation = 0;
94
98
 
95
99
  static VALUE waiting_threads_count(VALUE module) {
96
- return UINT2NUM(waiting_threads_total);
100
+ return ULL2NUM(waiting_threads_total);
97
101
  }
98
102
 
99
103
  static VALUE waiting_threads_reset(VALUE module) {
100
- RUBY_ATOMIC_SET(waiting_threads_total, 0);
104
+ waiting_threads_current_generation++;
105
+ waiting_threads_total = 0;
101
106
  return Qtrue;
102
107
  }
103
108
 
@@ -120,7 +125,8 @@ static void gt_thread_callback(rb_event_flag_t event, const rb_internal_thread_e
120
125
  if (!was_ready) was_ready = true;
121
126
 
122
127
  if (ENABLED(WAITING_THREADS)) {
123
- RUBY_ATOMIC_INC(waiting_threads_total);
128
+ waiting_threads_ready_generation = waiting_threads_current_generation;
129
+ waiting_threads_total++;
124
130
  }
125
131
 
126
132
  if (ENABLED(TIMER_GLOBAL | TIMER_LOCAL)) {
@@ -132,20 +138,22 @@ static void gt_thread_callback(rb_event_flag_t event, const rb_internal_thread_e
132
138
  if (!was_ready) break; // In case we registered the hook while some threads were already waiting on the GVL
133
139
 
134
140
  if (ENABLED(WAITING_THREADS)) {
135
- RUBY_ATOMIC_DEC(waiting_threads_total);
141
+ if (waiting_threads_ready_generation == waiting_threads_current_generation) {
142
+ waiting_threads_total--;
143
+ }
136
144
  }
137
145
 
138
146
  if (ENABLED(TIMER_GLOBAL | TIMER_LOCAL)) {
139
147
  struct timespec current_time;
140
148
  gt_gettime(&current_time);
141
- rb_atomic_t diff = gt_time_diff_ns(timer_ready_at, current_time);
149
+ counter_t diff = gt_time_diff_ns(timer_ready_at, current_time);
142
150
 
143
151
  if (ENABLED(TIMER_LOCAL)) {
144
152
  local_timer_total += diff;
145
153
  }
146
154
 
147
155
  if (ENABLED(TIMER_GLOBAL)) {
148
- RUBY_ATOMIC_ADD(global_timer_total, diff);
156
+ global_timer_total += diff;
149
157
  }
150
158
  }
151
159
  }
@@ -170,6 +178,6 @@ void Init_instrumentation(void) {
170
178
  rb_define_singleton_method(rb_mLocalTimer, "monotonic_time", local_timer_monotonic_time, 0);
171
179
 
172
180
  VALUE rb_mWaitingThreads = rb_const_get(rb_mGVLTools, rb_intern("WaitingThreads"));
173
- rb_define_singleton_method(rb_mWaitingThreads, "reset", waiting_threads_reset, 0);
181
+ rb_define_singleton_method(rb_mWaitingThreads, "_reset", waiting_threads_reset, 0);
174
182
  rb_define_singleton_method(rb_mWaitingThreads, "count", waiting_threads_count, 0);
175
183
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GVLTools
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/gvltools.rb CHANGED
@@ -96,8 +96,27 @@ module GVLTools
96
96
  end
97
97
  alias_method :count, :count
98
98
 
99
+ def enable
100
+ unless enabled?
101
+ reset
102
+ end
103
+ super
104
+ end
105
+
106
+ def reset
107
+ if enabled?
108
+ raise Error, "can't reset WaitingThreads counter while it is active"
109
+ else
110
+ _reset
111
+ end
112
+ end
113
+
99
114
  private
100
115
 
116
+ def _reset
117
+ end
118
+ alias_method :_reset, :_reset # to be redefined from C.
119
+
101
120
  def metric
102
121
  WAITING_THREADS
103
122
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gvltools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-17 00:00:00.000000000 Z
11
+ date: 2023-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -67,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  requirements: []
70
- rubygems_version: 3.4.1
70
+ rubygems_version: 3.4.10
71
71
  signing_key:
72
72
  specification_version: 4
73
73
  summary: Set of GVL instrumentation tools