use std::sync::atomic::{AtomicU8, Ordering}; use crate::iter::Bytes; use super::avx2; use super::sse42; const AVX2: u8 = 1; const SSE42: u8 = 2; const NOP: u8 = 3; fn detect_runtime_feature() -> u8 { if is_x86_feature_detected!("avx2") { AVX2 } else if is_x86_feature_detected!("sse4.2") { SSE42 } else { NOP } } 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_header_name_vectored(bytes: &mut Bytes) { super::swar::match_header_name_vectored(bytes); } pub fn match_uri_vectored(bytes: &mut Bytes) { // SAFETY: calls are guarded by a feature check unsafe { match get_runtime_feature() { AVX2 => avx2::match_uri_vectored(bytes), SSE42 => sse42::match_uri_vectored(bytes), _ /* NOP */ => super::swar::match_uri_vectored(bytes), } } } pub fn match_header_value_vectored(bytes: &mut Bytes) { // SAFETY: calls are guarded by a feature check unsafe { match get_runtime_feature() { AVX2 => avx2::match_header_value_vectored(bytes), SSE42 => sse42::match_header_value_vectored(bytes), _ /* NOP */ => super::swar::match_header_value_vectored(bytes), } } }