Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/arm/cpu_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static const struct cpu_feature arm_cpu_feature_table[] = {
{ARM_CPU_FEATURE_DOTPROD, "dotprod"},
};

volatile u32 libdeflate_arm_cpu_features = 0;
u32 libdeflate_arm_cpu_features = 0;

void libdeflate_init_arm_cpu_features(void)
{
Expand All @@ -224,7 +224,8 @@ void libdeflate_init_arm_cpu_features(void)
disable_cpu_features_for_testing(&features, arm_cpu_feature_table,
ARRAY_LEN(arm_cpu_feature_table));

libdeflate_arm_cpu_features = features | ARM_CPU_FEATURES_KNOWN;
__atomic_store_n(&libdeflate_arm_cpu_features,
features | ARM_CPU_FEATURES_KNOWN, __ATOMIC_RELAXED);
}

#endif /* ARM_CPU_FEATURES_KNOWN */
16 changes: 13 additions & 3 deletions lib/arm/cpu_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,25 @@
(defined(_WIN32) && defined(ARCH_ARM64)))
/* Runtime ARM CPU feature detection is supported. */
# define ARM_CPU_FEATURES_KNOWN (1U << 31)
extern volatile u32 libdeflate_arm_cpu_features;
extern u32 libdeflate_arm_cpu_features;

void libdeflate_init_arm_cpu_features(void);

/*
* Resolved on the first call. Accessed with relaxed atomics: the first-call initialization is a
* benign race (every thread computes the same features bitmask, a pure function of the CPU), but
* a plain load racing with the store in libdeflate_init_arm_cpu_features() is undefined behavior
* and is flagged by ThreadSanitizer. Relaxed ordering suffices because no other memory is
* published through it.
*/
static inline u32 get_arm_cpu_features(void)
{
if (libdeflate_arm_cpu_features == 0)
u32 features = __atomic_load_n(&libdeflate_arm_cpu_features, __ATOMIC_RELAXED);
if (features == 0) {
libdeflate_init_arm_cpu_features();
return libdeflate_arm_cpu_features;
features = __atomic_load_n(&libdeflate_arm_cpu_features, __ATOMIC_RELAXED);
}
return features;
}
#else
static inline u32 get_arm_cpu_features(void) { return 0; }
Expand Down
5 changes: 3 additions & 2 deletions lib/x86/cpu_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ static const struct cpu_feature x86_cpu_feature_table[] = {
{X86_CPU_FEATURE_AVXVNNI, "avx_vnni"},
};

volatile u32 libdeflate_x86_cpu_features = 0;
u32 libdeflate_x86_cpu_features = 0;

static inline bool
os_supports_avx512(u64 xcr0)
Expand Down Expand Up @@ -207,7 +207,8 @@ void libdeflate_init_x86_cpu_features(void)
disable_cpu_features_for_testing(&features, x86_cpu_feature_table,
ARRAY_LEN(x86_cpu_feature_table));

libdeflate_x86_cpu_features = features | X86_CPU_FEATURES_KNOWN;
__atomic_store_n(&libdeflate_x86_cpu_features,
features | X86_CPU_FEATURES_KNOWN, __ATOMIC_RELAXED);
}

#endif /* X86_CPU_FEATURES_KNOWN */
16 changes: 13 additions & 3 deletions lib/x86/cpu_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,25 @@
#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
/* Runtime x86 CPU feature detection is supported. */
# define X86_CPU_FEATURES_KNOWN (1U << 31)
extern volatile u32 libdeflate_x86_cpu_features;
extern u32 libdeflate_x86_cpu_features;

void libdeflate_init_x86_cpu_features(void);

/*
* Resolved on the first call. Accessed with relaxed atomics: the first-call initialization is a
* benign race (every thread computes the same features bitmask, a pure function of the CPU), but
* a plain load racing with the store in libdeflate_init_x86_cpu_features() is undefined behavior
* and is flagged by ThreadSanitizer. Relaxed ordering suffices because no other memory is
* published through it.
*/
static inline u32 get_x86_cpu_features(void)
{
if (libdeflate_x86_cpu_features == 0)
u32 features = __atomic_load_n(&libdeflate_x86_cpu_features, __ATOMIC_RELAXED);
if (features == 0) {
libdeflate_init_x86_cpu_features();
return libdeflate_x86_cpu_features;
features = __atomic_load_n(&libdeflate_x86_cpu_features, __ATOMIC_RELAXED);
}
return features;
}
/*
* x86 intrinsics are also supported. Include the headers needed to use them.
Expand Down