//===-- sanitizer_stoptheworld_test.cc ------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Tests for sanitizer_stoptheworld.h
//
//===----------------------------------------------------------------------===//

#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_LINUX && defined(__x86_64__)

#include "sanitizer_common/sanitizer_stoptheworld.h"
#include "gtest/gtest.h"

#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_common.h"

#include <pthread.h>
#include <sched.h>

namespace __sanitizer {

static pthread_mutex_t incrementer_thread_exit_mutex;

struct CallbackArgument {
  volatile int counter;
  volatile bool threads_stopped;
  volatile bool callback_executed;
  CallbackArgument()
    : counter(0),
      threads_stopped(false),
      callback_executed(false) {}
};

void *IncrementerThread(void *argument) {
  CallbackArgument *callback_argument = (CallbackArgument *)argument;
  while (true) {
    __sync_fetch_and_add(&callback_argument->counter, 1);
    if (pthread_mutex_trylock(&incrementer_thread_exit_mutex) == 0) {
      pthread_mutex_unlock(&incrementer_thread_exit_mutex);
      return NULL;
    } else {
      sched_yield();
    }
  }
}

// This callback checks that IncrementerThread is suspended at the time of its
// execution.
void Callback(const SuspendedThreadsList &suspended_threads_list,
              void *argument) {
  CallbackArgument *callback_argument = (CallbackArgument *)argument;
  callback_argument->callback_executed = true;
  int counter_at_init = __sync_fetch_and_add(&callback_argument->counter, 0);
  for (uptr i = 0; i < 1000; i++) {
    sched_yield();
    if (__sync_fetch_and_add(&callback_argument->counter, 0) !=
          counter_at_init) {
      callback_argument->threads_stopped = false;
      return;
    }
  }
  callback_argument->threads_stopped = true;
}

TEST(StopTheWorld, SuspendThreadsSimple) {
  pthread_mutex_init(&incrementer_thread_exit_mutex, NULL);
  CallbackArgument argument;
  pthread_t thread_id;
  int pthread_create_result;
  pthread_mutex_lock(&incrementer_thread_exit_mutex);
  pthread_create_result = pthread_create(&thread_id, NULL, IncrementerThread,
                                         &argument);
  ASSERT_EQ(0, pthread_create_result);
  StopTheWorld(&Callback, &argument);
  pthread_mutex_unlock(&incrementer_thread_exit_mutex);
  EXPECT_TRUE(argument.callback_executed);
  EXPECT_TRUE(argument.threads_stopped);
  // argument is on stack, so we have to wait for the incrementer thread to
  // terminate before we can return from this function.
  ASSERT_EQ(0, pthread_join(thread_id, NULL));
  pthread_mutex_destroy(&incrementer_thread_exit_mutex);
}

// A more comprehensive test where we spawn a bunch of threads while executing
// StopTheWorld in parallel.
static const uptr kThreadCount = 50;
static const uptr kStopWorldAfter = 10; // let this many threads spawn first

static pthread_mutex_t advanced_incrementer_thread_exit_mutex;

struct AdvancedCallbackArgument {
  volatile uptr thread_index;
  volatile int counters[kThreadCount];
  pthread_t thread_ids[kThreadCount];
  volatile bool threads_stopped;
  volatile bool callback_executed;
  volatile bool fatal_error;
  AdvancedCallbackArgument()
    : thread_index(0),
      threads_stopped(false),
      callback_executed(false),
      fatal_error(false) {}
};

void *AdvancedIncrementerThread(void *argument) {
  AdvancedCallbackArgument *callback_argument =
      (AdvancedCallbackArgument *)argument;
  uptr this_thread_index = __sync_fetch_and_add(
      &callback_argument->thread_index, 1);
  // Spawn the next thread.
  int pthread_create_result;
  if (this_thread_index + 1 < kThreadCount) {
    pthread_create_result =
        pthread_create(&callback_argument->thread_ids[this_thread_index + 1],
                       NULL, AdvancedIncrementerThread, argument);
    // Cannot use ASSERT_EQ in non-void-returning functions. If there's a
    // problem, defer failing to the main thread.
    if (pthread_create_result != 0) {
      callback_argument->fatal_error = true;
      __sync_fetch_and_add(&callback_argument->thread_index,
                           kThreadCount - callback_argument->thread_index);
    }
  }
  // Do the actual work.
  while (true) {
    __sync_fetch_and_add(&callback_argument->counters[this_thread_index], 1);
    if (pthread_mutex_trylock(&advanced_incrementer_thread_exit_mutex) == 0) {
      pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
      return NULL;
    } else {
      sched_yield();
    }
  }
}

void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
                             void *argument) {
  AdvancedCallbackArgument *callback_argument =
      (AdvancedCallbackArgument *)argument;
  callback_argument->callback_executed = true;

  int counters_at_init[kThreadCount];
  for (uptr j = 0; j < kThreadCount; j++)
    counters_at_init[j] = __sync_fetch_and_add(&callback_argument->counters[j],
                                               0);
  for (uptr i = 0; i < 10; i++) {
    sched_yield();
    for (uptr j = 0; j < kThreadCount; j++)
      if (__sync_fetch_and_add(&callback_argument->counters[j], 0) !=
            counters_at_init[j]) {
        callback_argument->threads_stopped = false;
        return;
      }
  }
  callback_argument->threads_stopped = true;
}

TEST(StopTheWorld, SuspendThreadsAdvanced) {
  pthread_mutex_init(&advanced_incrementer_thread_exit_mutex, NULL);
  AdvancedCallbackArgument argument;

  pthread_mutex_lock(&advanced_incrementer_thread_exit_mutex);
  int pthread_create_result;
  pthread_create_result = pthread_create(&argument.thread_ids[0], NULL,
                                         AdvancedIncrementerThread,
                                         &argument);
  ASSERT_EQ(0, pthread_create_result);
  // Wait for several threads to spawn before proceeding.
  while (__sync_fetch_and_add(&argument.thread_index, 0) < kStopWorldAfter)
    sched_yield();
  StopTheWorld(&AdvancedCallback, &argument);
  EXPECT_TRUE(argument.callback_executed);
  EXPECT_TRUE(argument.threads_stopped);

  // Wait for all threads to spawn before we start terminating them.
  while (__sync_fetch_and_add(&argument.thread_index, 0) < kThreadCount)
    sched_yield();
  ASSERT_FALSE(argument.fatal_error); // a pthread_create has failed
  // Signal the threads to terminate.
  pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
  for (uptr i = 0; i < kThreadCount; i++)
    ASSERT_EQ(0, pthread_join(argument.thread_ids[i], NULL));
  pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex);
}

static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,
                         void *argument) {
  *(volatile int*)0x1234 = 0;
}

TEST(StopTheWorld, SegvInCallback) {
  // Test that tracer thread catches SIGSEGV.
  StopTheWorld(&SegvCallback, NULL);
}

}  // namespace __sanitizer

#endif  // SANITIZER_LINUX && defined(__x86_64__)
