/*
  This file is part of drd, a thread error detector.

  Copyright (C) 2006-2013 Bart Van Assche <bvanassche@acm.org>.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of the
  License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307, USA.

  The GNU General Public License is contained in the file COPYING.
*/


#include "drd_clientobj.h"
#include "drd_error.h"
#include "drd_semaphore.h"
#include "drd_suppression.h"
#include "pub_tool_errormgr.h"    // VG_(maybe_record_error)()
#include "pub_tool_libcassert.h"  // tl_assert()
#include "pub_tool_libcprint.h"   // VG_(printf)()
#include "pub_tool_machine.h"     // VG_(get_IP)()
#include "pub_tool_mallocfree.h"  // VG_(malloc), VG_(free)
#include "pub_tool_threadstate.h" // VG_(get_running_tid)()


/* Local functions. */

static void semaphore_cleanup(struct semaphore_info* p);


/* Local variables. */

static Bool s_trace_semaphore;
static ULong s_semaphore_segment_creation_count;


/* Function definitions. */

/** Push a segment at the end of the queue 'p->last_sem_post_seg'. */
static void drd_segment_push(struct semaphore_info* p, Segment* sg)
{
   Word n;

   tl_assert(sg);
   n = VG_(addToXA)(p->last_sem_post_seg, &sg);
#if 0
   VG_(message)(Vg_DebugMsg, "0x%lx push: added at position %ld/%ld",
                p->a1, n, VG_(sizeXA)(p->last_sem_post_seg));
#endif
   tl_assert(*(Segment**)VG_(indexXA)(p->last_sem_post_seg, n) == sg);
}

/** Pop a segment from the beginning of the queue 'p->last_sem_post_seg'. */
static Segment* drd_segment_pop(struct semaphore_info* p)
{
   Word sz;
   Segment* sg;

   sz = VG_(sizeXA)(p->last_sem_post_seg);
#if 0
   VG_(message)(Vg_DebugMsg, "0x%lx pop:  removed from position %ld/%ld",
                p->a1, sz - 1, sz);
#endif
   sg = 0;
   if (sz > 0)
   {
      sg = *(Segment**)VG_(indexXA)(p->last_sem_post_seg, sz - 1);
      tl_assert(sg);
      VG_(dropTailXA)(p->last_sem_post_seg, 1);
   }
   return sg;
}

/** Enable or disable tracing of semaphore actions. */
void DRD_(semaphore_set_trace)(const Bool trace_semaphore)
{
   s_trace_semaphore = trace_semaphore;
}

/**
 * Initialize the memory 'p' points at as a semaphore_info structure for the
 * client semaphore at client addres 'semaphore'.
 */
static
void drd_semaphore_initialize(struct semaphore_info* const p,
                              const Addr semaphore)
{
   tl_assert(semaphore != 0);
   tl_assert(p->a1 == semaphore);
   tl_assert(p->type == ClientSemaphore);

   p->cleanup           = (void(*)(DrdClientobj*))semaphore_cleanup;
   p->delete_thread     = 0;
   p->waits_to_skip     = 0;
   p->value             = 0;
   p->waiters           = 0;
   p->last_sem_post_tid = DRD_INVALID_THREADID;
   p->last_sem_post_seg = VG_(newXA)(VG_(malloc), "drd.sg-stack",
                                     VG_(free), sizeof(Segment*));
}

/**
 * Free the memory that was allocated by semaphore_initialize(). Called by
 * DRD_(clientobj_remove)().
 */
static void semaphore_cleanup(struct semaphore_info* p)
{
   Segment* sg;

   if (p->waiters > 0)
   {
      SemaphoreErrInfo sei = { DRD_(thread_get_running_tid)(), p->a1 };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              SemaphoreErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Destruction of semaphore that is being waited"
                              " upon",
                              &sei);
   }
   while ((sg = drd_segment_pop(p)))
      DRD_(sg_put)(sg);
   VG_(deleteXA)(p->last_sem_post_seg);
}

/**
 * Return a pointer to the structure with information about the specified
 * client semaphore. Allocate a new structure if such a structure did not
 * yet exist.
 */
static
struct semaphore_info*
drd_semaphore_get_or_allocate(const Addr semaphore)
{
   struct semaphore_info *p;

   tl_assert(offsetof(DrdClientobj, semaphore) == 0);
   p = &(DRD_(clientobj_get)(semaphore, ClientSemaphore)->semaphore);
   if (p == 0)
   {
      tl_assert(offsetof(DrdClientobj, semaphore) == 0);
      p = &(DRD_(clientobj_add)(semaphore, ClientSemaphore)->semaphore);
      drd_semaphore_initialize(p, semaphore);
   }
   return p;
}

/**
 * Return a pointer to the structure with information about the specified
 * client semaphore, or null if no such structure was found.
 */
static struct semaphore_info* semaphore_get(const Addr semaphore)
{
   tl_assert(offsetof(DrdClientobj, semaphore) == 0);
   return &(DRD_(clientobj_get)(semaphore, ClientSemaphore)->semaphore);
}

/** Called before sem_init(). */
struct semaphore_info* DRD_(semaphore_init)(const Addr semaphore,
                                            const Word pshared,
                                            const UInt value)
{
   struct semaphore_info* p;
   Segment* sg;

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_init      0x%lx value %u",
                      DRD_(thread_get_running_tid)(), semaphore, value);

   p = semaphore_get(semaphore);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      SemaphoreErrInfo SEI = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(vg_tid,
                              SemaphoreErr,
                              VG_(get_IP)(vg_tid),
                              "Semaphore reinitialization",
                              &SEI);
      // Remove all segments from the segment stack.
      while ((sg = drd_segment_pop(p)))
      {
         DRD_(sg_put)(sg);
      }
   }
   else
   {
#if defined(VGO_darwin)
      const ThreadId vg_tid = VG_(get_running_tid)();
      GenericErrInfo GEI = { DRD_(thread_get_running_tid)(), 0 };
      VG_(maybe_record_error)(vg_tid,
			      GenericErr,
			      VG_(get_IP)(vg_tid),
			      "sem_init() is not yet supported on Darwin",
			      &GEI);
      return NULL;
#else
      p = drd_semaphore_get_or_allocate(semaphore);
#endif
   }
   tl_assert(p);
   p->waits_to_skip = value;
   p->value         = value;
   return p;
}

/** Called after sem_destroy(). */
void DRD_(semaphore_destroy)(const Addr semaphore)
{
   struct semaphore_info* p;

   p = semaphore_get(semaphore);

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_destroy   0x%lx value %u",
                      DRD_(thread_get_running_tid)(), semaphore,
                      p ? p->value : 0);

   if (p == 0)
   {
      GenericErrInfo GEI = {
	 .tid  = DRD_(thread_get_running_tid)(),
	 .addr = semaphore,
      };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              GenericErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Not a semaphore",
                              &GEI);
      return;
   }

   DRD_(clientobj_remove)(semaphore, ClientSemaphore);
}

/** Called after sem_open(). */
struct semaphore_info* DRD_(semaphore_open)(const Addr semaphore,
                                            const HChar* name, const Word oflag,
                                            const Word mode, const UInt value)
{
   struct semaphore_info* p;
   Segment* sg;

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_open      0x%lx name %s"
                      " oflag %#lx mode %#lo value %u",
                      DRD_(thread_get_running_tid)(),
                      semaphore, name, oflag, mode, value);

   /* Return if the sem_open() call failed. */
   if (! semaphore)
      return NULL;

   p = semaphore_get(semaphore);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      SemaphoreErrInfo SEI = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(vg_tid,
                              SemaphoreErr,
                              VG_(get_IP)(vg_tid),
                              "Semaphore reinitialization",
                              &SEI);
      // Remove all segments from the segment stack.
      while ((sg = drd_segment_pop(p)))
      {
         DRD_(sg_put)(sg);
      }
   }
   else
   {
      p = drd_semaphore_get_or_allocate(semaphore);
   }
   tl_assert(p);
   p->waits_to_skip = value;
   p->value         = value;
   return p;
}

/** Called before sem_close(). */
void DRD_(semaphore_close)(const Addr semaphore)
{
   struct semaphore_info* p;

   p = semaphore_get(semaphore);

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_close     0x%lx value %u",
                      DRD_(thread_get_running_tid)(), semaphore,
                      p ? p->value : 0);

   if (p == 0)
   {
      GenericErrInfo GEI = {
	 .tid  = DRD_(thread_get_running_tid)(),
	 .addr = semaphore,
      };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              GenericErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Not a semaphore",
                              &GEI);
      return;
   }

   DRD_(clientobj_remove)(semaphore, ClientSemaphore);
}

/** Called before sem_wait(). */
void DRD_(semaphore_pre_wait)(const Addr semaphore)
{
   struct semaphore_info* p;

   tl_assert(semaphore < semaphore + 1);
   p = drd_semaphore_get_or_allocate(semaphore);
   tl_assert(p);
   p->waiters++;

   if ((Word)(p->waiters) <= 0)
   {
      SemaphoreErrInfo sei = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              SemaphoreErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Invalid semaphore",
                              &sei);
   }
}

/**
 * Called after sem_wait() finished.
 * @note Some C libraries do not set the 'waited' value correctly.
 */
void DRD_(semaphore_post_wait)(const DrdThreadId tid, const Addr semaphore,
                               const Bool waited)
{
   struct semaphore_info* p;
   Segment* sg;

   tl_assert(waited == 0 || waited == 1);
   p = semaphore_get(semaphore);
   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_wait      0x%lx value %u -> %u%s",
                      DRD_(thread_get_running_tid)(), semaphore,
                      p ? p->value : 0, p ? p->value - waited : 0,
		      waited ? "" : " (did not wait)");

   if (p) {
      p->waiters--;
      p->value -= waited;
   }

   /*
    * Note: if another thread destroyed and reinitialized a semaphore while
    * the current thread was waiting in sem_wait, p->waiters may have been
    * set to zero by drd_semaphore_initialize() after
    * DRD_(semaphore_pre_wait)() has finished before
    * DRD_(semaphore_post_wait)() has been called.
    */
   if (p == NULL || (Int)(p->value) < 0 || (Word)(p->waiters) < 0)
   {
      SemaphoreErrInfo sei = { DRD_(thread_get_running_tid)(), semaphore };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              SemaphoreErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Invalid semaphore",
                              &sei);
      return;
   }

   if (!waited)
      return;

   if (p->waits_to_skip > 0)
      p->waits_to_skip--;
   else
   {
      sg = drd_segment_pop(p);
      tl_assert(sg);
      if (p->last_sem_post_tid != tid
          && p->last_sem_post_tid != DRD_INVALID_THREADID)
      {
         DRD_(thread_new_segment_and_combine_vc)(tid, sg);
      }
      else
         DRD_(thread_new_segment)(tid);
      s_semaphore_segment_creation_count++;
      DRD_(sg_put)(sg);
   }
}

/** Called before sem_post(). */
void DRD_(semaphore_pre_post)(const DrdThreadId tid, const Addr semaphore)
{
   struct semaphore_info* p;
   Segment* sg;

   p = drd_semaphore_get_or_allocate(semaphore);
   p->value++;

   if (s_trace_semaphore)
      DRD_(trace_msg)("[%d] sem_post      0x%lx value %u -> %u",
                      DRD_(thread_get_running_tid)(),
                      semaphore, p->value - 1, p->value);

   p->last_sem_post_tid = tid;
   sg = 0;
   DRD_(thread_get_latest_segment)(&sg, tid);
   tl_assert(sg);
   drd_segment_push(p, sg);
   DRD_(thread_new_segment)(tid);
   s_semaphore_segment_creation_count++;
}

/** Called after sem_post() finished. */
void DRD_(semaphore_post_post)(const DrdThreadId tid, const Addr semaphore,
                               const Bool succeeded)
{
   /*
    * Note: it is hard to implement the sem_post() wrapper correctly in
    * case sem_post() returns an error code. This is because handling this
    * case correctly requires restoring the vector clock associated with
    * the semaphore to its original value here. In order to do that without
    * introducing a race condition, extra locking has to be added around
    * each semaphore call. Such extra locking would have to be added in
    * drd_pthread_intercepts.c. However, it is hard to implement
    * synchronization in drd_pthread_intercepts.c in a portable way without
    * calling already redirected functions.
    */
}

ULong DRD_(get_semaphore_segment_creation_count)(void)
{
   return s_semaphore_segment_creation_count;
}
