//===-- main.cpp ------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// This test is intended to create a situation in which multiple events
// (breakpoints, watchpoints, crashes, and signal generation/delivery) happen
// from multiple threads. The test expects the debugger to set a breakpoint on
// the main thread (before any worker threads are spawned) and modify variables
// which control the number of threads that are spawned for each action.

#include "pseudo_barrier.h"
#include <vector>
using namespace std;

#include <pthread.h>

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

typedef std::vector<std::pair<unsigned, void*(*)(void*)> > action_counts;
typedef std::vector<pthread_t> thread_vector;

pseudo_barrier_t g_barrier;
int g_breakpoint = 0;
int g_sigusr1_count = 0;
uint32_t g_watchme;

struct action_args {
  int delay;
};

// Perform any extra actions required by thread 'input' arg
void do_action_args(void *input) {
    if (input) {
      action_args *args = static_cast<action_args*>(input);
      sleep(args->delay);
    }
}

void *
breakpoint_func (void *input)
{
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Do something
    g_breakpoint++;       // Set breakpoint here
    return 0;
}

void *
signal_func (void *input) {
    // Wait until all threads are running
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    // Send a user-defined signal to the current process
    //kill(getpid(), SIGUSR1);
    // Send a user-defined signal to the current thread
    pthread_kill(pthread_self(), SIGUSR1);

    return 0;
}

void *
watchpoint_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    g_watchme = 1;     // watchpoint triggers here
    return 0;
}

void *
crash_func (void *input) {
    pseudo_barrier_wait(g_barrier);
    do_action_args(input);

    int *a = 0;
    *a = 5; // crash happens here
    return 0;
}

void sigusr1_handler(int sig) {
    if (sig == SIGUSR1)
        g_sigusr1_count += 1; // Break here in signal handler
}

/// Register a simple function for to handle signal
void register_signal_handler(int signal, void (*handler)(int))
{
    sigset_t empty_sigset;
    sigemptyset(&empty_sigset);

    struct sigaction action;
    action.sa_sigaction = 0;
    action.sa_mask = empty_sigset;
    action.sa_flags = 0;
    action.sa_handler = handler;
    sigaction(SIGUSR1, &action, 0);
}

void start_threads(thread_vector& threads,
                   action_counts& actions,
                   void* args = 0) {
    action_counts::iterator b = actions.begin(), e = actions.end();
    for(action_counts::iterator i = b; i != e; ++i) {
        for(unsigned count = 0; count < i->first; ++count) {
            pthread_t t;
            pthread_create(&t, 0, i->second, args);
            threads.push_back(t);
        }
    }
}

int dotest()
{
    g_watchme = 0;

    // Actions are triggered immediately after the thread is spawned
    unsigned num_breakpoint_threads = 1;
    unsigned num_watchpoint_threads = 0;
    unsigned num_signal_threads = 1;
    unsigned num_crash_threads = 0;

    // Actions below are triggered after a 1-second delay
    unsigned num_delay_breakpoint_threads = 0;
    unsigned num_delay_watchpoint_threads = 0;
    unsigned num_delay_signal_threads = 0;
    unsigned num_delay_crash_threads = 0;

    register_signal_handler(SIGUSR1, sigusr1_handler); // Break here and adjust num_[breakpoint|watchpoint|signal|crash]_threads

    unsigned total_threads = num_breakpoint_threads \
                             + num_watchpoint_threads \
                             + num_signal_threads \
                             + num_crash_threads \
                             + num_delay_breakpoint_threads \
                             + num_delay_watchpoint_threads \
                             + num_delay_signal_threads \
                             + num_delay_crash_threads;

    // Don't let either thread do anything until they're both ready.
    pseudo_barrier_init(g_barrier, total_threads);

    action_counts actions;
    actions.push_back(std::make_pair(num_breakpoint_threads, breakpoint_func));
    actions.push_back(std::make_pair(num_watchpoint_threads, watchpoint_func));
    actions.push_back(std::make_pair(num_signal_threads, signal_func));
    actions.push_back(std::make_pair(num_crash_threads, crash_func));

    action_counts delay_actions;
    delay_actions.push_back(std::make_pair(num_delay_breakpoint_threads, breakpoint_func));
    delay_actions.push_back(std::make_pair(num_delay_watchpoint_threads, watchpoint_func));
    delay_actions.push_back(std::make_pair(num_delay_signal_threads, signal_func));
    delay_actions.push_back(std::make_pair(num_delay_crash_threads, crash_func));

    // Create threads that handle instant actions
    thread_vector threads;
    start_threads(threads, actions);

    // Create threads that handle delayed actions
    action_args delay_arg;
    delay_arg.delay = 1;
    start_threads(threads, delay_actions, &delay_arg);

    // Join all threads
    typedef std::vector<pthread_t>::iterator thread_iterator;
    for(thread_iterator t = threads.begin(); t != threads.end(); ++t)
        pthread_join(*t, 0);

    return 0;
}

int main ()
{
    dotest();
    return 0; // Break here and verify one thread is active.
}


