< prev index next >

src/hotspot/os/linux/systemMemoryBarrier_linux.cpp

Print this page

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "logging/log.hpp"
 27 #include "runtime/os.hpp"
 28 #include "utilities/debug.hpp"
 29 #include "utilities/systemMemoryBarrier.hpp"
 30 
 31 #include <sys/syscall.h>
 32 
 33 // Syscall defined in kernel 4.3
 34 // Oracle x64 builds may use old sysroot (pre 4.3)
 35 #ifndef SYS_membarrier
 36   #if defined(AMD64)
 37   #define SYS_membarrier 324
 38   #elif defined(X86)
 39   #define SYS_membarrier 375
 40   #elif defined(PPC64)
 41   #define SYS_membarrier 365
 42   #elif defined(AARCH64)
 43   #define SYS_membarrier 283
 44   #elif defined(ALPHA)
 45   #define SYS_membarrier 517
 46   #else
 47   #error define SYS_membarrier for the arch

 53 enum membarrier_cmd {
 54   MEMBARRIER_CMD_QUERY                      = 0,
 55   MEMBARRIER_CMD_PRIVATE_EXPEDITED          = (1 << 3),
 56   MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
 57 };
 58 
 59 #define check_with_errno(check_type, cond, msg)                             \
 60   do {                                                                      \
 61     int err = errno;                                                        \
 62     check_type(cond, "%s: error='%s' (errno=%s)", msg, os::strerror(err),   \
 63                os::errno_name(err));                                        \
 64 } while (false)
 65 
 66 #define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
 67 
 68 static int membarrier(int cmd, unsigned int flags, int cpu_id) {
 69   return syscall(SYS_membarrier, cmd, flags, cpu_id); // cpu_id only on >= 5.10
 70 }
 71 
 72 bool LinuxSystemMemoryBarrier::initialize() {












 73   int ret = membarrier(MEMBARRIER_CMD_QUERY, 0, 0);
 74   if (ret < 0) {
 75     log_info(os)("MEMBARRIER_CMD_QUERY unsupported");
 76     return false;
 77   }
 78   if (!(ret & MEMBARRIER_CMD_PRIVATE_EXPEDITED) ||
 79       !(ret & MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)) {
 80     log_info(os)("MEMBARRIER PRIVATE_EXPEDITED unsupported");
 81     return false;
 82   }
 83   ret = membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0);
 84   guarantee_with_errno(ret == 0, "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED failed");
 85   log_info(os)("Using MEMBARRIER PRIVATE_EXPEDITED");
 86   return true;
 87 }
 88 
 89 void LinuxSystemMemoryBarrier::emit() {
 90   int s = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0);
 91   guarantee_with_errno(s >= 0, "MEMBARRIER_CMD_PRIVATE_EXPEDITED failed");
 92 }

  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 #include "logging/log.hpp"
 27 #include "os_linux.hpp"
 28 #include "utilities/debug.hpp"
 29 #include "utilities/systemMemoryBarrier.hpp"
 30 
 31 #include <sys/syscall.h>
 32 
 33 // Syscall defined in kernel 4.3
 34 // Oracle x64 builds may use old sysroot (pre 4.3)
 35 #ifndef SYS_membarrier
 36   #if defined(AMD64)
 37   #define SYS_membarrier 324
 38   #elif defined(X86)
 39   #define SYS_membarrier 375
 40   #elif defined(PPC64)
 41   #define SYS_membarrier 365
 42   #elif defined(AARCH64)
 43   #define SYS_membarrier 283
 44   #elif defined(ALPHA)
 45   #define SYS_membarrier 517
 46   #else
 47   #error define SYS_membarrier for the arch

 53 enum membarrier_cmd {
 54   MEMBARRIER_CMD_QUERY                      = 0,
 55   MEMBARRIER_CMD_PRIVATE_EXPEDITED          = (1 << 3),
 56   MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
 57 };
 58 
 59 #define check_with_errno(check_type, cond, msg)                             \
 60   do {                                                                      \
 61     int err = errno;                                                        \
 62     check_type(cond, "%s: error='%s' (errno=%s)", msg, os::strerror(err),   \
 63                os::errno_name(err));                                        \
 64 } while (false)
 65 
 66 #define guarantee_with_errno(cond, msg) check_with_errno(guarantee, cond, msg)
 67 
 68 static int membarrier(int cmd, unsigned int flags, int cpu_id) {
 69   return syscall(SYS_membarrier, cmd, flags, cpu_id); // cpu_id only on >= 5.10
 70 }
 71 
 72 bool LinuxSystemMemoryBarrier::initialize() {
 73 #if defined(RISCV)
 74 // RISCV port was introduced in kernel 4.4.
 75 // 4.4 also made membar private expedited mandatory.
 76 // But RISCV actually don't support it until 6.9.
 77   long major, minor;
 78   os::Linux::kernel_version(&major, &minor);
 79   if (!(major > 6 || (major == 6 && minor >= 9))) {
 80     log_info(os)("Linux kernel %ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.",
 81                  major, minor);
 82     return false;
 83   }
 84 #endif
 85   int ret = membarrier(MEMBARRIER_CMD_QUERY, 0, 0);
 86   if (ret < 0) {
 87     log_info(os)("MEMBARRIER_CMD_QUERY unsupported");
 88     return false;
 89   }
 90   if (!(ret & MEMBARRIER_CMD_PRIVATE_EXPEDITED) ||
 91       !(ret & MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)) {
 92     log_info(os)("MEMBARRIER PRIVATE_EXPEDITED unsupported");
 93     return false;
 94   }
 95   ret = membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0);
 96   guarantee_with_errno(ret == 0, "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED failed");
 97   log_info(os)("Using MEMBARRIER PRIVATE_EXPEDITED");
 98   return true;
 99 }
100 
101 void LinuxSystemMemoryBarrier::emit() {
102   int s = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0);
103   guarantee_with_errno(s >= 0, "MEMBARRIER_CMD_PRIVATE_EXPEDITED failed");
104 }
< prev index next >