/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

// membarrier(2) is only supported for bionic builds (b/111199492).
#if defined(__BIONIC__)

#include <linux/membarrier.h>
#include <sys/syscall.h>

#include "utils.h"

class ScopedErrnoCleaner {
 public:
  ScopedErrnoCleaner() { errno = 0; }
  ~ScopedErrnoCleaner() { errno = 0; }
};

static bool HasMembarrier(int membarrier_cmd) {
  ScopedErrnoCleaner errno_cleaner;
  int supported_cmds = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
  return (supported_cmds > 0) && ((supported_cmds & membarrier_cmd) != 0);
}

TEST(membarrier, query) {
  ScopedErrnoCleaner errno_cleaner;
  int supported = syscall(__NR_membarrier, MEMBARRIER_CMD_QUERY, 0);
  if (supported == -1 && errno == ENOSYS) GTEST_SKIP() << "no membarrier() in this kernel";
  ASSERT_GE(supported, 0);
}

TEST(membarrier, global_barrier) {
  if (!HasMembarrier(MEMBARRIER_CMD_GLOBAL)) {
    GTEST_SKIP() << "MEMBARRIER_CMD_GLOBAL not supported";
  }
  ASSERT_EQ(0, syscall(__NR_membarrier, MEMBARRIER_CMD_GLOBAL, 0));
}

static const char* MembarrierCommandToName(int membarrier_cmd) {
  switch (membarrier_cmd) {
  case MEMBARRIER_CMD_QUERY:
    return "MEMBARRIER_CMD_QUERY";
  case MEMBARRIER_CMD_GLOBAL:
    return "MEMBARRIER_CMD_GLOBAL";
  case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
    return "MEMBARRIER_CMD_GLOBAL_EXPEDITED";
  case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
    return "MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
  case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
    return "MEMBARRIER_CMD_PRIVATE_EXPEDITED";
  case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
    return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
  case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
    return "MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
  case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
    return "MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
  default:
    return "MEMBARRIER_UNKNOWN";
  }
}

static void TestRegisterAndBarrierCommands(int membarrier_cmd_register,
                                           int membarrier_cmd_barrier) {
  if (!HasMembarrier(membarrier_cmd_register)) {
    GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_register) << " not supported";
  }
  if (!HasMembarrier(membarrier_cmd_barrier)) {
    GTEST_SKIP() << MembarrierCommandToName(membarrier_cmd_barrier) << " not supported";
  }

  ScopedErrnoCleaner errno_cleaner;

  // Check barrier use without prior registration.
  if (membarrier_cmd_register == MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED) {
    // Global barrier use is always okay.
    ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
  } else {
    // Private barrier should fail.
    ASSERT_EQ(-1, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
    ASSERT_ERRNO(EPERM);
    errno = 0;
  }

  // Check registration for barrier succeeds.
  ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_register, 0));

  // Check barrier use after registration succeeds.
  ASSERT_EQ(0, syscall(__NR_membarrier, membarrier_cmd_barrier, 0));
}

TEST(membarrier, global_expedited) {
  TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED,
                                 MEMBARRIER_CMD_GLOBAL_EXPEDITED);
}

TEST(membarrier, private_expedited) {
  TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED,
                                 MEMBARRIER_CMD_PRIVATE_EXPEDITED);
}

TEST(membarrier, private_expedited_sync_core) {
  TestRegisterAndBarrierCommands(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE,
                                 MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE);
}

#endif  // __BIONIC__
