/*
 * Copyright (C) 2014 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 <semaphore.h>

#include <errno.h>
#include <gtest/gtest.h>
#include <limits.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>

#include "private/bionic_constants.h"
#include "SignalUtils.h"

TEST(semaphore, sem_init) {
  sem_t s;

  // Perfectly fine initial values.
  ASSERT_EQ(0, sem_init(&s, 0, 0));
  ASSERT_EQ(0, sem_init(&s, 0, 1));
  ASSERT_EQ(0, sem_init(&s, 0, 123));

  // Too small an initial value.
  errno = 0;
  ASSERT_EQ(-1, sem_init(&s, 0, -1));
  ASSERT_EQ(EINVAL, errno);

  ASSERT_EQ(SEM_VALUE_MAX, sysconf(_SC_SEM_VALUE_MAX));

  // The largest initial value.
  ASSERT_EQ(0, sem_init(&s, 0, SEM_VALUE_MAX));

  // Too large an initial value.
  errno = 0;
  ASSERT_EQ(-1, sem_init(&s, 0, SEM_VALUE_MAX + 1));
  ASSERT_EQ(EINVAL, errno);

  ASSERT_EQ(0, sem_destroy(&s));
}

TEST(semaphore, sem_trywait) {
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 3));
  ASSERT_EQ(0, sem_trywait(&s));
  ASSERT_EQ(0, sem_trywait(&s));
  ASSERT_EQ(0, sem_trywait(&s));
  errno = 0;
  ASSERT_EQ(-1, sem_trywait(&s));
  ASSERT_EQ(EAGAIN, errno);
  ASSERT_EQ(0, sem_destroy(&s));
}

static void SemWaitThreadTestFn(sem_t& sem) {
  ASSERT_EQ(0, sem_wait(&sem));
}

static void* SemWaitThreadFn(void* arg) {
  SemWaitThreadTestFn(*reinterpret_cast<sem_t*>(arg));
  return nullptr;
}

TEST(semaphore, sem_wait__sem_post) {
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));

  pthread_t t1, t2, t3;
  ASSERT_EQ(0, pthread_create(&t1, NULL, SemWaitThreadFn, &s));
  ASSERT_EQ(0, pthread_create(&t2, NULL, SemWaitThreadFn, &s));
  ASSERT_EQ(0, pthread_create(&t3, NULL, SemWaitThreadFn, &s));

  ASSERT_EQ(0, sem_post(&s));
  ASSERT_EQ(0, sem_post(&s));
  ASSERT_EQ(0, sem_post(&s));

  void* result;
  ASSERT_EQ(0, pthread_join(t1, &result));
  ASSERT_EQ(0, pthread_join(t2, &result));
  ASSERT_EQ(0, pthread_join(t3, &result));
}

static inline void timespec_add_ms(timespec& ts, size_t ms) {
  ts.tv_sec  += ms / 1000;
  ts.tv_nsec += (ms % 1000) * 1000000;
  if (ts.tv_nsec >= NS_PER_S) {
    ts.tv_sec++;
    ts.tv_nsec -= NS_PER_S;
  }
}

static void sem_timedwait_helper(clockid_t clock,
                                 int (*wait_function)(sem_t* __sem, const timespec* __ts)) {
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));

  timespec ts;
  ASSERT_EQ(0, clock_gettime(clock, &ts));
  timespec_add_ms(ts, 100);

  errno = 0;
  ASSERT_EQ(-1, wait_function(&s, &ts));
  ASSERT_EQ(ETIMEDOUT, errno);

  // A negative timeout is an error.
  errno = 0;
  ts.tv_nsec = -1;
  ASSERT_EQ(-1, wait_function(&s, &ts));
  ASSERT_EQ(EINVAL, errno);
  errno = 0;
  ts.tv_nsec = NS_PER_S;
  ASSERT_EQ(-1, wait_function(&s, &ts));
  ASSERT_EQ(EINVAL, errno);

  errno = 0;
  ts.tv_nsec = NS_PER_S - 1;
  ts.tv_sec = -1;
  ASSERT_EQ(-1, wait_function(&s, &ts));
  ASSERT_EQ(ETIMEDOUT, errno);

  ASSERT_EQ(0, sem_destroy(&s));
}

TEST(semaphore, sem_timedwait) {
  sem_timedwait_helper(CLOCK_REALTIME, sem_timedwait);
}

TEST(semaphore, sem_timedwait_monotonic_np) {
#if defined(__BIONIC__)
  sem_timedwait_helper(CLOCK_MONOTONIC, sem_timedwait_monotonic_np);
#else   // __BIONIC__
  GTEST_LOG_(INFO)
      << "This test does nothing since sem_timedwait_monotonic_np is only supported on bionic";
#endif  // __BIONIC__
}

TEST(semaphore_DeathTest, sem_timedwait_null_timeout) {
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));

  ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
}

TEST(semaphore, sem_getvalue) {
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));

  int i;
  ASSERT_EQ(0, sem_getvalue(&s, &i));
  ASSERT_EQ(0, i);

  ASSERT_EQ(0, sem_post(&s));
  ASSERT_EQ(0, sem_getvalue(&s, &i));
  ASSERT_EQ(1, i);

  ASSERT_EQ(0, sem_post(&s));
  ASSERT_EQ(0, sem_getvalue(&s, &i));
  ASSERT_EQ(2, i);

  ASSERT_EQ(0, sem_wait(&s));
  ASSERT_EQ(0, sem_getvalue(&s, &i));
  ASSERT_EQ(1, i);
}

extern "C" void android_set_application_target_sdk_version(uint32_t target);

static void sem_wait_test_signal_handler(int) {
}

static void* SemWaitEINTRThreadFn(void* arg) {
  sem_t* sem = reinterpret_cast<sem_t*>(arg);
  uintptr_t have_eintr = 0;
  uintptr_t have_error = 0;
  while (true) {
    int result = sem_wait(sem);
    if (result == 0) {
      break;
    }
    if (result == -1) {
      if (errno == EINTR) {
        have_eintr = 1;
      } else {
        have_error = 1;
        break;
      }
    }
  }
  return reinterpret_cast<void*>((have_eintr << 1) | have_error);
}

TEST(semaphore, sem_wait_no_EINTR_in_sdk_less_equal_than_23) {
#if defined(__BIONIC__)
  android_set_application_target_sdk_version(__ANDROID_API_M__);
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));
  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
  pthread_t thread;
  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
  // Give some time for the thread to run sem_wait.
  usleep(500000);
  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
  // Give some time for the thread to handle signal.
  usleep(500000);
  ASSERT_EQ(0, sem_post(&s));
  void* result;
  ASSERT_EQ(0, pthread_join(thread, &result));
  ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(result));
#else
  GTEST_LOG_(INFO) << "This test tests sem_wait's compatibility for old sdk versions";
#endif
}

TEST(semaphore, sem_wait_EINTR_in_sdk_greater_than_23) {
#if defined(__BIONIC__)
  android_set_application_target_sdk_version(24U);
#endif
  sem_t s;
  ASSERT_EQ(0, sem_init(&s, 0, 0));
  ScopedSignalHandler handler(SIGUSR1, sem_wait_test_signal_handler);
  pthread_t thread;
  ASSERT_EQ(0, pthread_create(&thread, nullptr, SemWaitEINTRThreadFn, &s));
  // Give some time for the thread to run sem_wait.
  usleep(500000);
  ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
  // Give some time for the thread to handle signal.
  usleep(500000);
  ASSERT_EQ(0, sem_post(&s));
  void* result;
  ASSERT_EQ(0, pthread_join(thread, &result));
  ASSERT_EQ(2U, reinterpret_cast<uintptr_t>(result));
}
