Home | History | Annotate | Download | only in base
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "membarrier.h"
     18 
     19 #include <errno.h>
     20 
     21 #if !defined(_WIN32)
     22 #include <sys/syscall.h>
     23 #include <unistd.h>
     24 #endif
     25 #include "macros.h"
     26 
     27 #if defined(__BIONIC__)
     28 
     29 #include <atomic>
     30 #include <linux/membarrier.h>
     31 
     32 #define CHECK_MEMBARRIER_CMD(art_value, membarrier_value) \
     33   static_assert(static_cast<int>(art_value) == (membarrier_value), "Bad value for " # art_value)
     34 CHECK_MEMBARRIER_CMD(art::MembarrierCommand::kQuery, MEMBARRIER_CMD_QUERY);
     35 CHECK_MEMBARRIER_CMD(art::MembarrierCommand::kGlobal, MEMBARRIER_CMD_SHARED);
     36 CHECK_MEMBARRIER_CMD(art::MembarrierCommand::kPrivateExpedited, MEMBARRIER_CMD_PRIVATE_EXPEDITED);
     37 CHECK_MEMBARRIER_CMD(art::MembarrierCommand::kRegisterPrivateExpedited,
     38                      MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED);
     39 CHECK_MEMBARRIER_CMD(art::MembarrierCommand::kPrivateExpedited, MEMBARRIER_CMD_PRIVATE_EXPEDITED);
     40 #undef CHECK_MEMBARRIER_CMD
     41 
     42 #endif  // __BIONIC
     43 
     44 namespace art {
     45 
     46 #if defined(__NR_membarrier)
     47 
     48 int membarrier(MembarrierCommand command) {
     49 #if defined(__BIONIC__)
     50   // Avoid calling membarrier on older Android versions where membarrier may be barred by secomp
     51   // causing the current process to be killed. The probing here could be considered expensive so
     52   // endeavour not to repeat too often.
     53   static int api_level = android_get_device_api_level();
     54   if (api_level < __ANDROID_API_Q__) {
     55     errno = ENOSYS;
     56     return -1;
     57   }
     58 #endif  // __BIONIC__
     59   return syscall(__NR_membarrier, static_cast<int>(command), 0);
     60 }
     61 
     62 #else  // __NR_membarrier
     63 
     64 int membarrier(MembarrierCommand command ATTRIBUTE_UNUSED) {
     65   // In principle this could be supported on linux, but Android's prebuilt glibc does not include
     66   // the system call number defintions (b/111199492).
     67   errno = ENOSYS;
     68   return -1;
     69 }
     70 
     71 #endif  // __NR_membarrier
     72 
     73 }  // namespace art
     74