Skip to content

Commit 43f94a5

Browse files
authored
Merge pull request wolfSSL#9107 from douzzer/20250816-cpuid_get_flags_ex-optimize
20250816-cpuid_get_flags_ex-optimize
2 parents 0ba16a9 + 39c6c5a commit 43f94a5

2 files changed

Lines changed: 61 additions & 36 deletions

File tree

wolfcrypt/src/cpuid.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
#if defined(HAVE_CPUID) || defined(HAVE_CPUID_INTEL) || \
2727
defined(HAVE_CPUID_AARCH64)
28-
static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
28+
static cpuid_flags_atomic_t cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
2929
#endif
3030

3131
#ifdef HAVE_CPUID_INTEL
@@ -49,7 +49,7 @@
4949
#define ECX 2
5050
#define EDX 3
5151

52-
static word32 cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit)
52+
static cpuid_flags_t cpuid_flag(word32 leaf, word32 sub, word32 num, word32 bit)
5353
{
5454
int got_intel_cpu = 0;
5555
int got_amd_cpu = 0;
@@ -82,8 +82,9 @@
8282

8383
static WC_INLINE void cpuid_set_flags(void)
8484
{
85-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
86-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
85+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
86+
cpuid_flags_t new_cpuid_flags = 0,
87+
old_cpuid_flags = WC_CPUID_INITIALIZER;
8788
if (cpuid_flag(1, 0, ECX, 28)) { new_cpuid_flags |= CPUID_AVX1 ; }
8889
if (cpuid_flag(7, 0, EBX, 5)) { new_cpuid_flags |= CPUID_AVX2 ; }
8990
if (cpuid_flag(7, 0, EBX, 8)) { new_cpuid_flags |= CPUID_BMI2 ; }
@@ -115,8 +116,9 @@
115116

116117
static WC_INLINE void cpuid_set_flags(void)
117118
{
118-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
119-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
119+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
120+
cpuid_flags_t new_cpuid_flags = 0,
121+
old_cpuid_flags = WC_CPUID_INITIALIZER;
120122
word64 features;
121123

122124
__asm__ __volatile (
@@ -158,8 +160,9 @@
158160

159161
static WC_INLINE void cpuid_set_flags(void)
160162
{
161-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
162-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
163+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
164+
cpuid_flags_t new_cpuid_flags = 0,
165+
old_cpuid_flags = WC_CPUID_INITIALIZER;
163166
word64 hwcaps = getauxval(AT_HWCAP);
164167

165168
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
@@ -204,8 +207,9 @@
204207

205208
static WC_INLINE void cpuid_set_flags(void)
206209
{
207-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
208-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
210+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
211+
cpuid_flags_t new_cpuid_flags = 0,
212+
old_cpuid_flags = WC_CPUID_INITIALIZER;
209213
word64 features = android_getCpuFeatures();
210214

211215
if (features & ANDROID_CPU_ARM_FEATURE_AES)
@@ -237,8 +241,9 @@
237241

238242
static WC_INLINE void cpuid_set_flags(void)
239243
{
240-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
241-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
244+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
245+
cpuid_flags_t new_cpuid_flags = 0,
246+
old_cpuid_flags = WC_CPUID_INITIALIZER;
242247
if (cpuid_get_sysctlbyname("hw.optional.arm.FEAT_AES") != 0)
243248
new_cpuid_flags |= CPUID_AES;
244249
if (cpuid_get_sysctlbyname("hw.optional.arm.FEAT_PMULL") != 0)
@@ -269,8 +274,9 @@
269274

270275
static WC_INLINE void cpuid_set_flags(void)
271276
{
272-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
273-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
277+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
278+
cpuid_flags_t new_cpuid_flags = 0,
279+
old_cpuid_flags = WC_CPUID_INITIALIZER;
274280
word64 features = 0;
275281

276282
elf_aux_info(AT_HWCAP, &features, sizeof(features));
@@ -301,8 +307,9 @@
301307
#else
302308
static WC_INLINE void cpuid_set_flags(void)
303309
{
304-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
305-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
310+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
311+
cpuid_flags_t new_cpuid_flags = 0,
312+
old_cpuid_flags = WC_CPUID_INITIALIZER;
306313
#ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO
307314
new_cpuid_flags |= CPUID_AES;
308315
new_cpuid_flags |= CPUID_PMULL;
@@ -332,8 +339,9 @@
332339
#elif defined(HAVE_CPUID)
333340
static WC_INLINE void cpuid_set_flags(void)
334341
{
335-
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_UNINITED_VAL) {
336-
word32 new_cpuid_flags = 0, old_cpuid_flags = WC_CPUID_UNINITED_VAL;
342+
if (WOLFSSL_ATOMIC_LOAD(cpuid_flags) == WC_CPUID_INITIALIZER) {
343+
cpuid_flags_t new_cpuid_flags = 0,
344+
old_cpuid_flags = WC_CPUID_INITIALIZER;
337345
(void)wolfSSL_Atomic_Uint_CompareExchange
338346
(&cpuid_flags, &old_cpuid_flags, new_cpuid_flags);
339347
}
@@ -342,28 +350,28 @@
342350

343351
#ifdef HAVE_CPUID
344352

345-
word32 cpuid_get_flags(void)
353+
cpuid_flags_t cpuid_get_flags(void)
346354
{
347355
cpuid_set_flags();
348356
return WOLFSSL_ATOMIC_LOAD(cpuid_flags);
349357
}
350358

351-
void cpuid_select_flags(word32 flags)
359+
void cpuid_select_flags(cpuid_flags_t flags)
352360
{
353361
WOLFSSL_ATOMIC_STORE(cpuid_flags, flags);
354362
}
355363

356-
void cpuid_set_flag(word32 flag)
364+
void cpuid_set_flag(cpuid_flags_t flag)
357365
{
358-
word32 current_flags = WOLFSSL_ATOMIC_LOAD(cpuid_flags);
366+
cpuid_flags_t current_flags = WOLFSSL_ATOMIC_LOAD(cpuid_flags);
359367
while (! wolfSSL_Atomic_Uint_CompareExchange
360368
(&cpuid_flags, &current_flags, current_flags | flag))
361369
WC_RELAX_LONG_LOOP();
362370
}
363371

364-
void cpuid_clear_flag(word32 flag)
372+
void cpuid_clear_flag(cpuid_flags_t flag)
365373
{
366-
word32 current_flags = WOLFSSL_ATOMIC_LOAD(cpuid_flags);
374+
cpuid_flags_t current_flags = WOLFSSL_ATOMIC_LOAD(cpuid_flags);
367375
while (! wolfSSL_Atomic_Uint_CompareExchange
368376
(&cpuid_flags, &current_flags, current_flags & ~flag))
369377
WC_RELAX_LONG_LOOP();

wolfssl/wolfcrypt/cpuid.h

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,15 @@
4444
#define HAVE_CPUID_AARCH64
4545
#endif
4646

47-
#define WC_CPUID_UNINITED_VAL 0xffffffffU
47+
#define WC_CPUID_INITIALIZER 0xffffffffU
48+
typedef word32 cpuid_flags_t;
4849
#if !defined(WOLFSSL_NO_ATOMICS) && !defined(SINGLE_THREADED)
49-
typedef wolfSSL_Atomic_Uint cpuid_flags_t;
50-
#define WC_CPUID_INITIALIZER \
51-
WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_UNINITED_VAL)
50+
typedef wolfSSL_Atomic_Uint cpuid_flags_atomic_t;
51+
#define WC_CPUID_ATOMIC_INITIALIZER \
52+
WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_INITIALIZER)
5253
#else
53-
typedef word32 cpuid_flags_t;
54-
#define WC_CPUID_INITIALIZER WC_CPUID_UNINITED_VAL
54+
typedef word32 cpuid_flags_atomic_t;
55+
#define WC_CPUID_ATOMIC_INITIALIZER WC_CPUID_INITIALIZER
5556
#endif
5657

5758
#ifdef HAVE_CPUID_INTEL
@@ -103,22 +104,38 @@
103104
#endif
104105

105106
#ifdef HAVE_CPUID
106-
word32 cpuid_get_flags(void);
107+
cpuid_flags_t cpuid_get_flags(void);
107108

109+
/* Idempotent flag getter -- fast, but return value (whether updated) is not
110+
* strictly reliable.
111+
*/
108112
static WC_INLINE int cpuid_get_flags_ex(cpuid_flags_t *flags) {
109-
if (WOLFSSL_ATOMIC_LOAD(*flags) == WC_CPUID_UNINITED_VAL) {
110-
word32 old_cpuid_flags = WC_CPUID_UNINITED_VAL;
113+
if (*flags == WC_CPUID_INITIALIZER) {
114+
*flags = cpuid_get_flags();
115+
return 1;
116+
}
117+
else
118+
return 0;
119+
}
120+
121+
/* Strictly race-free flag getter -- slow, but the return value is strictly
122+
* accurate.
123+
*/
124+
static WC_INLINE int cpuid_get_flags_atomic(cpuid_flags_atomic_t *flags) {
125+
if (WOLFSSL_ATOMIC_LOAD(*flags) == WC_CPUID_INITIALIZER) {
126+
cpuid_flags_t old_cpuid_flags = WC_CPUID_INITIALIZER;
111127
return wolfSSL_Atomic_Uint_CompareExchange
112128
(flags, &old_cpuid_flags, cpuid_get_flags());
113129
}
114130
else
115131
return 0;
116132
}
117133

134+
118135
/* Public APIs to modify flags. */
119-
WOLFSSL_API void cpuid_select_flags(word32 flags);
120-
WOLFSSL_API void cpuid_set_flag(word32 flag);
121-
WOLFSSL_API void cpuid_clear_flag(word32 flag);
136+
WOLFSSL_API void cpuid_select_flags(cpuid_flags_t flags);
137+
WOLFSSL_API void cpuid_set_flag(cpuid_flags_t flag);
138+
WOLFSSL_API void cpuid_clear_flag(cpuid_flags_t flag);
122139

123140
#endif
124141

0 commit comments

Comments
 (0)