/*
 * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "logging/log.hpp"
#include "os_linux.hpp"
#include "utilities/debug.hpp"
#include "utilities/systemMemoryBarrier.hpp"

#include <sys/syscall.h>

// Syscall defined in kernel 4.3
// Oracle x64 builds may use old sysroot (pre 4.3)
#ifndef SYS_membarrier
  #if defined(AMD64)
  #define SYS_membarrier 324
  #elif defined(X86)
  #define SYS_membarrier 375
  #elif defined(PPC64)
  #define SYS_membarrier 365
  #elif defined(AARCH64)
  #define SYS_membarrier 283
  #elif defined(ARM32)
  #define SYS_membarrier 389
  #elif defined(ALPHA)
  #define SYS_membarrier 517
  #else
  #error define SYS_membarrier for the arch
  #endif
#endif // SYS_membarrier

// Expedited defined in kernel 4.14
// Therefore we define it here instead of including linux/membarrier.h
enum membarrier_cmd {
  MEMBARRIER_CMD_QUERY                      = 0,
  MEMBARRIER_CMD_PRIVATE_EXPEDITED          = (1 << 3),
  MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
};

static long membarrier(int cmd, unsigned int flags, int cpu_id) {
  return syscall(SYS_membarrier, cmd, flags, cpu_id); // cpu_id only on >= 5.10
}

bool LinuxSystemMemoryBarrier::initialize() {
#if defined(RISCV)
// RISCV port was introduced in kernel 4.4.
// 4.4 also made membar private expedited mandatory.
// But RISCV actually don't support it until 6.9.
  long major, minor, patch;
  os::Linux::kernel_version(&major, &minor, &patch);
  if (os::Linux::kernel_version_compare(major, minor, patch, 6, 9, 0) == -1) {
    log_info(os)("Linux kernel %ld.%ld.%ld does not support MEMBARRIER PRIVATE_EXPEDITED on RISC-V.",
                 major, minor, patch);
    return false;
  }
#endif
  long ret = membarrier(MEMBARRIER_CMD_QUERY, 0, 0);
  if (ret < 0) {
    log_info(os)("MEMBARRIER_CMD_QUERY unsupported");
    return false;
  }
  if (!(ret & MEMBARRIER_CMD_PRIVATE_EXPEDITED) ||
      !(ret & MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)) {
    log_info(os)("MEMBARRIER PRIVATE_EXPEDITED unsupported");
    return false;
  }
  ret = membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0, 0);
  guarantee_with_errno(ret == 0, "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED failed");
  log_info(os)("Using MEMBARRIER PRIVATE_EXPEDITED");
  return true;
}

void LinuxSystemMemoryBarrier::emit() {
  long s = membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0, 0);
  guarantee_with_errno(s >= 0, "MEMBARRIER_CMD_PRIVATE_EXPEDITED failed");
}
