-
Notifications
You must be signed in to change notification settings - Fork 166
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
ringbuf: Add event counters #1621
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
7791354
ringbuf: Add event counters (#1621)
hawkw 3504b41
gimlet-seq: Count ringbuf events (#1621)
hawkw 8b8b7a1
ringbuf: generate structs for event counters (#1621)
hawkw 8ab3ae6
ringbuf: fix test build on non-ARM
hawkw f046ba0
ringbuf: get rid of separate `count_entry!` macro (#1621)
hawkw 3714c19
ringbuf: remove `concat_idents!` proc-macros (#1621)
hawkw d6c275b
fix example breaking with `cargo test --workspace`
hawkw 474239b
ringbuf: dispatch counting using a trait instead
hawkw 6c02a7b
whoops, actually unwrap results in hiffy/build.rs
hawkw 71e6013
don't inline stuff
hawkw f10abb6
don't derive `Debug` for counter types
hawkw 82771e3
wip attempt to monomorphize less
hawkw a785972
whoops, that got eaten in the rebase
hawkw 2379114
rm "disabled" from derive crate
hawkw 51db96b
add documentation
hawkw 2d41888
Merge branch 'master' into eliza/ringbuf-counts
hawkw adeba16
undo rebase mistake
hawkw d5f8d5c
fixup some names in the derive crate
hawkw File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
//! Demonstrates the use of `counted_ringbuf!` and friends. | ||
hawkw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
//! | ||
//! This example is primarily intended to be used with `cargo expand` to show | ||
//! the macro-generated code for `#[derive(ringbuf::Count)]` and friends. | ||
use ringbuf::*; | ||
|
||
#[derive(ringbuf::Count, Debug, Copy, Clone, PartialEq, Eq)] | ||
pub enum Event { | ||
NothingHappened, | ||
SomethingHappened, | ||
SomethingElse(u32), | ||
SecretThirdThing { secret: () }, | ||
} | ||
|
||
counted_ringbuf!(Event, 16, Event::NothingHappened); | ||
counted_ringbuf!(MY_NAMED_RINGBUF, Event, 16, Event::NothingHappened); | ||
|
||
ringbuf!(NON_COUNTED_RINGBUF, Event, 16, Event::NothingHappened); | ||
|
||
pub fn example() { | ||
ringbuf_entry!(Event::SomethingHappened); | ||
ringbuf_entry!(NON_COUNTED_RINGBUF, Event::SomethingHappened); | ||
} | ||
|
||
pub fn example_named() { | ||
ringbuf_entry!(MY_NAMED_RINGBUF, Event::SomethingElse(420)); | ||
} | ||
|
||
pub mod nested { | ||
use super::Event; | ||
|
||
ringbuf::counted_ringbuf!(Event, 16, Event::NothingHappened); | ||
|
||
pub fn example() { | ||
ringbuf::ringbuf_entry!(Event::SomethingHappened); | ||
ringbuf::ringbuf_entry_root!(Event::SomethingElse(666)); | ||
ringbuf::ringbuf_entry_root!( | ||
MY_NAMED_RINGBUF, | ||
Event::SecretThirdThing { secret: () } | ||
); | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "ringbuf-macros" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
proc-macro2 = "1.0.78" | ||
quote = "1.0.35" | ||
syn = "2.0.48" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
extern crate proc_macro; | ||
hawkw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
use proc_macro::TokenStream; | ||
use proc_macro2::{Ident, Span}; | ||
use quote::{quote, ToTokens}; | ||
use syn::{parse_macro_input, DeriveInput}; | ||
|
||
/// Derives an implementation of the `ringbuf::Count` trait for the annotated | ||
/// `enum` type. | ||
/// | ||
/// Note that this macro can currently only be used on `enum` types. | ||
#[proc_macro_derive(Count)] | ||
pub fn derive_count(input: TokenStream) -> TokenStream { | ||
let input = parse_macro_input!(input as DeriveInput); | ||
match gen_count_impl(input) { | ||
Ok(tokens) => tokens.to_token_stream().into(), | ||
Err(err) => err.to_compile_error().into(), | ||
} | ||
} | ||
|
||
fn gen_count_impl(input: DeriveInput) -> Result<impl ToTokens, syn::Error> { | ||
let name = &input.ident; | ||
let data_enum = match input.data { | ||
syn::Data::Enum(ref data_enum) => data_enum, | ||
_ => { | ||
return Err(syn::Error::new_spanned( | ||
input, | ||
"`ringbuf::Count` can only be derived for enums", | ||
)); | ||
} | ||
}; | ||
let variants = &data_enum.variants; | ||
let len = variants.len(); | ||
let mut variant_names = Vec::with_capacity(len); | ||
let mut variant_patterns = Vec::with_capacity(len); | ||
for variant in variants { | ||
let ident = &variant.ident; | ||
variant_patterns.push(match variant.fields { | ||
syn::Fields::Unit => quote! { #name::#ident => &counters.#ident }, | ||
syn::Fields::Named(_) => { | ||
quote! { #name::#ident { .. } => &counters.#ident } | ||
} | ||
syn::Fields::Unnamed(_) => { | ||
quote! { #name::#ident(..) => &counters.#ident } | ||
} | ||
}); | ||
variant_names.push(ident.clone()); | ||
} | ||
let counts_ty = counts_ty(name); | ||
let code = quote! { | ||
#[doc = concat!(" Ringbuf entry total counts for [`", stringify!(#name), "`].")] | ||
#[allow(nonstandard_style)] | ||
pub struct #counts_ty { | ||
#( | ||
#[doc = concat!( | ||
" The total number of times a [`", | ||
stringify!(#name), "::", stringify!(#variant_names), | ||
"`] entry" | ||
)] | ||
#[doc = " has been recorded by this ringbuf."] | ||
pub #variant_names: core::sync::atomic::AtomicU32 | ||
),* | ||
} | ||
|
||
#[automatically_derived] | ||
impl ringbuf::Count for #name { | ||
type Counters = #counts_ty; | ||
|
||
// This is intended for use in a static initializer, so the fact that every | ||
// time the constant is used it will be a different instance is not a | ||
// problem --- in fact, it's the desired behavior. | ||
// | ||
// `declare_interior_mutable_const` is really Not My Favorite Clippy | ||
// Lint... | ||
#[allow(clippy::declare_interior_mutable_const)] | ||
const NEW_COUNTERS: #counts_ty = #counts_ty { | ||
#(#variant_names: core::sync::atomic::AtomicU32::new(0)),* | ||
}; | ||
|
||
fn count(&self, counters: &Self::Counters) { | ||
#[cfg(all(target_arch = "arm", armv6m))] | ||
use ringbuf::rmv6m_atomic_hack::AtomicU32Ext; | ||
|
||
let counter = match self { | ||
#(#variant_patterns),* | ||
}; | ||
counter.fetch_add(1, core::sync::atomic::Ordering::Relaxed); | ||
} | ||
} | ||
}; | ||
Ok(code) | ||
} | ||
|
||
fn counts_ty(ident: &Ident) -> Ident { | ||
Ident::new(&format!("{ident}Counts"), Span::call_site()) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This change was necessary because I added an
examples/
dir toringbuf
, and thecargo test
run on CI for the host target attempts to build examples as well as running tests. Sinceringbuf
depends onstatic_cell
(and now, onarmv6m-atomic-hack
as well), buildingringbuf
callsexpose_m_profile
, which panics on x86_64 build hosts. Therefore, I've changed this method to return aResult
instead, which the libs that can reasonably be built for x86_64 (ringbuf
,static-cell
,armv6m-atomic-hack
) turn into a warning, as we only need to determine ARM profile for ARM targets, while the crates that only build for ARM unwrap, maintaining the previous behavior of failing the build if built for a non-ARM target.This, unfortunately, required changing a bunch of build scritps as well. Sorry about the big diff!