Skip to content

Commit fd8b35b

Browse files
majnemercopybara-github
authored andcommitted
Random: Rollforward support runtime dispatch on AArch64 macOS
The __builtin_cpu_supports path seems to cause problems on certain builds, let's remove it. PiperOrigin-RevId: 717993600 Change-Id: I69568c17dc768a5edd097709884ba07f2c78db91
1 parent df8178e commit fd8b35b

File tree

5 files changed

+71
-18
lines changed

5 files changed

+71
-18
lines changed

absl/random/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ absl_cc_library(
853853
absl::random_internal_platform
854854
absl::random_internal_randen_hwaes_impl
855855
absl::config
856+
absl::optional
856857
)
857858

858859
# Internal-only target, do not depend on directly.

absl/random/internal/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ cc_library(
403403
":platform",
404404
":randen_hwaes_impl",
405405
"//absl/base:config",
406+
"//absl/types:optional",
406407
],
407408
)
408409

absl/random/internal/platform.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
16+
1517
#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_
1618
#define ABSL_RANDOM_INTERNAL_PLATFORM_H_
1719

@@ -134,16 +136,23 @@
134136
// accelerated Randen implementation.
135137
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
136138

137-
#if defined(ABSL_ARCH_X86_64)
139+
// iOS does not support dispatch, even on x86, since applications
140+
// should be bundled as fat binaries, with a different build tailored for
141+
// each specific supported platform/architecture.
142+
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
143+
(defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
144+
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
145+
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
146+
#elif defined(ABSL_ARCH_X86_64)
138147
// Dispatch is available on x86_64
139148
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
140149
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
141150
#elif defined(__linux__) && defined(ABSL_ARCH_PPC)
142151
// Or when running linux PPC
143152
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
144153
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
145-
#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64)
146-
// Or when running linux AArch64
154+
#elif (defined(__linux__) || defined(__APPLE__)) && defined(ABSL_ARCH_AARCH64)
155+
// Or when running linux or macOS AArch64
147156
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
148157
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
149158
#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8)
@@ -159,13 +168,4 @@
159168
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
160169
#endif
161170

162-
// iOS does not support dispatch, even on x86, since applications
163-
// should be bundled as fat binaries, with a different build tailored for
164-
// each specific supported platform/architecture.
165-
#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
166-
(defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
167-
#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
168-
#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
169-
#endif
170-
171171
#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_

absl/random/internal/randen_detect.cc

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,21 @@
1919

2020
#include "absl/random/internal/randen_detect.h"
2121

22+
#if defined(__APPLE__) && defined(__aarch64__)
23+
#if defined(__has_include)
24+
#if __has_include(<arm/cpu_capabilities_public.h>)
25+
#include <arm/cpu_capabilities_public.h>
26+
#endif
27+
#endif
28+
#include <sys/sysctl.h>
29+
#include <sys/types.h>
30+
#endif
31+
2232
#include <cstdint>
2333
#include <cstring>
2434

2535
#include "absl/random/internal/platform.h"
36+
#include "absl/types/optional.h" // IWYU pragma: keep
2637

2738
#if !defined(__UCLIBC__) && defined(__GLIBC__) && \
2839
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
@@ -102,6 +113,19 @@ static uint32_t GetAuxval(uint32_t hwcap_type) {
102113

103114
#endif
104115

116+
#if defined(__APPLE__) && defined(ABSL_ARCH_AARCH64)
117+
template <typename T>
118+
static absl::optional<T> ReadSysctlByName(const char* name) {
119+
T val;
120+
size_t val_size = sizeof(T);
121+
int ret = sysctlbyname(name, &val, &val_size, nullptr, 0);
122+
if (ret == -1) {
123+
return std::nullopt;
124+
}
125+
return val;
126+
}
127+
#endif
128+
105129
namespace absl {
106130
ABSL_NAMESPACE_BEGIN
107131
namespace random_internal {
@@ -129,7 +153,9 @@ namespace random_internal {
129153
// cpu capabilities, and should allow us to enable crypto in the android
130154
// builds where it is supported.
131155
//
132-
// 3. Use the default for the compiler architecture.
156+
// 3. When __APPLE__ is defined on AARCH64, use sysctlbyname().
157+
//
158+
// 4. Use the default for the compiler architecture.
133159
//
134160

135161
bool CPUSupportsRandenHwAes() {
@@ -178,8 +204,36 @@ bool CPUSupportsRandenHwAes() {
178204
return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0);
179205
#endif
180206

207+
#elif defined(__APPLE__) && defined(ABSL_ARCH_AARCH64)
208+
// 3. Use sysctlbyname.
209+
210+
// Newer XNU kernels support querying all capabilities in a single
211+
// sysctlbyname.
212+
#if defined(CAP_BIT_AdvSIMD) && defined(CAP_BIT_FEAT_AES)
213+
static const absl::optional<uint64_t> caps =
214+
ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
215+
if (caps.has_value()) {
216+
constexpr uint64_t kNeonAndAesCaps =
217+
(uint64_t{1} << CAP_BIT_AdvSIMD) | (uint64_t{1} << CAP_BIT_FEAT_AES);
218+
return (*caps & kNeonAndAesCaps) == kNeonAndAesCaps;
219+
}
220+
#endif
221+
222+
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#overview
223+
static const absl::optional<int> adv_simd =
224+
ReadSysctlByName<int>("hw.optional.AdvSIMD");
225+
if (adv_simd.value_or(0) == 0) {
226+
return false;
227+
}
228+
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
229+
static const absl::optional<int> feat_aes =
230+
ReadSysctlByName<int>("hw.optional.arm.FEAT_AES");
231+
if (feat_aes.value_or(0) == 0) {
232+
return false;
233+
}
234+
return true;
181235
#else // ABSL_INTERNAL_USE_GETAUXVAL
182-
// 3. By default, assume that the compiler default.
236+
// 4. By default, assume that the compiler default.
183237
return ABSL_HAVE_ACCELERATED_AES ? true : false;
184238

185239
#endif
@@ -215,9 +269,6 @@ bool CPUSupportsRandenHwAes() {
215269
// __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val));
216270
//
217271
// * Use a CPUID-style heuristic database.
218-
//
219-
// * On Apple (__APPLE__), AES is available on Arm v8.
220-
// https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
221272
}
222273

223274
#if defined(__clang__)

absl/random/internal/randen_hwaes_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ int main(int argc, char* argv[]) {
8989
LOG(INFO) << "HasRandenHwAesImplementation = " << x;
9090

9191
int y = absl::random_internal::CPUSupportsRandenHwAes();
92-
LOG(INFO) << "CPUSupportsRandenHwAes = " << x;
92+
LOG(INFO) << "CPUSupportsRandenHwAes = " << y;
9393

9494
if (!x || !y) {
9595
LOG(INFO) << "Skipping Randen HWAES tests.";

0 commit comments

Comments
 (0)