httparse/simd/
runtime.rs

1use std::sync::atomic::{AtomicU8, Ordering};
2use crate::iter::Bytes;
3use super::avx2;
4use super::sse42;
5
6const AVX2: u8 = 1;
7const SSE42: u8 = 2;
8const NOP: u8 = 3;
9
10fn detect_runtime_feature() -> u8 {
11    if is_x86_feature_detected!("avx2") {
12        AVX2
13    } else if is_x86_feature_detected!("sse4.2") {
14        SSE42
15    } else {
16        NOP
17    }
18}
19
20static RUNTIME_FEATURE: AtomicU8 = AtomicU8::new(0);
21
22#[inline]
23fn get_runtime_feature() -> u8 {
24    let mut feature = RUNTIME_FEATURE.load(Ordering::Relaxed);
25    if feature == 0 {
26        feature = detect_runtime_feature();
27        RUNTIME_FEATURE.store(feature, Ordering::Relaxed);
28    }
29
30    feature
31}
32
33pub fn match_header_name_vectored(bytes: &mut Bytes) {
34    super::swar::match_header_name_vectored(bytes);
35}
36
37pub fn match_uri_vectored(bytes: &mut Bytes) {
38    // SAFETY: calls are guarded by a feature check
39    unsafe {
40        match get_runtime_feature() {
41            AVX2 => avx2::match_uri_vectored(bytes),
42            SSE42 => sse42::match_uri_vectored(bytes),
43            _ /* NOP */ => super::swar::match_uri_vectored(bytes),
44        }
45    }
46}
47
48pub fn match_header_value_vectored(bytes: &mut Bytes) {
49    // SAFETY: calls are guarded by a feature check
50    unsafe {
51        match get_runtime_feature() {
52            AVX2 => avx2::match_header_value_vectored(bytes),
53            SSE42 => sse42::match_header_value_vectored(bytes),
54            _ /* NOP */ => super::swar::match_header_value_vectored(bytes),
55        }
56    }
57}