gvl_timing 0.1.2 → 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 +4 -4
- data/README.md +17 -11
- data/ext/gvl_timing/extconf.rb +3 -0
- data/ext/gvl_timing/gvl_timing.c +26 -11
- data/lib/gvl_timing/version.rb +1 -1
- data/lib/gvl_timing.rb +48 -9
- metadata +5 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11943fd2bd229bb71b905436ff49735fa683355107e773798a0c265e91dc51c9
|
4
|
+
data.tar.gz: 28e2c52c9d4aa6eb9d9346c4bf85398c41d70f7cd8dfd70699f3618340779979
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca21dea3e3d9d8bc9b4c46a76c32d33aa7e501f4b56c28f4543e46374e8e5341d90950dc18381f841011fd65cfbc4a47df280e5cec6297655991300574d31ac4
|
7
|
+
data.tar.gz: dfa75b00eac2c2c0e23d9c4acbb816a6c3f18224405bfacf40345c6d9d59e0ab22691f3697f70934ca13387520f050aa7d8fc3d706c1d6a2a1bc52cabc34b348
|
data/README.md
CHANGED
@@ -1,24 +1,30 @@
|
|
1
|
-
#
|
1
|
+
# gvl\_timing
|
2
2
|
|
3
|
-
|
3
|
+
Measures timings for the current thread's GVL state for CRuby.
|
4
4
|
|
5
|
-
|
5
|
+
This will add some (small) overhead to all GVL activity, so may be better to
|
6
|
+
development/test or sampled use rather than continuous timing.
|
6
7
|
|
7
8
|
## Installation
|
8
9
|
|
9
|
-
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
10
|
-
|
11
10
|
Install the gem and add to the application's Gemfile by executing:
|
12
11
|
|
13
|
-
$ bundle add
|
14
|
-
|
15
|
-
If bundler is not being used to manage dependencies, install the gem by executing:
|
16
|
-
|
17
|
-
$ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
12
|
+
$ bundle add gvl_timing
|
18
13
|
|
19
14
|
## Usage
|
20
15
|
|
21
|
-
|
16
|
+
```
|
17
|
+
>> timer = GVLTiming.measure { sleep 0.1 }
|
18
|
+
=> #<GVLTiming::Timer total=0.10s running=0.00s idle=0.10s stalled=0.00s>
|
19
|
+
>> timer.duration
|
20
|
+
=> 0.101082
|
21
|
+
>> timer.cpu_duration
|
22
|
+
=> 7.4667e-05
|
23
|
+
>> timer.idle_duration
|
24
|
+
=> 0.101048
|
25
|
+
>> timer.stalled_duration
|
26
|
+
=> 1.0e-06
|
27
|
+
```
|
22
28
|
|
23
29
|
## Development
|
24
30
|
|
data/ext/gvl_timing/extconf.rb
CHANGED
data/ext/gvl_timing/gvl_timing.c
CHANGED
@@ -26,6 +26,8 @@ struct gvl_timer {
|
|
26
26
|
uint64_t cputime_start;
|
27
27
|
uint64_t cputime_stop;
|
28
28
|
|
29
|
+
uint64_t yields_count;
|
30
|
+
|
29
31
|
uint64_t prev_timestamp;
|
30
32
|
enum ruby_gvl_state prev_state;
|
31
33
|
VALUE thread;
|
@@ -40,16 +42,23 @@ void record_timing(struct gvl_timer *timer, enum ruby_gvl_state new_state) {
|
|
40
42
|
timer->timings[timer->prev_state] += (timestamp - timer->prev_timestamp);
|
41
43
|
timer->prev_timestamp = timestamp;
|
42
44
|
timer->prev_state = new_state;
|
45
|
+
|
46
|
+
if (new_state == GVL_STATE_IDLE) {
|
47
|
+
timer->yields_count++;
|
48
|
+
}
|
49
|
+
|
43
50
|
}
|
44
51
|
|
45
52
|
void internal_thread_event_cb(rb_event_flag_t event, const rb_internal_thread_event_data_t *event_data, void *data) {
|
46
53
|
struct gvl_timer *timer = data;
|
47
54
|
|
55
|
+
VALUE thread;
|
56
|
+
#if HAVE_RB_INTERNAL_THREAD_EVENT_DATA_T_THREAD
|
57
|
+
thread = event_data->thread;
|
58
|
+
#else
|
48
59
|
if (!ruby_native_thread_p()) return;
|
49
|
-
|
50
|
-
|
51
|
-
//#else
|
52
|
-
//#endif
|
60
|
+
thread = rb_thread_current();
|
61
|
+
#endif
|
53
62
|
if (thread != timer->thread) {
|
54
63
|
return;
|
55
64
|
}
|
@@ -150,6 +159,10 @@ VALUE gvl_timer_idle_duration(VALUE obj) {
|
|
150
159
|
return ULL2NUM(get_timer(obj)->timings[GVL_STATE_IDLE]);
|
151
160
|
}
|
152
161
|
|
162
|
+
VALUE gvl_timer_yields_count(VALUE obj) {
|
163
|
+
return ULL2NUM(get_timer(obj)->yields_count);
|
164
|
+
}
|
165
|
+
|
153
166
|
RUBY_FUNC_EXPORTED void
|
154
167
|
Init_gvl_timing(void)
|
155
168
|
{
|
@@ -159,12 +172,14 @@ Init_gvl_timing(void)
|
|
159
172
|
rb_define_method(rb_cTimer, "start", gvl_timer_start, 0);
|
160
173
|
rb_define_method(rb_cTimer, "stop", gvl_timer_stop, 0);
|
161
174
|
|
162
|
-
rb_define_method(rb_cTimer, "
|
163
|
-
rb_define_method(rb_cTimer, "
|
164
|
-
rb_define_method(rb_cTimer, "
|
165
|
-
rb_define_method(rb_cTimer, "
|
175
|
+
rb_define_method(rb_cTimer, "monotonic_start_ns", gvl_timer_monotonic_start, 0);
|
176
|
+
rb_define_method(rb_cTimer, "monotonic_stop_ns", gvl_timer_monotonic_stop, 0);
|
177
|
+
rb_define_method(rb_cTimer, "cputime_start_ns", gvl_timer_cputime_start, 0);
|
178
|
+
rb_define_method(rb_cTimer, "cputime_stop_ns", gvl_timer_cputime_stop, 0);
|
179
|
+
|
180
|
+
rb_define_method(rb_cTimer, "running_duration_ns", gvl_timer_running_duration, 0);
|
181
|
+
rb_define_method(rb_cTimer, "stalled_duration_ns", gvl_timer_stalled_duration, 0);
|
182
|
+
rb_define_method(rb_cTimer, "idle_duration_ns", gvl_timer_idle_duration, 0);
|
166
183
|
|
167
|
-
rb_define_method(rb_cTimer, "
|
168
|
-
rb_define_method(rb_cTimer, "stalled_duration", gvl_timer_stalled_duration, 0);
|
169
|
-
rb_define_method(rb_cTimer, "idle_duration", gvl_timer_idle_duration, 0);
|
184
|
+
rb_define_method(rb_cTimer, "yields_count", gvl_timer_yields_count, 0);
|
170
185
|
}
|
data/lib/gvl_timing/version.rb
CHANGED
data/lib/gvl_timing.rb
CHANGED
@@ -20,21 +20,60 @@ module GVLTiming
|
|
20
20
|
class Timer
|
21
21
|
NANOSECONDS_PER_SECOND_F = 1000000000.0
|
22
22
|
|
23
|
-
def
|
24
|
-
|
23
|
+
def duration_ns
|
24
|
+
monotonic_stop_ns - monotonic_start_ns
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def cpu_duration_ns
|
28
|
+
cputime_stop_ns - cputime_start_ns
|
29
29
|
end
|
30
30
|
|
31
|
+
[
|
32
|
+
:duration, :cpu_duration,
|
33
|
+
:monotonic_start, :monotonic_stop,
|
34
|
+
:cputime_start, :cputime_stop,
|
35
|
+
:running_duration, :stalled_duration, :idle_duration
|
36
|
+
].each do |name|
|
37
|
+
class_eval <<~RUBY
|
38
|
+
def #{name}(unit = :float_second)
|
39
|
+
scale_ns(#{name}_ns, unit)
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
|
44
|
+
alias releases_count yields_count
|
45
|
+
|
31
46
|
def inspect
|
32
|
-
"#<#{self.class} total=%.2fs running=%.2fs idle=%.2fs stalled=%.2fs>" % [
|
33
|
-
duration
|
34
|
-
running_duration
|
35
|
-
idle_duration
|
36
|
-
stalled_duration
|
47
|
+
"#<#{self.class} total=%.2fs running=%.2fs idle=%.2fs stalled=%.2fs yields=%d>" % [
|
48
|
+
duration,
|
49
|
+
running_duration,
|
50
|
+
idle_duration,
|
51
|
+
stalled_duration,
|
52
|
+
yields_count,
|
37
53
|
]
|
38
54
|
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def scale_ns(value_ns, unit)
|
59
|
+
case unit
|
60
|
+
when :float_second
|
61
|
+
value_ns / 1_000_000_000.0
|
62
|
+
when :float_millisecond
|
63
|
+
value_ns / 1_000_000.0
|
64
|
+
when :float_microsecond
|
65
|
+
value_ns / 1000.0
|
66
|
+
when :second
|
67
|
+
value_ns / 1_000_000_000
|
68
|
+
when :millisecond
|
69
|
+
value_ns / 1_000_000
|
70
|
+
when :microsecond
|
71
|
+
value_ns / 1000
|
72
|
+
when :nanosecond
|
73
|
+
value_ns
|
74
|
+
else
|
75
|
+
raise ArgumentError, "unexpected unit: #{unit.inspect}"
|
76
|
+
end
|
77
|
+
end
|
39
78
|
end
|
40
79
|
end
|
metadata
CHANGED
@@ -1,16 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gvl_timing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hawthorn
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-04-18 00:00:00.000000000 Z
|
12
11
|
dependencies: []
|
13
|
-
description:
|
12
|
+
description: Measure time spent in different GVL states
|
14
13
|
email:
|
15
14
|
- john@hawthorn.email
|
16
15
|
executables:
|
@@ -36,7 +35,6 @@ metadata:
|
|
36
35
|
homepage_uri: https://github.com/jhawthorn/gvl_timing
|
37
36
|
source_code_uri: https://github.com/jhawthorn/gvl_timing
|
38
37
|
changelog_uri: https://github.com/jhawthorn/gvl_timing
|
39
|
-
post_install_message:
|
40
38
|
rdoc_options: []
|
41
39
|
require_paths:
|
42
40
|
- lib
|
@@ -51,8 +49,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
49
|
- !ruby/object:Gem::Version
|
52
50
|
version: '0'
|
53
51
|
requirements: []
|
54
|
-
rubygems_version: 3.
|
55
|
-
signing_key:
|
52
|
+
rubygems_version: 3.6.2
|
56
53
|
specification_version: 4
|
57
|
-
summary:
|
54
|
+
summary: Measure time spent in different GVL states
|
58
55
|
test_files: []
|