@@ -14,19 +14,17 @@ static bool isKnownAndSupported(const char *name) {
14
14
void __init_cpu_features_resolver (void ) {
15
15
// On Darwin platforms, this may be called concurrently by multiple threads
16
16
// because the resolvers that use it are called lazily at runtime (unlike on
17
- // ELF platforms, where IFuncs are resolved serially at load time). This
18
- // function's effect on __aarch64_cpu_features should be idempotent, but even
19
- // so we need dispatch_once to resolve the race condition. Dispatch is
20
- // available through libSystem, which we need anyway for the sysctl, so this
21
- // does not add a new dependency.
17
+ // ELF platforms, where IFuncs are resolved serially at load time). This
18
+ // function's effect on __aarch64_cpu_features must be idempotent.
19
+
20
+ if (! __atomic_load_n (&__aarch64_cpu_features. features , __ATOMIC_RELAXED)) {
21
+ uint64_t features = 0 ;
22
22
23
- static dispatch_once_t onceToken = 0 ;
24
- dispatch_once (&onceToken, ^{
25
23
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
26
24
static const struct {
27
25
const char *sysctl_name;
28
26
enum CPUFeatures feature;
29
- } features [] = {
27
+ } feature_checks [] = {
30
28
{" hw.optional.arm.FEAT_FlagM" , FEAT_FLAGM},
31
29
{" hw.optional.arm.FEAT_FlagM2" , FEAT_FLAGM2},
32
30
{" hw.optional.arm.FEAT_FHM" , FEAT_FP16FML},
@@ -58,12 +56,16 @@ void __init_cpu_features_resolver(void) {
58
56
{" hw.optional.arm.FEAT_BTI" , FEAT_BTI},
59
57
};
60
58
61
- for (size_t I = 0 , E = sizeof (features) / sizeof (features[0 ]); I != E; ++I)
62
- if (isKnownAndSupported (features[I].sysctl_name ))
63
- __aarch64_cpu_features.features |= (1ULL << features[I].feature );
59
+ for (size_t I = 0 , E = sizeof (feature_checks) / sizeof (feature_checks[0 ]);
60
+ I != E; ++I)
61
+ if (isKnownAndSupported (feature_checks[I].sysctl_name ))
62
+ features |= (1ULL << feature_checks[I].feature );
63
+
64
+ features |= (1ULL << FEAT_INIT);
64
65
65
- __aarch64_cpu_features.features |= (1ULL << FEAT_INIT);
66
- });
66
+ __atomic_store (&__aarch64_cpu_features.features , &features,
67
+ __ATOMIC_RELAXED);
68
+ }
67
69
}
68
70
69
71
#endif // TARGET_OS_OSX || TARGET_OS_IPHONE
0 commit comments