-
Notifications
You must be signed in to change notification settings - Fork 15
Introduce AtomicLevelFilter
#110
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: main-dev
Are you sure you want to change the base?
Conversation
0741cb5 to
ca57e28
Compare
|
I have changed to use I'll run Miri later to see if there are any issues. |
15811c1 to
ceb39bd
Compare
|
In this PR we adds a |
ceb39bd to
07d4747
Compare
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.
⚠️ Performance Alert ⚠️
Possible performance regression was detected for benchmark 'spdlog-rs on Linux'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.
| Benchmark suite | Current: 1896486 | Previous: 7c107c2 | Ratio |
|---|---|---|---|
bench_2_full_pattern_ct |
428.9 ns/iter (± 10.42) |
196.64 ns/iter (± 25.57) |
2.18 |
This comment was automatically generated by workflow using github-action-benchmark.
CC: @SpriteOvO
Should be false positive due to unstable CI VM environment. |
07d4747 to
afd4805
Compare
|
Renamed |
spdlog/src/level.rs
Outdated
|
|
||
| // Atomic | ||
|
|
||
| // This struct must have the same memory layout as `LevelFilter`. |
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.
Could you explain the reason behind this constraint?
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.
Because we are doing mem::transmute(LevelFilterLayout) -> LevelFilter in impl From<LevelFilterLayout> for LevelFilter, they must have the same layout to avoid undefined behavior.
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.
I still don't get why we have to use transmute to convert LevelFilterLayout to LevelFilter. Could we just do the conversion field-by-field, without invoking transmute?
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.
Sure, just that way I'd be a bit concerned about the performance cost. Since it introduces match blocks, I'm not sure if the compiler will optimize them away.
I'll run a benchmark later and inspect the generated ASM to see if the compiler is smart enough. XD
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.
I have faith in compiler optimizations. They should be really good at this sort of optimizations. But let's see the benchmark results first.
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.
Benchmarking commit: 4421785
running 4 tests
test safe_from_layout ... bench: 1.07 ns/iter (+/- 0.01)
test safe_into_layout ... bench: 0.71 ns/iter (+/- 0.01)
test unsafe_from_layout ... bench: 0.71 ns/iter (+/- 0.01)
test unsafe_into_layout ... bench: 1.07 ns/iter (+/- 0.01)
test result: ok. 0 passed; 0 failed; 0 ignored; 4 measured; 0 filtered out; finished in 1.22s
I inspected the generated ASM, it's just a very minor difference, likely because the unsafe version transmutes UNDEFINED_FALLBACK directly into the uninitialized bytes part of LevelFilter, while the safe version handles it separately.
Looks acceptable, though we'll need to write more code. I'll refactor this PR tomorrow to avoid unsafe code.
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.
Refactored to avoid unsafe code~ please review it again, thanks!
4421785 to
c5ef04a
Compare
Reasons
Using
Atomic<T>(fromatomiccrate) with types that contain uninitialized bytes is undefined behavior. Prior toatomicv0.6, that crate did not restrict this (Footgun: compare_exchange may fail if T contains unused bytes Amanieu/atomic-rs#23). In spdlog-rs,LevelFilteris an enum, for variantsOffandAll, they have uninitialized bytes.The new introduced
AtomicLevelFilter, makes downstream users no longer need to addatomiccrate to theirCargo.toml, and eliminates uninitialized bytes. Ensured the soundness of atomic level filter.We can now bump
atomicto the latest version, this was the main obstacle that kept us locked toatomicv0.5.Miri currently reports this error, so once it's fixed we can enable Miri in CI (there may be other obstacles, some tests run very slowly even on my real machine).
@Lancern Given that this PR relates to safety, would you be willing to take a look?