/*
 * Test whether all data races are detected in a multithreaded program with
 * user-annotated barriers. See also pth_barrier.c.
 */


#define _GNU_SOURCE


#include <pthread.h> /* pthread_create() */
#include <stdio.h>   /* fprintf() */
#include <stdlib.h>  /* atoi() */
#include <string.h>  /* memset() */
#include <unistd.h>  /* usleep() */
#include "../../drd/drd.h"
#include "../../config.h"


#define BARRIER_SERIAL_THREAD -1


/* Local datatypes. */

typedef struct
{
  /*
   * number of threads that must call barrier_wait() before any of them
   * successfully return from the call.
   */
  unsigned thread_count;
  /* number of barrier_wait() calls since last barrier. */
  volatile unsigned wait_count;
  /*
   * barrier count. Only the least significant bit matters -- a single bit
   * counter would be sufficient.
   */
  volatile unsigned barrier_count;
} barrier_t;

struct threadinfo
{
  int        thread_num;
  barrier_t* b;
  pthread_t  tid;
  int*       array;
  int        iterations;
};


/* Local variables. */

static int s_silent;


/* Local functions. */

static void barrier_init(barrier_t* b, unsigned count)
{
  b->thread_count = count;
  b->wait_count = 0;
  b->barrier_count = 0;
  ANNOTATE_BARRIER_INIT(b, count, 0);
}

static void barrier_destroy(barrier_t* b)
{
  ANNOTATE_BARRIER_DESTROY(b);
  memset(b, 0, sizeof(*b));
}

static int barrier_wait(barrier_t* b)
{
  int res;
  unsigned barrier_count;

  res = 0;
  ANNOTATE_BARRIER_WAIT_BEFORE(b);
  barrier_count = b->barrier_count;
  if (__sync_add_and_fetch(&b->wait_count, 1) == b->thread_count)
  {
    __sync_sub_and_fetch(&b->wait_count, b->thread_count);
    __sync_add_and_fetch(&b->barrier_count, 1);
    res = BARRIER_SERIAL_THREAD;
  }
  else
  {
    while (b->barrier_count == barrier_count)
    {
#ifndef HAVE_PTHREAD_YIELD
      /* Darwin doesn't have an implementation of pthread_yield(). */
      usleep(100 * 1000);
#else
      pthread_yield();
#endif
    }
  }
  ANNOTATE_BARRIER_WAIT_AFTER(b);
  return res;
}

/*
 * Single thread, which touches p->iterations elements of array p->array.
 * Each modification of an element of p->array is a data race.
 */
static void* threadfunc(struct threadinfo* p)
{
  int i;
  int* const array = p->array;
  barrier_t* const b = p->b;
  if (! s_silent)
    printf("thread %d iteration 0\n", p->thread_num);
  barrier_wait(b);
  for (i = 0; i < p->iterations; i++)
  {
    if (! s_silent)
      printf("thread %d iteration %d; writing to %p\n",
             p->thread_num, i + 1, &array[i]);
    array[i] = i;
    barrier_wait(b);
  }
  return 0;
}

/* Actual test, consisting of nthread threads. */
static void barriers_and_races(const int nthread, const int iterations)
{
  const struct timespec delay = { 0, 100 * 1000 * 1000 };
  int i;
  struct threadinfo* t;
  barrier_t b;
  int* array;

  t = malloc(nthread * sizeof(struct threadinfo));
  array = malloc(iterations * sizeof(array[0]));

  if (! s_silent)
    printf("&array[0] = %p\n", array);

  barrier_init(&b, nthread);

  for (i = 0; i < nthread; i++)
  {
    t[i].thread_num = i + 1;
    t[i].b = &b;
    t[i].array = array;
    t[i].iterations = iterations;
    pthread_create(&t[i].tid, 0, (void*(*)(void*))threadfunc, &t[i]);
    nanosleep(&delay, 0);
  }

  for (i = 0; i < nthread; i++)
    pthread_join(t[i].tid, 0);

  barrier_destroy(&b);

  free(array);
  free(t);
}

int main(int argc, char** argv)
{
  int nthread;
  int iterations;

  nthread    = (argc > 1) ? atoi(argv[1]) : 2;
  iterations = (argc > 2) ? atoi(argv[2]) : 3;
  s_silent   = (argc > 3) ? atoi(argv[3]) : 0;

  barriers_and_races(nthread, iterations);

  fprintf(stderr, "Done.\n");

  return 0;
}
