/*
  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\n",
                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\n",
                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;
}
