
/* This program is a marginally modified copy of
   drd/tests/annotate_rwlock.c,

   which was originally written by Bart van Assche.

   Unfortunately due to the need to #include helgrind.h instead of
   drd.h, it can't be an exact copy.
*/

/**
 * @file  annotate_rwlock.c
 *
 * @brief Multithreaded test program that triggers various access patterns
 *        without triggering any race conditions using a reader-writer lock
 *        implemented via busy-waiting. Annotations are used to tell DRD
 *        which higher-level rwlock operations are being performed.
 */


#define _GNU_SOURCE 1

#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>        /* usleep() */
#include "../../config.h"
#include "../../helgrind/helgrind.h"


#ifndef HAVE_BUILTIN_ATOMIC
#error Sorry, but this test program can only be compiled by a compiler that\
has built-in functions for atomic memory access.
#endif


typedef struct {
  volatile int locked;
  int          writer_count;
  int          reader_count;
} rwlock_t;


static rwlock_t s_rwlock;
static int s_counter;


static void rwlock_init(rwlock_t* p)
{
  //  DRD_IGNORE_VAR(*p);
  p->locked       = 0;
  p->writer_count = 0;
  p->reader_count = 0;
  ANNOTATE_RWLOCK_CREATE(p);
}

static void rwlock_destroy(rwlock_t* p)
{
  ANNOTATE_RWLOCK_DESTROY(p);
  assert(p->locked       == 0);
  assert(p->writer_count == 0);
  assert(p->reader_count == 0);
}

static void rwlock_rdlock(rwlock_t* p)
{
  while (1)
  {
    while (__sync_val_compare_and_swap(&p->locked, 0, 1) == 1)
      ;
    if (p->writer_count == 0)
      break;
#ifdef __APPLE__
    /* Darwin doesn't have an implementation of pthread_yield(). */
    usleep(100 * 1000);
#else
    sched_yield();
#endif
    (void) __sync_fetch_and_sub(&p->locked, 1);
  }
  p->reader_count++;
  assert(p->reader_count >= 0);
  assert(p->writer_count >= 0);
  assert(p->reader_count == 0 || p->writer_count == 0);
  (void) __sync_fetch_and_sub(&p->locked, 1);
  //ANNOTATE_READERLOCK_ACQUIRED(p);
  ANNOTATE_RWLOCK_ACQUIRED(p, 0);
}

static void rwlock_wrlock(rwlock_t* p)
{
  while (1)
  {
    while (__sync_val_compare_and_swap(&p->locked, 0, 1) == 1)
      ;
    if (p->reader_count == 0)
      break;
#ifdef __APPLE__
    /* Darwin doesn't have an implementation of pthread_yield(). */
    usleep(100 * 1000);
#else
    sched_yield();
#endif
    (void) __sync_fetch_and_sub(&p->locked, 1);
  }
  p->writer_count++;
  assert(p->reader_count >= 0);
  assert(p->writer_count >= 0);
  assert(p->reader_count == 0 || p->writer_count == 0);
  (void) __sync_fetch_and_sub(&p->locked, 1);
  //  ANNOTATE_WRITERLOCK_ACQUIRED(p);
  ANNOTATE_RWLOCK_ACQUIRED(p, 1);
}

static void rwlock_unlock(rwlock_t* p)
{
  while (__sync_val_compare_and_swap(&p->locked, 0, 1) == 1)
    ;
  if (p->reader_count > 0)
  {
    p->reader_count--;
    //ANNOTATE_READERLOCK_RELEASED(p);
    ANNOTATE_RWLOCK_RELEASED(p, 0);
  }
  else
  {
    p->writer_count--;
    //ANNOTATE_WRITERLOCK_RELEASED(p);
    ANNOTATE_RWLOCK_RELEASED(p, 1);
  }
  assert(p->reader_count >= 0);
  assert(p->writer_count >= 0);
  assert(p->reader_count == 0 || p->writer_count == 0);
  (void) __sync_fetch_and_sub(&p->locked, 1);
}

static void* thread_func(void* arg)
{
  int i;
  int sum = 0;

  for (i = 0; i < 1000; i++)
  {
    rwlock_rdlock(&s_rwlock);
    sum += s_counter;
    rwlock_unlock(&s_rwlock);
    rwlock_wrlock(&s_rwlock);
    s_counter++;
    rwlock_unlock(&s_rwlock);
  }

  return 0;
}

int main(int argc, char** argv)
{
  const int thread_count = 10;
  pthread_t tid[thread_count];
  int i;

  rwlock_init(&s_rwlock);
  for (i = 0; i < thread_count; i++)
  {
    pthread_create(&tid[i], 0, thread_func, 0);
  }

  for (i = 0; i < thread_count; i++)
  {
    pthread_join(tid[i], 0);
  }
  rwlock_destroy(&s_rwlock);

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

  return 0;
}
