xref: /aosp_15_r20/bionic/tests/membarrier_test.cpp (revision 8d67ca893c1523eb926b9080dbe4e2ffd2a27ba1)
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