pf2 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29a7c92a2a313dec57af9a3427cd723224f64bf53cf74a488253741e1098c12d
4
- data.tar.gz: 4958d188fdddec9fb8143a1b864e9c40d989bbb3360745eb0846687cefc97b9d
3
+ metadata.gz: 66bf1eb8d6457621a04819a8d100bdb109bf1fd7b4820eb1423a85dcfb91799c
4
+ data.tar.gz: b1046c04ae8a2a0630d3bd2ed86c4dc645a9ca42c8038bfaaee0be4c71dbec78
5
5
  SHA512:
6
- metadata.gz: 2a2a7ecd0a4cb0d84f022c3ec1e0844e2c537cfad88f91b0051609006d8c2f4d596f15a1fd259709c97c1ffccbae87e96758a4bcfb70293d88fb44d7888f4071
7
- data.tar.gz: 28b108cd63c75d7ead6f34fdd88fdaa867a9601a0217899b024176a4e5508ef9dec7395bf7ae77513de6eb4cc765be90e010146bdd114b989b33359e4ac55068
6
+ metadata.gz: 5e8854a44c477c42dc9baa0a5b2cd95e19cd09a3c41fad0e950e7de6bd88ff90bf6a3d8e7b61c43c966976211047d5ecb6da11fbe5cba6460ab456186856e2b8
7
+ data.tar.gz: 8d577d2502f38dab61d3ab130f2555b314667c414ec13b2829f2e7fdf0ddf1f114310d560806685145e5ce65f7f24cc50f834f9fc6eb2b1e0d7763b8ebe69d5f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.2] - 2024-07-13
4
+
5
+ ### Fixed
6
+
7
+ - Properly default to TimerThread scheduler on non-Linux environments.
8
+
3
9
 
4
10
  ## [0.5.1] - 2024-03-25
5
11
 
data/README.md CHANGED
@@ -58,7 +58,7 @@ File.write("my_program.pf2profile", profile)
58
58
  Profiles can be visualized using the [Firefox Profiler](https://profiler.firefox.com/).
59
59
 
60
60
  ```console
61
- $ pf2 -o report.json my_program.pf2profile
61
+ $ pf2 report -o report.json my_program.pf2profile
62
62
  ```
63
63
 
64
64
  ### Configuration
@@ -108,9 +108,9 @@ Schedulers determine when to execute sample collection, based on configuration (
108
108
 
109
109
  #### SignalScheduler (Linux-only)
110
110
 
111
- The first is the `SignalScheduler`, based on POSIX timers. Pf2 will use this scheduler when possible. SignalScheduler creates a POSIX timer for each Ruby Thread (the underlying pthread to be more accurate) using `timer_create(3)`. This leaves the actual time-keeping to the OS, which is capable of tracking accurate per-thread CPU time usage.
111
+ The first is the `SignalScheduler`, based on POSIX timers. Pf2 will use this scheduler when possible. SignalScheduler creates a POSIX timer for each Ruby Thread (the underlying pthread to be more accurate) using `timer_create(2)`. This leaves the actual time-keeping to the OS, which is capable of tracking accurate per-thread CPU time usage.
112
112
 
113
- When the specified interval has arrived (the timer has _expired_), the OS delivers us a SIGALRM (note: Unlike `setitimer(2)`, `timer_create(3)` allows us to choose which signal to be delivered, and Pf2 uses SIGALRM regardless of time mode). This is why the scheduler is named SignalScheduler.
113
+ When the specified interval has arrived (the timer has _expired_), the OS delivers us a SIGALRM (note: Unlike `setitimer(2)`, `timer_create(2)` allows us to choose which signal to be delivered, and Pf2 uses SIGALRM regardless of time mode). This is why the scheduler is named SignalScheduler.
114
114
 
115
115
  Signals are directed to Ruby Threads' underlying pthread, effectively "pausing" the Thread's activity. This routing is done using `SIGEV_THREAD_ID`, which is a Linux-only feature. Sample collection is done in the signal handler, which is expected to be more _accurate_, capturing the paused Thread's activity.
116
116
 
@@ -6,9 +6,16 @@ use rb_sys::*;
6
6
 
7
7
  use crate::util::cstr;
8
8
 
9
+ #[cfg(target_os = "linux")]
9
10
  pub const DEFAULT_SCHEDULER: Scheduler = Scheduler::Signal;
10
- pub const DEFAULT_INTERVAL: Duration = Duration::from_millis(49);
11
+ #[cfg(target_os = "linux")]
11
12
  pub const DEFAULT_TIME_MODE: TimeMode = TimeMode::CpuTime;
13
+ #[cfg(not(target_os = "linux"))]
14
+ pub const DEFAULT_SCHEDULER: Scheduler = Scheduler::TimerThread;
15
+ #[cfg(not(target_os = "linux"))]
16
+ pub const DEFAULT_TIME_MODE: TimeMode = TimeMode::WallTime;
17
+
18
+ pub const DEFAULT_INTERVAL: Duration = Duration::from_millis(49);
12
19
 
13
20
  #[derive(Clone, Debug)]
14
21
  pub struct Configuration {
@@ -1,7 +1,7 @@
1
1
  use std::ffi::{c_int, c_void};
2
2
  use std::mem;
3
3
  use std::mem::ManuallyDrop;
4
- use std::ptr::null_mut;
4
+ use std::ptr::{addr_of, null_mut};
5
5
 
6
6
  use rb_sys::*;
7
7
 
@@ -43,7 +43,7 @@ impl SessionRubyObject {
43
43
  // Extract the SessionRubyObject struct from a Ruby object
44
44
  unsafe fn get_struct_from(obj: VALUE) -> ManuallyDrop<Box<Self>> {
45
45
  unsafe {
46
- let ptr = rb_check_typeddata(obj, &RBDATA);
46
+ let ptr = rb_check_typeddata(obj, addr_of!(RBDATA));
47
47
  ManuallyDrop::new(Box::from_raw(ptr as *mut SessionRubyObject))
48
48
  }
49
49
  }
@@ -55,7 +55,11 @@ impl SessionRubyObject {
55
55
  let rb_mPf2: VALUE = rb_define_module(cstr!("Pf2"));
56
56
  let rb_cSession = rb_define_class_under(rb_mPf2, cstr!("Session"), rb_cObject);
57
57
  // Wrap the struct into a Ruby object
58
- rb_data_typed_object_wrap(rb_cSession, Box::into_raw(obj) as *mut c_void, &RBDATA)
58
+ rb_data_typed_object_wrap(
59
+ rb_cSession,
60
+ Box::into_raw(obj) as *mut c_void,
61
+ addr_of!(RBDATA),
62
+ )
59
63
  }
60
64
 
61
65
  unsafe extern "C" fn dmark(ptr: *mut c_void) {
@@ -93,12 +93,17 @@ impl Session {
93
93
  )),
94
94
  };
95
95
 
96
+ let running = Arc::new(AtomicBool::new(false));
97
+
96
98
  let new_thread_watcher = match threads {
97
99
  configuration::Threads::All => {
98
100
  let scheduler = Arc::clone(&scheduler);
101
+ let running = Arc::clone(&running);
99
102
  Some(NewThreadWatcher::watch(move |thread: VALUE| {
100
- log::debug!("New Ruby thread detected: {:?}", thread);
101
- scheduler.on_new_thread(thread);
103
+ if running.load(Ordering::Relaxed) {
104
+ log::debug!("New Ruby thread detected: {:?}", thread);
105
+ scheduler.on_new_thread(thread);
106
+ }
102
107
  }))
103
108
  }
104
109
  configuration::Threads::Targeted(_) => None,
@@ -108,7 +113,7 @@ impl Session {
108
113
  configuration,
109
114
  scheduler,
110
115
  profile,
111
- running: Arc::new(AtomicBool::new(false)),
116
+ running,
112
117
  new_thread_watcher,
113
118
  }
114
119
  }
@@ -103,6 +103,7 @@ impl SignalScheduler {
103
103
  if err != 0 {
104
104
  panic!("sigaction failed: {}", err);
105
105
  }
106
+ log::debug!("Signal handler installed");
106
107
  }
107
108
 
108
109
  // Respond to the signal and collect a sample.
data/lib/pf2/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Pf2
2
- VERSION = '0.5.1'
2
+ VERSION = '0.5.2'
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pf2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daisuke Aritomo
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2024-03-24 00:00:00.000000000 Z
10
+ date: 2024-07-12 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rake-compiler