Skip to content

Commit

Permalink
Use atomic global for feature detection
Browse files Browse the repository at this point in the history
Previous implementation was correct, but this is more obviously so and idiomatic
  • Loading branch information
AaronO committed Apr 18, 2023
1 parent c84873e commit 5232599
Showing 1 changed file with 31 additions and 31 deletions.
62 changes: 31 additions & 31 deletions src/simd/runtime.rs
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),
_ => {},
}
}
}

0 comments on commit 5232599

Please sign in to comment.