/*
  This file is part of drd, a data race detector.

  Copyright (C) 2006-2007 Bart Van Assche
  bart.vanassche@gmail.com

  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_error.h"
#include "drd_segment.h"
#include "drd_thread.h"
#include "pub_tool_basics.h"      // Addr, SizeT
#include "pub_tool_errormgr.h"    // VG_(unique_error)()
#include "pub_tool_libcassert.h"  // tl_assert()
#include "pub_tool_libcbase.h"    // VG_(strlen)()
#include "pub_tool_libcprint.h"   // VG_(printf)()
#include "pub_tool_mallocfree.h"  // VG_(malloc)(), VG_(free)()
#include "pub_tool_threadstate.h" // VG_INVALID_THREADID


// Local variables.

static ULong s_segments_created_count;
static ULong s_segments_alive_count;
static ULong s_max_segments_alive_count;
static Bool drd_trace_segment = False;


// Function definitions.

/**
 * Note: creator and created may be equal.
 */
void sg_init(Segment* const sg,
             DrdThreadId const creator,
             DrdThreadId const created)
{
  Segment* creator_sg;
  ThreadId vg_created = DrdThreadIdToVgThreadId(created);

  tl_assert(sg);
  tl_assert(creator == DRD_INVALID_THREADID || IsValidDrdThreadId(creator));

  creator_sg = (creator != DRD_INVALID_THREADID
                ? thread_get_segment(creator) : 0);
  
  sg->next = 0;
  sg->prev = 0;

  if (vg_created != VG_INVALID_THREADID && VG_(get_SP)(vg_created) != 0)
    sg->stacktrace = VG_(record_ExeContext)(vg_created, 0);
  else
    sg->stacktrace = 0;

  if (creator_sg)
    vc_copy(&sg->vc, &creator_sg->vc);
  else
    vc_init(&sg->vc, 0, 0);
  vc_increment(&sg->vc, created);
  sg->bm = bm_new();

  if (drd_trace_segment)
  {
    char msg[256];
    VG_(snprintf)(msg, sizeof(msg),
                  "New segment for thread %d with vc ",
                  creator);
    vc_snprint(msg + VG_(strlen)(msg), sizeof(msg) - VG_(strlen)(msg),
               &sg->vc);
    VG_(message)(Vg_DebugMsg, "%s", msg);
  }
}

void sg_cleanup(Segment* const sg)
{
  tl_assert(sg);
  vc_cleanup(&sg->vc);
  bm_delete(sg->bm);
  sg->bm = 0;
}

Segment* sg_new(ThreadId const creator, ThreadId const created)
{
  Segment* sg;

  s_segments_created_count++;
  s_segments_alive_count++;
  if (s_max_segments_alive_count < s_segments_alive_count)
    s_max_segments_alive_count = s_segments_alive_count;

  sg = VG_(malloc)(sizeof(*sg));
  tl_assert(sg);
  sg_init(sg, creator, created);
  return sg;
}

void sg_delete(Segment* const sg)
{
  s_segments_alive_count--;

  tl_assert(sg);
  sg_cleanup(sg);
  VG_(free)(sg);
}

void sg_print(const Segment* const sg)
{
  tl_assert(sg);
  VG_(printf)("vc: ");
  vc_print(&sg->vc);
  VG_(printf)("\n");
  bm_print(sg->bm);
}

Bool sg_get_trace(void)
{
  return drd_trace_segment;
}

void sg_set_trace(Bool const trace_segment)
{
  tl_assert(trace_segment == False || trace_segment == True);
  drd_trace_segment = trace_segment;
}

ULong sg_get_segments_created_count(void)
{
  return s_segments_created_count;
}

ULong sg_get_max_segments_alive_count(void)
{
  return s_max_segments_alive_count;
}
