1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker *
4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker *
10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker */
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker // membarrier(2) is only supported for bionic builds (b/111199492).
20*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
21*8d67ca89SAndroid Build Coastguard Worker
22*8d67ca89SAndroid Build Coastguard Worker #include <linux/membarrier.h>
23*8d67ca89SAndroid Build Coastguard Worker #include <sys/syscall.h>
24*8d67ca89SAndroid Build Coastguard Worker
25*8d67ca89SAndroid Build Coastguard Worker #include "utils.h"
26*8d67ca89SAndroid Build Coastguard Worker
27*8d67ca89SAndroid Build Coastguard Worker class ScopedErrnoCleaner {
28*8d67ca89SAndroid Build Coastguard Worker public:
ScopedErrnoCleaner()29*8d67ca89SAndroid Build Coastguard Worker ScopedErrnoCleaner() { errno = 0; }
~ScopedErrnoCleaner()30*8d67ca89SAndroid Build Coastguard Worker ~ScopedErrnoCleaner() { errno = 0; }
31*8d67ca89SAndroid Build Coastguard Worker };
32*8d67ca89SAndroid Build Coastguard Worker
HasMembarrier(int membarrier_cmd)33*8d67ca89SAndroid Build Coastguard Worker static bool HasMembarrier(int membarrier_cmd) {
34*8d67ca89SAndroid Build Coastguard Worker ScopedErrnoCleaner errno_cleaner;
35*8d67ca89SAndroid Build Coastguard Worker int supported_cmds = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
36*8d67ca89SAndroid Build Coastguard Worker return (supported_cmds > 0) && ((supported_cmds & membarrier_cmd) != 0);
37*8d67ca89SAndroid Build Coastguard Worker }
38*8d67ca89SAndroid Build Coastguard Worker
TEST(membarrier,query)39*8d67ca89SAndroid Build Coastguard Worker TEST(membarrier, query) {
40*8d67ca89SAndroid Build Coastguard Worker ScopedErrnoCleaner errno_cleaner;
41*8d67ca89SAndroid Build Coastguard Worker int supported = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
42*8d67ca89SAndroid Build Coastguard Worker if (supported == -1 && errno == ENOSYS) GTEST_SKIP() << "no membarrier() in this kernel";
43*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(supported, 0);
44*8d67ca89SAndroid Build Coastguard Worker }
45*8d67ca89SAndroid Build Coastguard Worker
TEST(membarrier,global_barrier)46*8d67ca89SAndroid Build Coastguard Worker TEST(membarrier, global_barrier) {
47*8d67ca89SAndroid Build Coastguard Worker if (!HasMembarrier(MEMBARRIER_CMD_GLOBAL)) {
48*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "MEMBARRIER_CMD_GLOBAL not supported";
49*8d67ca89SAndroid Build Coastguard Worker }
50*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
51*8d67ca89SAndroid Build Coastguard Worker }
52*8d67ca89SAndroid Build Coastguard Worker
MembarrierCommandToName(int membarrier_cmd)53*8d67ca89SAndroid Build Coastguard Worker static const char* MembarrierCommandToName(int membarrier_cmd) {
54*8d67ca89SAndroid Build Coastguard Worker switch (membarrier_cmd) {
55*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_QUERY:
56*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_QUERY";
57*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_GLOBAL:
58*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_GLOBAL";
59*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
60*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_GLOBAL_EXPEDITED";
61*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
62*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
63*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
64*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_PRIVATE_EXPEDITED";
65*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
66*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
67*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
68*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
69*8d67ca89SAndroid Build Coastguard Worker case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
70*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
71*8d67ca89SAndroid Build Coastguard Worker default:
72*8d67ca89SAndroid Build Coastguard Worker return "MEMBARRIER_UNKNOWN";
73*8d67ca89SAndroid Build Coastguard Worker }
74*8d67ca89SAndroid Build Coastguard Worker }
75*8d67ca89SAndroid Build Coastguard Worker
TestRegisterAndBarrierCommands(int membarrier_cmd_register,int membarrier_cmd_barrier)76*8d67ca89SAndroid Build Coastguard Worker static void TestRegisterAndBarrierCommands(int membarrier_cmd_register,
77*8d67ca89SAndroid Build Coastguard Worker int membarrier_cmd_barrier) {
78*8d67ca89SAndroid Build Coastguard Worker if (!HasMembarrier(membarrier_cmd_register)) {
79*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_register) << " not supported";
80*8d67ca89SAndroid Build Coastguard Worker }
81*8d67ca89SAndroid Build Coastguard Worker if (!HasMembarrier(membarrier_cmd_barrier)) {
82*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_barrier) << " not supported";
83*8d67ca89SAndroid Build Coastguard Worker }
84*8d67ca89SAndroid Build Coastguard Worker
85*8d67ca89SAndroid Build Coastguard Worker ScopedErrnoCleaner errno_cleaner;
86*8d67ca89SAndroid Build Coastguard Worker
87*8d67ca89SAndroid Build Coastguard Worker // Check barrier use without prior registration.
88*8d67ca89SAndroid Build Coastguard Worker if (membarrier_cmd_register == MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED) {
89*8d67ca89SAndroid Build Coastguard Worker // Global barrier use is always okay.
90*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
91*8d67ca89SAndroid Build Coastguard Worker } else {
92*8d67ca89SAndroid Build Coastguard Worker // Private barrier should fail.
93*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(-1, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
94*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(EPERM);
95*8d67ca89SAndroid Build Coastguard Worker errno = 0;
96*8d67ca89SAndroid Build Coastguard Worker }
97*8d67ca89SAndroid Build Coastguard Worker
98*8d67ca89SAndroid Build Coastguard Worker // Check registration for barrier succeeds.
99*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_register, 0));
100*8d67ca89SAndroid Build Coastguard Worker
101*8d67ca89SAndroid Build Coastguard Worker // Check barrier use after registration succeeds.
102*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
103*8d67ca89SAndroid Build Coastguard Worker }
104*8d67ca89SAndroid Build Coastguard Worker
TEST(membarrier,global_expedited)105*8d67ca89SAndroid Build Coastguard Worker TEST(membarrier, global_expedited) {
106*8d67ca89SAndroid Build Coastguard Worker TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
107*8d67ca89SAndroid Build Coastguard Worker MEMBARRIER_CMD_GLOBAL_EXPEDITED);
108*8d67ca89SAndroid Build Coastguard Worker }
109*8d67ca89SAndroid Build Coastguard Worker
TEST(membarrier,private_expedited)110*8d67ca89SAndroid Build Coastguard Worker TEST(membarrier, private_expedited) {
111*8d67ca89SAndroid Build Coastguard Worker TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
112*8d67ca89SAndroid Build Coastguard Worker MEMBARRIER_CMD_PRIVATE_EXPEDITED);
113*8d67ca89SAndroid Build Coastguard Worker }
114*8d67ca89SAndroid Build Coastguard Worker
TEST(membarrier,private_expedited_sync_core)115*8d67ca89SAndroid Build Coastguard Worker TEST(membarrier, private_expedited_sync_core) {
116*8d67ca89SAndroid Build Coastguard Worker TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
117*8d67ca89SAndroid Build Coastguard Worker MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE);
118*8d67ca89SAndroid Build Coastguard Worker }
119*8d67ca89SAndroid Build Coastguard Worker
120*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
121