// RUN: %libomp-compile && env LIBOMP_NUM_HIDDEN_HELPER_THREADS=0 OMP_PROC_BIND=close OMP_PLACES=cores KMP_AFFINITY=verbose %libomp-run 8 1 4
// REQUIRES: linux
//
// This test pthread_creates 8 root threads before any OpenMP
// runtime entry is ever called. We have all the root threads
// register with the runtime by calling omp_set_num_threads(),
// but this does not initialize their affinity. The fourth root thread
// then calls a parallel region and we make sure its affinity
// is correct. We also make sure all the other root threads are
// free-floating since they have not called into a parallel region.

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include "libomp_test_affinity.h"

volatile int entry_flag = 0;
volatile int flag = 0;
volatile int num_roots_arrived = 0;
int num_roots;
int spawner = 0;
pthread_mutex_t lock;
int register_workers = 0; // boolean
affinity_mask_t *full_mask;

int __kmpc_global_thread_num(void*);

int get_os_thread_id() {
  return (int)syscall(SYS_gettid);
}

int place_and_affinity_match() {
  int i, max_cpu;
  char buf[512];
  affinity_mask_t *mask = affinity_mask_alloc();
  int place = omp_get_place_num();
  int num_procs = omp_get_place_num_procs(place);
  int *ids = (int*)malloc(sizeof(int) * num_procs);
  omp_get_place_proc_ids(place, ids);
  get_thread_affinity(mask);
  affinity_mask_snprintf(buf, sizeof(buf), mask);
  printf("Primary Thread Place: %d\n", place);
  printf("Primary Thread mask: %s\n", buf);

  for (i = 0; i < num_procs; ++i) {
    int cpu = ids[i];
    if (!affinity_mask_isset(mask, cpu))
      return 0;
  }

  max_cpu = AFFINITY_MAX_CPUS;
  for (i = 0; i < max_cpu; ++i) {
    int cpu = i;
    if (affinity_mask_isset(mask, cpu)) {
      int j, found = 0;
      for (j = 0; j < num_procs; ++j) {
        if (ids[j] == cpu) {
          found = 1;
          break;
        }
      }
      if (!found)
        return 0;
    }
  }

  affinity_mask_free(mask);
  free(ids);
  return 1;
}

void* thread_func(void *arg) {
  int place, nplaces;
  int root_id = *((int*)arg);
  int pid = getpid();
  int tid = get_os_thread_id();

  // Order how the root threads are assigned a gtid in the runtime
  // i.e., root_id = gtid
  while (1) {
    int v = entry_flag;
    if (v == root_id)
      break;
  }

  // If main root thread
  if (root_id == spawner) {
    printf("Initial application thread (pid=%d, tid=%d, spawner=%d) reached thread_func (will call OpenMP)\n", pid, tid, spawner);
    omp_set_num_threads(4);
    #pragma omp atomic
    entry_flag++;
    // Wait for the workers to signal their arrival before #pragma omp parallel
    while (num_roots_arrived < num_roots - 1) {}
    // This will trigger the output for KMP_AFFINITY in this case
    #pragma omp parallel
    {
      int gtid = __kmpc_global_thread_num(NULL);
      #pragma omp single
      {
        printf("Exactly %d threads in the #pragma omp parallel\n",
               omp_get_num_threads());
      }
      #pragma omp critical
      {
        printf("OpenMP thread %d: gtid=%d\n", omp_get_thread_num(), gtid);
      }
    }
    flag = 1;
    if (!place_and_affinity_match()) {
      fprintf(stderr, "error: place and affinity mask do not match for primary thread\n");
      exit (EXIT_FAILURE);
    }

  } else { // If worker root thread
    // Worker root threads, register with OpenMP through omp_set_num_threads()
    // if designated to, signal their arrival and then wait for the main root
    // thread to signal them to exit.
    printf("New root pthread (pid=%d, tid=%d) reached thread_func\n", pid, tid);
    if (register_workers)
      omp_set_num_threads(4);
    #pragma omp atomic
    entry_flag++;

    pthread_mutex_lock(&lock);
    num_roots_arrived++;
    pthread_mutex_unlock(&lock);
    while (flag == 0) {}

    // Main check whether root threads' mask is equal to the
    // initial affinity mask
    affinity_mask_t *mask = affinity_mask_alloc();
    get_thread_affinity(mask);
    if (!affinity_mask_equal(mask, full_mask)) {
      char buf[1024];
      printf("root thread %d mask: ", root_id);
      affinity_mask_snprintf(buf, sizeof(buf), mask);
      printf("initial affinity mask: %s\n", buf);
      fprintf(stderr, "error: root thread %d affinity mask not equal"
                      " to initial full mask\n", root_id);
      affinity_mask_free(mask);
      exit(EXIT_FAILURE);
    }
    affinity_mask_free(mask);
  }
  return NULL;
}

int main(int argc, char** argv) {
  int i;
  if (argc != 3 && argc != 4) {
    fprintf(stderr, "usage: %s <num_roots> <register_workers_bool> [<spawn_root_number>]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  // Initialize pthread mutex
  pthread_mutex_init(&lock, NULL);

  // Get initial full mask
  full_mask = affinity_mask_alloc();
  get_thread_affinity(full_mask);

  // Get the number of root pthreads to create and allocate resources for them
  num_roots = atoi(argv[1]);
  pthread_t *roots = (pthread_t*)malloc(sizeof(pthread_t) * num_roots);
  int *root_ids = (int*)malloc(sizeof(int) * num_roots);

  // Get the flag indicating whether to have root pthreads call omp_set_num_threads() or not
  register_workers = atoi(argv[2]);

  if (argc == 4)
    spawner = atoi(argv[3]);

  // Spawn worker root threads
  for (i = 1; i < num_roots; ++i) {
    *(root_ids + i) = i;
    pthread_create(roots + i, NULL, thread_func, root_ids + i);
  }
  // Have main root thread (root 0) go into thread_func
  *root_ids = 0;
  thread_func(root_ids);

  // Cleanup all resources
  for (i = 1; i < num_roots; ++i) {
    void *status;
    pthread_join(roots[i], &status);
  }
  free(roots);
  free(root_ids);
  pthread_mutex_destroy(&lock);
  return EXIT_SUCCESS;
}
