/*
  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_basics.h"
#include "drd_clientobj.h"
#include "drd_error.h"
#include "drd_mutex.h"
#include "pub_tool_vki.h"
#include "pub_tool_errormgr.h"    /* VG_(maybe_record_error)()     */
#include "pub_tool_libcassert.h"  /* tl_assert()                   */
#include "pub_tool_libcbase.h"    /* VG_(strlen)                   */
#include "pub_tool_libcprint.h"   /* VG_(message)()                */
#include "pub_tool_libcproc.h"    /* VG_(read_millisecond_timer)() */
#include "pub_tool_machine.h"     /* VG_(get_IP)()                 */
#include "pub_tool_threadstate.h" /* VG_(get_running_tid)()        */


/* Local functions. */

static void mutex_cleanup(struct mutex_info* p);
static Bool mutex_is_locked(struct mutex_info* const p);
static void mutex_delete_thread(struct mutex_info* p, const DrdThreadId tid);


/* Local variables. */

static Bool s_trace_mutex;
static ULong s_mutex_lock_count;
static ULong s_mutex_segment_creation_count;
static UInt s_mutex_lock_threshold_ms;


/* Function definitions. */

void DRD_(mutex_set_trace)(const Bool trace_mutex)
{
   tl_assert((!! trace_mutex) == trace_mutex);
   s_trace_mutex = trace_mutex;
}

void DRD_(mutex_set_lock_threshold)(const UInt lock_threshold_ms)
{
   s_mutex_lock_threshold_ms = lock_threshold_ms;
}

static
void DRD_(mutex_initialize)(struct mutex_info* const p,
                            const Addr mutex, const MutexT mutex_type)
{
   tl_assert(mutex);
   tl_assert(p->a1 == mutex);

   p->cleanup             = (void(*)(DrdClientobj*))mutex_cleanup;
   p->delete_thread
      = (void(*)(DrdClientobj*, DrdThreadId))mutex_delete_thread;
   p->mutex_type          = mutex_type;
   p->recursion_count     = 0;
   p->ignore_ordering     = False;
   p->owner               = DRD_INVALID_THREADID;
   p->last_locked_segment = 0;
   p->acquiry_time_ms     = 0;
   p->acquired_at         = 0;
}

void DRD_(mutex_ignore_ordering)(const Addr mutex)
{
   struct mutex_info* p = DRD_(mutex_get)(mutex);

   if (s_trace_mutex)
      DRD_(trace_msg)("[%d] mutex_ignore_ordering %s 0x%lx",
                      DRD_(thread_get_running_tid)(),
                      p ? DRD_(mutex_type_name)(p->mutex_type) : "(?)",
                      mutex);

   if (p) {
      p->ignore_ordering = True;
   } else {
      DRD_(not_a_mutex)(mutex);
   }
}

/** Deallocate the memory that was allocated by mutex_initialize(). */
static void mutex_cleanup(struct mutex_info* p)
{
   tl_assert(p);

   if (s_trace_mutex)
      DRD_(trace_msg)("[%d] mutex_destroy   %s 0x%lx rc %d owner %d",
                      DRD_(thread_get_running_tid)(),
                      DRD_(mutex_get_typename)(p), p->a1,
                      p ? p->recursion_count : -1,
                      p ? p->owner : DRD_INVALID_THREADID);

   if (mutex_is_locked(p))
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              MutexErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Destroying locked mutex",
                              &MEI);
   }

   DRD_(sg_put)(p->last_locked_segment);
   p->last_locked_segment = 0;
}

/** Report that address 'mutex' is not the address of a mutex object. */
void DRD_(not_a_mutex)(const Addr mutex)
{
   MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                        mutex, -1, DRD_INVALID_THREADID };
   VG_(maybe_record_error)(VG_(get_running_tid)(),
                           MutexErr,
                           VG_(get_IP)(VG_(get_running_tid)()),
                           "Not a mutex",
                           &MEI);
}

/**
 * Report that address 'mutex' is not the address of a mutex object of the
 * expected type.
 */
static void wrong_mutex_type(const Addr mutex)
{
   MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                        mutex, -1, DRD_INVALID_THREADID };
   VG_(maybe_record_error)(VG_(get_running_tid)(),
                           MutexErr,
                           VG_(get_IP)(VG_(get_running_tid)()),
                           "Mutex type mismatch",
                           &MEI);
}

static
struct mutex_info*
DRD_(mutex_get_or_allocate)(const Addr mutex, const MutexT mutex_type)
{
   struct mutex_info* p;

   tl_assert(offsetof(DrdClientobj, mutex) == 0);
   p = &(DRD_(clientobj_get)(mutex, ClientMutex)->mutex);
   if (p)
   {
      if (mutex_type == mutex_type_unknown || p->mutex_type == mutex_type)
	 return p;
      else
      {
	 wrong_mutex_type(mutex);
	 return 0;
      }
   }

   if (DRD_(clientobj_present)(mutex, mutex + 1))
   {
      DRD_(not_a_mutex)(mutex);
      return 0;
   }

   p = &(DRD_(clientobj_add)(mutex, ClientMutex)->mutex);
   DRD_(mutex_initialize)(p, mutex, mutex_type);
   return p;
}

struct mutex_info* DRD_(mutex_get)(const Addr mutex)
{
   tl_assert(offsetof(DrdClientobj, mutex) == 0);
   return &(DRD_(clientobj_get)(mutex, ClientMutex)->mutex);
}

/** Called before pthread_mutex_init(). */
struct mutex_info*
DRD_(mutex_init)(const Addr mutex, const MutexT mutex_type)
{
   struct mutex_info* p;

   if (s_trace_mutex)
      DRD_(trace_msg)("[%d] mutex_init      %s 0x%lx",
                      DRD_(thread_get_running_tid)(),
                      DRD_(mutex_type_name)(mutex_type),
                      mutex);

   if (mutex_type == mutex_type_invalid_mutex)
   {
      DRD_(not_a_mutex)(mutex);
      return 0;
   }

   p = DRD_(mutex_get)(mutex);
   if (p)
   {
      const ThreadId vg_tid = VG_(get_running_tid)();
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid,
                              MutexErr,
                              VG_(get_IP)(vg_tid),
                              "Mutex reinitialization",
                              &MEI);
      p->mutex_type = mutex_type;
      return p;
   }
   p = DRD_(mutex_get_or_allocate)(mutex, mutex_type);

   return p;
}

/** Called after pthread_mutex_destroy(). */
void DRD_(mutex_post_destroy)(const Addr mutex)
{
   struct mutex_info* p;

   p = DRD_(mutex_get)(mutex);
   if (p == 0)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   DRD_(clientobj_remove)(mutex, ClientMutex);
}

/**
 * Called before pthread_mutex_lock() is invoked. If a data structure for the
 * client-side object was not yet created, do this now. Also check whether an
 * attempt is made to lock recursively a synchronization object that must not
 * be locked recursively.
 */
void DRD_(mutex_pre_lock)(const Addr mutex, MutexT mutex_type,
                          const Bool trylock)
{
   struct mutex_info* p;

   p = DRD_(mutex_get_or_allocate)(mutex, mutex_type);
   if (p && mutex_type == mutex_type_unknown)
      mutex_type = p->mutex_type;

   if (s_trace_mutex)
      DRD_(trace_msg)("[%d] %s %s 0x%lx rc %d owner %d",
                      DRD_(thread_get_running_tid)(),
                      trylock ? "pre_mutex_lock " : "mutex_trylock  ",
                      p ? DRD_(mutex_get_typename)(p) : "(?)",
                      mutex, p ? p->recursion_count : -1,
                      p ? p->owner : DRD_INVALID_THREADID);

   if (p == 0)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   tl_assert(p);

   if (mutex_type == mutex_type_invalid_mutex)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   if (! trylock
       && p->owner == DRD_(thread_get_running_tid)()
       && p->recursion_count >= 1
       && mutex_type != mutex_type_recursive_mutex)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              MutexErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Recursive locking not allowed",
                              &MEI);
   }
}

/**
 * Update mutex_info state when locking the pthread_mutex_t mutex.
 * Note: this function must be called after pthread_mutex_lock() has been
 * called, or a race condition is triggered !
 */
void DRD_(mutex_post_lock)(const Addr mutex, const Bool took_lock,
                           const Bool post_cond_wait)
{
   const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
   struct mutex_info* p;

   p = DRD_(mutex_get)(mutex);

   if (s_trace_mutex)
      DRD_(trace_msg)("[%d] %s %s 0x%lx rc %d owner %d%s",
                      drd_tid,
                      post_cond_wait ? "cond_post_wait " : "post_mutex_lock",
                      p ? DRD_(mutex_get_typename)(p) : "(?)",
                      mutex, p ? p->recursion_count : 0,
                      p ? p->owner : VG_INVALID_THREADID,
                      took_lock ? "" : " (locking failed)");

   if (! p || ! took_lock)
      return;

   if (p->recursion_count == 0) {
      if (!p->ignore_ordering) {
         if (p->owner != drd_tid && p->owner != DRD_INVALID_THREADID) {
            tl_assert(p->last_locked_segment);

            DRD_(thread_new_segment_and_combine_vc)(drd_tid,
                                                    p->last_locked_segment);
         } else {
            DRD_(thread_new_segment)(drd_tid);
         }

         s_mutex_segment_creation_count++;
      }

      p->owner           = drd_tid;
      p->acquiry_time_ms = VG_(read_millisecond_timer)();
      p->acquired_at     = VG_(record_ExeContext)(VG_(get_running_tid)(), 0);
      s_mutex_lock_count++;
   } else if (p->owner != drd_tid) {
      const ThreadId vg_tid = VG_(get_running_tid)();
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid,
                              MutexErr,
                              VG_(get_IP)(vg_tid),
                              "The impossible happened: mutex is locked"
                              " simultaneously by two threads",
                              &MEI);
      p->owner = drd_tid;
   }
   p->recursion_count++;
}

/**
 * Update mutex_info state when unlocking the pthread_mutex_t mutex.
 *
 * @param[in] mutex      Address of the client mutex.
 * @param[in] mutex_type Mutex type.
 *
 * @return New value of the mutex recursion count.
 *
 * @note This function must be called before pthread_mutex_unlock() is called,
 *       or a race condition is triggered !
 */
void DRD_(mutex_unlock)(const Addr mutex, MutexT mutex_type)
{
   const DrdThreadId drd_tid = DRD_(thread_get_running_tid)();
   const ThreadId vg_tid = VG_(get_running_tid)();
   struct mutex_info* p;

   p = DRD_(mutex_get)(mutex);
   if (p && mutex_type == mutex_type_unknown)
      mutex_type = p->mutex_type;

   if (s_trace_mutex) {
      DRD_(trace_msg)("[%d] mutex_unlock    %s 0x%lx rc %d",
                      drd_tid, p ? DRD_(mutex_get_typename)(p) : "(?)",
                      mutex, p ? p->recursion_count : 0);
   }

   if (p == 0 || mutex_type == mutex_type_invalid_mutex)
   {
      DRD_(not_a_mutex)(mutex);
      return;
   }

   if (p->owner == DRD_INVALID_THREADID)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid,
                              MutexErr,
                              VG_(get_IP)(vg_tid),
                              "Mutex not locked",
                              &MEI);
      return;
   }

   tl_assert(p);
   if (p->mutex_type != mutex_type) {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid, MutexErr, VG_(get_IP)(vg_tid),
                              "Mutex type changed", &MEI);
   }
   tl_assert(p->mutex_type == mutex_type);
   tl_assert(p->owner != DRD_INVALID_THREADID);

   if (p->owner != drd_tid || p->recursion_count <= 0)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(vg_tid,
                              MutexErr,
                              VG_(get_IP)(vg_tid),
                              "Mutex not locked by calling thread",
                              &MEI);
      return;
   }
   tl_assert(p->recursion_count > 0);
   p->recursion_count--;
   tl_assert(p->recursion_count >= 0);

   if (p->recursion_count == 0)
   {
      if (s_mutex_lock_threshold_ms > 0)
      {
         Long held = VG_(read_millisecond_timer)() - p->acquiry_time_ms;
         if (held > s_mutex_lock_threshold_ms)
         {
            HoldtimeErrInfo HEI
               = { DRD_(thread_get_running_tid)(),
                   mutex, p->acquired_at, held, s_mutex_lock_threshold_ms };
            VG_(maybe_record_error)(vg_tid,
                                    HoldtimeErr,
                                    VG_(get_IP)(vg_tid),
                                    "mutex",
                                    &HEI);
         }
      }

      /* This pthread_mutex_unlock() call really unlocks the mutex. Save the */
      /* current vector clock of the thread such that it is available when  */
      /* this mutex is locked again.                                        */

      DRD_(thread_get_latest_segment)(&p->last_locked_segment, drd_tid);
      if (!p->ignore_ordering)
         DRD_(thread_new_segment)(drd_tid);
      p->acquired_at = 0;
      s_mutex_segment_creation_count++;
   }
}

void DRD_(spinlock_init_or_unlock)(const Addr spinlock)
{
   struct mutex_info* mutex_p = DRD_(mutex_get)(spinlock);
   if (mutex_p)
   {
      DRD_(mutex_unlock)(spinlock, mutex_type_spinlock);
   }
   else
   {
      DRD_(mutex_init)(spinlock, mutex_type_spinlock);
   }
}

const HChar* DRD_(mutex_get_typename)(struct mutex_info* const p)
{
   tl_assert(p);

   return DRD_(mutex_type_name)(p->mutex_type);
}

const HChar* DRD_(mutex_type_name)(const MutexT mt)
{
   switch (mt)
   {
   case mutex_type_unknown:
      return "mutex";
   case mutex_type_invalid_mutex:
      return "invalid mutex";
   case mutex_type_recursive_mutex:
      return "recursive mutex";
   case mutex_type_errorcheck_mutex:
      return "error checking mutex";
   case mutex_type_default_mutex:
      return "mutex";
   case mutex_type_spinlock:
      return "spinlock";
   case mutex_type_cxa_guard:
      return "cxa_guard";
   }
   tl_assert(0);
   return "?";
}

/** Return true if the specified mutex is locked by any thread. */
static Bool mutex_is_locked(struct mutex_info* const p)
{
   tl_assert(p);
   return (p->recursion_count > 0);
}

Bool DRD_(mutex_is_locked_by)(const Addr mutex, const DrdThreadId tid)
{
   struct mutex_info* const p = DRD_(mutex_get)(mutex);
   if (p)
   {
      return (p->recursion_count > 0 && p->owner == tid);
   }
   return False;
}

int DRD_(mutex_get_recursion_count)(const Addr mutex)
{
   struct mutex_info* const p = DRD_(mutex_get)(mutex);
   tl_assert(p);
   return p->recursion_count;
}

/**
 * Call this function when thread tid stops to exist, such that the
 * "last owner" field can be cleared if it still refers to that thread.
 */
static void mutex_delete_thread(struct mutex_info* p, const DrdThreadId tid)
{
   tl_assert(p);

   if (p->owner == tid && p->recursion_count > 0)
   {
      MutexErrInfo MEI = { DRD_(thread_get_running_tid)(),
                           p->a1, p->recursion_count, p->owner };
      VG_(maybe_record_error)(VG_(get_running_tid)(),
                              MutexErr,
                              VG_(get_IP)(VG_(get_running_tid)()),
                              "Mutex still locked at thread exit",
                              &MEI);
      p->owner = VG_INVALID_THREADID;
   }
}

ULong DRD_(get_mutex_lock_count)(void)
{
   return s_mutex_lock_count;
}

ULong DRD_(get_mutex_segment_creation_count)(void)
{
   return s_mutex_segment_creation_count;
}
