
/*--------------------------------------------------------------------*/
/*--- Support functions for xtree memory reports. m_xtmemory.c     ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2016-2017 Philippe Waroquiers

   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 "pub_core_libcassert.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_xarray.h"
#include "pub_core_xtree.h"
#include "pub_core_xtmemory.h"    /* self */

static void VG_(XT_Allocs_init)(void* xt_allocs)
{
   VG_(memset) (xt_allocs, 0, sizeof(XT_Allocs));
}
static void VG_(XT_Allocs_add) (void* to, const void* xt_allocs)
{
   XT_Allocs* xto = to;
   const XT_Allocs* xta = xt_allocs;

   xto->nbytes  += xta->nbytes;
   xto->nblocks += xta->nblocks;
}
static void VG_(XT_Allocs_sub) (void* from, const void* xt_allocs)
{
   XT_Allocs* xfrom = from;
   const XT_Allocs* xta = xt_allocs;

   xfrom->nbytes  -= xta->nbytes;
   xfrom->nblocks -= xta->nblocks;
}
static const HChar* VG_(XT_Allocs_img) (const void* xt_allocs)
{
   static HChar buf[100];

   const XT_Allocs* xta = xt_allocs;
   
   if (xta->nbytes > 0 || xta->nblocks > 0) {
      VG_(sprintf) (buf, "%lu %lu",
                    xta->nbytes, xta->nblocks);
      return buf;
   } else {
      return NULL;
   }
}
const HChar* XT_Allocs_events = "curB : currently allocated Bytes"   ","
                                "curBk : currently allocated Blocks";

/* Type and functions for full xtree memory profiling. */
static XTree* full_xt;
typedef
   struct _XT_Full {
      // Current nr of bytes/blocks allocated by this ec
      SizeT cur_alloc_nbytes;
      SizeT cur_alloc_nblocks;

      // Total/cumulative nr of bytes/blocks allocated by this ec
      ULong tot_alloc_nbytes;
      ULong tot_alloc_nblocks;

      // Total/cumulative nr of bytes/blocks freed by this ec
      ULong tot_freed_nbytes;
      ULong tot_freed_nblocks;
   } XT_Full;
/* Note: normally, an ec should never be used as both an alloc_ec and
   a free_ec. This implies that we should never have a XT_Full that has
   at the same time some alloc and some freed components > 0.
   We however still will support this possibility, just in case very
   strange ec are produced and/or given by the tool. */

static void VG_(XT_Full_init)(void* xtfull)
{
   VG_(memset) (xtfull, 0, sizeof(XT_Full));
}
static void VG_(XT_Full_add) (void* to, const void* xtfull)
{
   XT_Full* xto = to;
   const XT_Full* xtf = xtfull;

   xto->cur_alloc_nbytes  += xtf->cur_alloc_nbytes;
   xto->cur_alloc_nblocks += xtf->cur_alloc_nblocks;
   xto->tot_alloc_nbytes  += xtf->tot_alloc_nbytes;
   xto->tot_alloc_nblocks += xtf->tot_alloc_nblocks;
   xto->tot_freed_nbytes  += xtf->tot_freed_nbytes;
   xto->tot_freed_nblocks += xtf->tot_freed_nblocks;
}
static void VG_(XT_Full_sub) (void* from, const void* xtfull)
{
   XT_Full* xfrom = from;
   const XT_Full* xtf = xtfull;

   xfrom->cur_alloc_nbytes  -= xtf->cur_alloc_nbytes;
   xfrom->cur_alloc_nblocks -= xtf->cur_alloc_nblocks;
   xfrom->tot_alloc_nbytes  -= xtf->tot_alloc_nbytes;
   xfrom->tot_alloc_nblocks -= xtf->tot_alloc_nblocks;
   xfrom->tot_freed_nbytes  -= xtf->tot_freed_nbytes;
   xfrom->tot_freed_nblocks -= xtf->tot_freed_nblocks;
}
static const HChar* VG_(XT_Full_img) (const void* xtfull)
{
   static HChar buf[300];

   const XT_Full* xtf = xtfull;
   
   if (   xtf->cur_alloc_nbytes  > 0
       || xtf->cur_alloc_nblocks > 0
       || xtf->tot_alloc_nbytes  > 0
       || xtf->tot_alloc_nblocks > 0
       || xtf->tot_freed_nbytes  > 0
       || xtf->tot_freed_nblocks > 0) {
      VG_(sprintf) (buf, 
                    "%lu %lu "
                    "%llu %llu "
                    "%llu %llu",
                    xtf->cur_alloc_nbytes, xtf->cur_alloc_nblocks,
                    xtf->tot_alloc_nbytes, xtf->tot_alloc_nblocks,
                    xtf->tot_freed_nbytes, xtf->tot_freed_nblocks);
      return buf;
   } else {
      return NULL;
   }
}
static const HChar* XT_Full_events = 
   "curB : currently allocated Bytes"   ","
   "curBk : currently allocated Blocks" ","
   "totB : total allocated Bytes"       ","
   "totBk : total allocated Blocks"     ","
   "totFdB : total Freed Bytes"         ","
   "totFdBk : total Freed Blocks";
void VG_(XTMemory_Full_init)(XT_filter_IPs_t filter_IPs_fn)
{
   full_xt = VG_(XT_create) (VG_(malloc),
                             "m_xtree.full_xt",
                             VG_(free),
                             sizeof(XT_Full),
                             VG_(XT_Full_init),
                             VG_(XT_Full_add),
                             VG_(XT_Full_sub),
                             filter_IPs_fn);
}
void VG_(XTMemory_Full_alloc)(SizeT szB,
                              ExeContext* ec_alloc)
{
   XT_Full xtf = {szB, 1, szB, 1, 0, 0};
   VG_(XT_add_to_ec)(full_xt, ec_alloc, &xtf);
}
void VG_(XTMemory_Full_free)(SizeT szB,
                             ExeContext* ec_alloc,
                             ExeContext* ec_free)
{
   // substract from ec_alloc the freed memory.
   XT_Full xtf_sub = {szB, 1, 0, 0, 0, 0};
   VG_(XT_sub_from_ec)(full_xt, ec_alloc, &xtf_sub);

   // add to ec_free the freed memory
   XT_Full xtf_add = {0, 0, 0, 0, szB, 1};
   VG_(XT_add_to_ec)(full_xt, ec_free, &xtf_add);
}

void VG_(XTMemory_Full_resize_in_place)(SizeT oldSzB, SizeT newSzB,
                                        ExeContext* ec_alloc)
{
   if (oldSzB > newSzB) {
      XT_Full xtf = {oldSzB - newSzB, 0, oldSzB - newSzB, 0, 0, 0};
      VG_(XT_sub_from_ec)(full_xt, ec_alloc, &xtf);
   } else {
      XT_Full xtf = {newSzB - oldSzB, 0, newSzB - oldSzB, 0, 0, 0};
      VG_(XT_add_to_ec)(full_xt, ec_alloc, &xtf);
   }
}

// Indicates which event nr the report_value function must return.
static UInt event_report_value_id;
static ULong XT_Full_report_value(const void* xtfull)
{
   const XT_Full* xtf = xtfull;   
   switch (event_report_value_id) {
      case 0: return (ULong) xtf->cur_alloc_nbytes;
      case 1: return (ULong) xtf->cur_alloc_nblocks;
      case 2: return xtf->tot_alloc_nbytes;
      case 3: return xtf->tot_alloc_nblocks;
      case 4: return xtf->tot_freed_nbytes;
      case 5: return xtf->tot_freed_nblocks;
      default: vg_assert(0);
   }
}
static ULong XT_Allocs_report_value(const void* xt_allocs)
{
   const XT_Allocs* xta = xt_allocs;   
   switch (event_report_value_id) {
      case 0: return (ULong) xta->nbytes;
      case 1: return (ULong) xta->nblocks;
      default: vg_assert(0);
   }
}

static void produce_report(XTree* xt, const HChar* filename,
                           const HChar* events,
                           const HChar* (*img_value) (const void* value),
                           ULong (*report_value)(const void* value))
{
   /* The user can control the kind of report using filename extension. */
   if (VG_(strstr)(filename, ".ms")) {
      /* If needed, some harcoded value below could become parameters. */
      MsFile* fp;
      Massif_Header header = (Massif_Header) {
         .snapshot_n    = 0,
         .time          = VG_(read_millisecond_timer)(),
         .sz_B          = 0ul,
         .extra_B       = 0ul,
         .stacks_B      = 0ul,
         .detailed      = True,
         .peak          = False,
         .top_node_desc = NULL,
         .sig_threshold = 0.00000000000001
         // Currently, we take a very small float value to not output
         // the 0 values, but still output all the rest.
      };

      // Variables to parse events
      HChar strtok_events[VG_(strlen)(events)+1];
      HChar* e;
      HChar* ssaveptr;

      fp = VG_(XT_massif_open)(filename,
                               "xtree.produce_report",
                               NULL,
                               "ms");

      event_report_value_id = 0;
      VG_(strcpy)(strtok_events, events);
      for (e = VG_(strtok_r) (strtok_events, ",", &ssaveptr); 
           e != NULL; 
           e = VG_(strtok_r) (NULL, ",", &ssaveptr)) {
         header.top_node_desc = e;
         VG_(XT_massif_print)(fp, xt, &header, report_value);
         header.snapshot_n++;
         event_report_value_id++;
      }

      VG_(XT_massif_close)(fp);
   } else
      VG_(XT_callgrind_print)(xt,
                             filename,
                             events,
                             img_value);
}

void VG_(XTMemory_report) 
     (const HChar* filename, Bool fini,
      void (*next_block)(XT_Allocs* xta, ExeContext** ec_alloc),
      XT_filter_IPs_t filter_IPs_fn)
{
   HChar* expanded_filename;

   if (fini && VG_(clo_xtree_memory) == Vg_XTMemory_None)
      return;

   expanded_filename 
      = VG_(expand_file_name)("--xtree-memory-file",
                              (filename == NULL) ?
                              (fini ? 
                               VG_(clo_xtree_memory_file)
                               : "xtmemory.kcg.%p.%n")
                              : filename);

   /* fini is False => even if user kept --xtree-memory=none, we
      produce a report when explicitely requested e.g. via a monitor
      command. */
   switch (VG_(clo_xtree_memory)) {
      case Vg_XTMemory_None:
      case Vg_XTMemory_Allocs: {
         XTree* xt;
         XT_Allocs  xta;
         ExeContext* ec_alloc;

         xt = VG_(XT_create) (VG_(malloc),
                              "VG_(XTMemory_report)",
                              VG_(free),
                              sizeof(XT_Allocs),
                              VG_(XT_Allocs_init),
                              VG_(XT_Allocs_add),
                              VG_(XT_Allocs_sub),
                              filter_IPs_fn);
         (*next_block)(&xta, &ec_alloc);
         while ( xta.nblocks > 0 ) {
            VG_(XT_add_to_ec) (xt, ec_alloc, &xta);
            (*next_block)(&xta, &ec_alloc);
         }

         produce_report(xt, expanded_filename,
                        XT_Allocs_events, VG_(XT_Allocs_img),
                        XT_Allocs_report_value);

         VG_(XT_delete)(xt);
         break;
      }
      case Vg_XTMemory_Full:
         produce_report(full_xt, expanded_filename,
                        XT_Full_events, VG_(XT_Full_img),
                        XT_Full_report_value);
         break;
      default: 
         vg_assert(0);
   }
   if (VG_(clo_verbosity) >= 1 || !fini)
      VG_(umsg)("xtree memory report: %s\n", expanded_filename);

   VG_(free)(expanded_filename);
}

/*--------------------------------------------------------------------*/
/*--- end                                                m_xtree.c ---*/
/*--------------------------------------------------------------------*/
