-
-
Notifications
You must be signed in to change notification settings - Fork 110
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use atomic global for feature detection
Previous implementation was correct, but this is more obviously so and idiomatic
- Loading branch information
Showing
1 changed file
with
31 additions
and
31 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,53 +1,53 @@ | ||
use std::sync::atomic::{AtomicU8, Ordering}; | ||
use crate::iter::Bytes; | ||
use super::avx2; | ||
use super::sse42; | ||
|
||
pub enum RuntimeFeature { | ||
Avx2, | ||
Sse42, | ||
Nop, | ||
} | ||
const AVX2: u8 = 1; | ||
const SSE42: u8 = 2; | ||
const NOP: u8 = 3; | ||
|
||
impl RuntimeFeature { | ||
fn detect() -> Self { | ||
if is_x86_feature_detected!("avx2") { | ||
RuntimeFeature::Avx2 | ||
} else if is_x86_feature_detected!("sse4.2") { | ||
RuntimeFeature::Sse42 | ||
} else { | ||
RuntimeFeature::Nop | ||
} | ||
fn detect_runtime_feature() -> u8 { | ||
if is_x86_feature_detected!("avx2") { | ||
AVX2 | ||
} else if is_x86_feature_detected!("sse4.2") { | ||
SSE42 | ||
} else { | ||
NOP | ||
} | ||
} | ||
|
||
static mut RUNTIME_FEATURE: Option<RuntimeFeature> = None; | ||
static RUNTIME_FEATURE: AtomicU8 = AtomicU8::new(0); | ||
|
||
#[inline] | ||
fn get_runtime_feature() -> u8 { | ||
let mut feature = RUNTIME_FEATURE.load(Ordering::Relaxed); | ||
if feature == 0 { | ||
feature = detect_runtime_feature(); | ||
RUNTIME_FEATURE.store(feature, Ordering::Relaxed); | ||
} | ||
|
||
feature | ||
} | ||
|
||
pub fn match_uri_vectored(bytes: &mut Bytes) { | ||
// SAFETY: calls are guarded by a feature check | ||
unsafe { | ||
if let None = RUNTIME_FEATURE { | ||
RUNTIME_FEATURE = Some(RuntimeFeature::detect()); | ||
} | ||
|
||
match RUNTIME_FEATURE.as_ref().unwrap() { | ||
RuntimeFeature::Avx2 => avx2::match_uri_vectored(bytes), | ||
RuntimeFeature::Sse42 => sse42::match_uri_vectored(bytes), | ||
RuntimeFeature::Nop => {}, | ||
match get_runtime_feature() { | ||
AVX2 => avx2::match_uri_vectored(bytes), | ||
SSE42 => sse42::match_uri_vectored(bytes), | ||
_ => {}, | ||
} | ||
} | ||
} | ||
|
||
pub fn match_header_value_vectored(bytes: &mut Bytes) { | ||
// SAFETY: calls are guarded by a feature check | ||
unsafe { | ||
if let None = RUNTIME_FEATURE { | ||
RUNTIME_FEATURE = Some(RuntimeFeature::detect()); | ||
} | ||
|
||
match RUNTIME_FEATURE.as_ref().unwrap() { | ||
RuntimeFeature::Avx2 => avx2::match_header_value_vectored(bytes), | ||
RuntimeFeature::Sse42 => sse42::match_header_value_vectored(bytes), | ||
RuntimeFeature::Nop => {}, | ||
match get_runtime_feature() { | ||
AVX2 => avx2::match_header_value_vectored(bytes), | ||
SSE42 => sse42::match_header_value_vectored(bytes), | ||
_ => {}, | ||
} | ||
} | ||
} |