-
Notifications
You must be signed in to change notification settings - Fork 7
Rework and simplify internals #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This change simplifies Builder's internals and makes it harder to misuse. It also makes tracepoint support explicit, and an example of working tracepoints is supplied. Finally, I took a dependency on this error to generate some previously hand-written code.
| ), | ||
| }; | ||
|
|
||
| debug_assert!(!(pid == -1 && cpu == -1)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, it was too easy to accidentally set this combination, and there was nothing of diagnostic usefulness in the kernel's error message.
| event_data: data, | ||
| }; | ||
|
|
||
| builder.enabled(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Events that actually need these values now set them. So, existing code continues to work!
| } | ||
|
|
||
| /// Which CPU and PID to target. | ||
| pub fn targeting(&mut self, cpu_pid: CpuPid) -> &mut Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's impossible to pass invalid options to this method. So, you no longer need to fiddle with combinations of other cpu and pid methods. Just ask for what you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I'm not going to have time to give it a proper review until next week (as I'll be out camping) but I've given the PR (and your blog post!) a skim and I'm gonna drop some initial comments here.
So for some initial remarks:
- You've definitely run into a papercut/footgun with the tracepoint. That's definitely somthing that should be fixed. I'm somewhat inclined to update the docs here as opposed to implicitly setting options that no other event type sets. I will admit that your experience is a strong point in the other direction. I'll think about this more.
- I really do like the new builder method. It is a good addition.
- It appears that I've missed some methods on the various error types. I'll get that fixed.
Now onto issues I see:
- Adding
'staticto theEventDatatrait is a breaking change. I'm not entirely sure I want to do that just yet. - I would rather the builder remain cloneable as opposed to removing the lifetime.
- The same applies to changing the defaults of the builder. I don't particularly like the defaults but changing them like this is a dangerous breaking change because there's no outward sign that users of this library would have to change their code to work with it.
Tracepointshould at a minimum document what other things it is changing on the builder.- I don't think it's worth it to pull in
thiserrorfor this. I have tried quite hard to keep the dependency count down forperf-event2andsynis a rather heavy dependency for a crate like this.
In that case let me suggest a major version bump. Hard to use APIs can be deprecated. Breakages can be clearly advertised. That makes none of these breaking changes dangerous. I have deliberately introduced breaking changes because I consider the existing behavior to be buggy. Yes, you can figure out the right combination of flags by reading let mut sampler = Builder::new(tp)
.sample_period(1)
.build()?
.sampled(8192)?;Instead, you have to do this: let mut sampler = Builder::new(tp)
.any_pid()
.one_cpu(1)
.include_kernel()
.sample(SampleFlag::RAW)
.sample_period(1)
.build()?
.sampled(8192)?;Do you want to make these APIs more user friendly in a way that is clearly advertised as a breaking change? There are only three dependents on crates.io.
I would ask that you reconsider. |
I've updated the code so that |
|
I've bumped the version number because I think these breaking changes are useful enough to justify. Nobody depending on |
Added better docs and some examples. |
Ah, just to clarify, I also changed the implementations of the other |
| /// This is automatically implemented for any type which is both `Send` and | ||
| /// `Sync`. | ||
| pub trait EventData: Send + Sync {} | ||
| pub trait EventData: Send + Sync + 'static {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I consider this a sensible breaking change.
This change fixes a few things in one go. I wrote up a blog post on my adventures with this crate: https://roci.co.za/posts/hunting-bugs-in-perf-event2
Eventwere not being respected. This is now fixed. More importantly, the events in this crate now set sensible defaults. For instance, static kernel tracepoints are intrinsically kernel-level events, so they are now automatically marked as such. This fixes the bug wherepollhung indefinitely when asking for a tracepoint. Tracepoints now work out of the box. If anyone needs to explicitly set these parameters back to the non-sensible defaults, they still can.thiserrorcould generate, and took a dependency on it.Builderto carry a lifetime. This works because on Linux you can liberally and infallibly clone file descriptors pointing at cgroups.EventData, because non-static lifetimes cannot reasonably be justified.