/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   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 3, 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, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include <errno.h>
#include <utime.h>
#include <alloca.h>
#include <dirent.h>
#include <ctype.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <set>

#include "util.h"
#include "CacheMap.h"
#include "DbeFile.h"
#include "DbeCacheMap.h"
#include "DefaultHandler.h"
#include "DefaultMap2D.h"
#include "Emsg.h"
#include "Elf.h"
#include "SAXParser.h"
#include "SAXParserFactory.h"
#include "StringBuilder.h"
#include "DbeSession.h"
#include "DbeThread.h"
#include "Application.h"
#include "CallStack.h"
#include "Experiment.h"
#include "Exp_Layout.h"
#include "DataStream.h"
#include "Expression.h"
#include "Function.h"
#include "HeapMap.h"
#include "LoadObject.h"
#include "Module.h"
#include "Ovw_data.h"
#include "PRBTree.h"
#include "Sample.h"
#include "SegMem.h"
#include "StringMap.h"
#include "UserLabel.h"
#include "Table.h"
#include "dbe_types.h"
#include "FileData.h"
#include "cc_libcollector.h"
#include "ExpGroup.h"

int nPush;
int nPop;
int pushCnt;
int popCnt;
int pushCnt3;
int popCnt3;

struct Experiment::UIDnode
{
  uint64_t uid;
  uint64_t val;
  UIDnode *next;
};

struct Experiment::RawFramePacket
{
  uint64_t uid;
  UIDnode *uidn;
  UIDnode *uidj;
  UIDnode *omp_uid;
  uint32_t omp_state;
};

static hrtime_t
parseTStamp (const char *s)
{
  hrtime_t ts = (hrtime_t) 0;
  ts = (hrtime_t) atoi (s) * NANOSEC;
  s = strchr (s, '.');
  if (s != NULL)
    ts += (hrtime_t) atoi (s + 1);
  return ts;
}

class Experiment::ExperimentFile
{
public:

  enum
  {
    EF_NOT_OPENED,
    EF_OPENED,
    EF_CLOSED,
    EF_FAILURE
  };

  ExperimentFile (Experiment *_exp, const char *_fname);
  ~ExperimentFile ();

  bool open (bool new_open = false);

  char *
  get_name ()
  {
    return fname;
  }

  inline int
  get_status ()
  {
    return ef_status;
  }

  char *fgets ();
  void close ();

  FILE *fh;

private:
  Experiment *exp;
  char *fname;
  off64_t offset;
  int bufsz, ef_status;
  char *buffer;
};

class Experiment::ExperimentHandler : public DefaultHandler
{
public:

  ExperimentHandler (Experiment *_exp);
  ~ExperimentHandler ();

  void
  startDocument () { }
  void endDocument ();
  void startElement (char *uri, char *localName, char *qName, Attributes *attrs);
  void endElement (char *uri, char *localName, char *qName);
  void characters (char *ch, int start, int length);

  void
  ignorableWhitespace (char*, int, int) { }
  void
  error (SAXParseException *e);

private:

  enum Element
  {
    EL_NONE,
    EL_EXPERIMENT,
    EL_COLLECTOR,
    EL_SETTING,
    EL_PROCESS,
    EL_SYSTEM,
    EL_EVENT,
    EL_PROFILE,
    EL_DATAPTR,
    EL_PROFDATA,
    EL_PROFPCKT,
    EL_FIELD,
    EL_CPU,
    EL_STATE,
    EL_FREQUENCY,
    EL_POWERM,
    EL_DTRACEFATAL
  };

  static int toInt (Attributes *attrs, const char *atr);
  static char*toStr (Attributes *attrs, const char *atr);
  void pushElem (Element);
  void popElem ();

  Experiment *exp;
  Element curElem;
  Vector<Element> *stack;
  Module *dynfuncModule;
  DataDescriptor *dDscr;
  PacketDescriptor *pDscr;
  PropDescr *propDscr;
  char *text;
  Cmsg_warn mkind;
  int mnum;
  int mec;
};


// HTableSize is the size of smemHTable and instHTable
// omazur: both HTableSize and the hash function haven't been tuned;
static const int HTableSize = 8192;

//-------------------------------------------------- Experiment file handler

Experiment::ExperimentFile::ExperimentFile (Experiment *_exp, const char *_fname)
{
  exp = _exp;
  fh = NULL;
  bufsz = 0;
  buffer = NULL;
  ef_status = EF_NOT_OPENED;
  offset = 0;
  fname = dbe_sprintf (NTXT ("%s/%s"), exp->expt_name, _fname);
}

Experiment::ExperimentFile::~ExperimentFile ()
{
  close ();
  free (buffer);
  free (fname);
}

bool
Experiment::ExperimentFile::open (bool new_open)
{
  if (fh == NULL)
    {
      fh = fopen64 (fname, NTXT ("r"));
      if (fh == NULL)
	{
	  ef_status = EF_FAILURE;
	  return false;
	}
      ef_status = EF_OPENED;
      if (new_open)
	offset = 0;
      if (offset != 0)
	fseeko64 (fh, offset, SEEK_SET);
    }
  return true;
}

char *
Experiment::ExperimentFile::fgets ()
{
  if (bufsz == 0)
    {
      bufsz = 1024;
      buffer = (char *) malloc (bufsz);
      if (buffer == NULL)
	return NULL;
      buffer[bufsz - 1] = (char) 1; // sentinel
    }
  char *res = ::fgets (buffer, bufsz, fh);
  if (res == NULL)
    return NULL;
  while (buffer[bufsz - 1] == (char) 0)
    {
      int newsz = bufsz + 1024;
      char *newbuf = (char *) malloc (newsz);
      if (newbuf == NULL)
	return NULL;
      memcpy (newbuf, buffer, bufsz);
      free (buffer);
      buffer = newbuf;
      buffer[newsz - 1] = (char) 1; // sentinel
      // we don't care about fgets result here
      ::fgets (buffer + bufsz - 1, newsz - bufsz + 1, fh);
      bufsz = newsz;
    }
  return buffer;
}

void
Experiment::ExperimentFile::close ()
{
  if (fh)
    {
      offset = ftello64 (fh);
      fclose (fh);
      ef_status = EF_CLOSED;
      fh = NULL;
    }
}


//-------------------------------------------------- Experiment XML parser
int
Experiment::ExperimentHandler::toInt (Attributes *attrs, const char *atr)
{
  const char *str = attrs->getValue (atr);
  return str ? atoi (str) : 0;
}

char *
Experiment::ExperimentHandler::toStr (Attributes *attrs, const char *atr)
{
  const char *str = attrs->getValue (atr);
  return dbe_strdup (str ? str : NTXT (""));
}

Experiment::ExperimentHandler::ExperimentHandler (Experiment *_exp)
{
  exp = _exp;
  stack = new Vector<Element>;
  pushElem (EL_NONE);
  dynfuncModule = NULL;
  dDscr = NULL;
  pDscr = NULL;
  propDscr = NULL;
  text = NULL;
  mkind = (Cmsg_warn) - 1; // CMSG_NONE
  mnum = -1;
  mec = -1;
}

Experiment::ExperimentHandler::~ExperimentHandler ()
{
  delete stack;
  free (text);
}

void
Experiment::ExperimentHandler::endDocument ()
{
  { // SP_TAG_STATE should be used to describe states, but it isn't
    // let's do it here:
    DataDescriptor *dd = exp->getDataDescriptor (DATA_HEAP);
    if (dd != NULL)
      {
	PropDescr *prop = dd->getProp (PROP_HTYPE);
	if (prop != NULL)
	  {
	    char * stateNames [HEAPTYPE_LAST] = HEAPTYPE_STATE_STRINGS;
	    char * stateUNames[HEAPTYPE_LAST] = HEAPTYPE_STATE_USTRINGS;
	    for (int ii = 0; ii < HEAPTYPE_LAST; ii++)
	      prop->addState (ii, stateNames[ii], stateUNames[ii]);
	  }
      }
    dd = exp->getDataDescriptor (DATA_IOTRACE);
    if (dd != NULL)
      {
	PropDescr *prop = dd->getProp (PROP_IOTYPE);
	if (prop != NULL)
	  {
	    char * stateNames [IOTRACETYPE_LAST] = IOTRACETYPE_STATE_STRINGS;
	    char * stateUNames[IOTRACETYPE_LAST] = IOTRACETYPE_STATE_USTRINGS;
	    for (int ii = 0; ii < IOTRACETYPE_LAST; ii++)
	      prop->addState (ii, stateNames[ii], stateUNames[ii]);
	  }
      }
  }
}

void
Experiment::ExperimentHandler::pushElem (Element elem)
{
  curElem = elem;
  stack->append (curElem);
}

void
Experiment::ExperimentHandler::popElem ()
{
  stack->remove (stack->size () - 1);
  curElem = stack->fetch (stack->size () - 1);
}

void
Experiment::ExperimentHandler::startElement (char*, char*, char *qName, Attributes *attrs)
{
  DEBUG_CODE if (DEBUG_SAXPARSER) dump_startElement (qName, attrs);
  if (strcmp (qName, SP_TAG_EXPERIMENT) == 0)
    {
      pushElem (EL_EXPERIMENT);
      const char *str = attrs->getValue (NTXT ("version"));
      if (str != NULL)
	{
	  int major = atoi (str);
	  str = strchr (str, '.');
	  int minor = str ? atoi (str + 1) : 0;
	  exp->exp_maj_version = major;
	  exp->exp_min_version = minor;
	  if (major != SUNPERF_VERNUM || minor != SUNPERF_VERNUM_MINOR)
	    {
	      // not the current version, see if we support some earlier versions
	      if (major < 12)
		{
		  StringBuilder sb;
		  sb.sprintf (GTXT ("*** Error: experiment %s version %d.%d is not supported;\nuse the version of the tools that recorded the experiment to read it"),
			      exp->get_expt_name (), major, minor);
		  // exp->errorq->append( new Emsg(CMSG_FATAL, sb) );
		  exp->status = FAILURE;
		  exp->obsolete = 1;
		  throw new SAXException (sb.toString ());
		}
	    }
	}
    }
  else if (strcmp (qName, SP_TAG_COLLECTOR) == 0)
    pushElem (EL_COLLECTOR);
  else if (strcmp (qName, SP_TAG_SETTING) == 0)
    {
      int found = 0;
      pushElem (EL_SETTING);
      const char *str = attrs->getValue (SP_JCMD_LIMIT);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.limit = atoi (str);
	}
      str = attrs->getValue (SP_JCMD_BLKSZ);
      if (str != NULL)
	{
	  found = 1;
	  exp->blksz = strtol (str, NULL, 0);
	}
      str = attrs->getValue (SP_JCMD_STACKBASE);
      if (str)
	{
	  found = 1;
	  exp->stack_base = strtoull (str, NULL, 0);
	}
      str = attrs->getValue (SP_JCMD_HWC_DEFAULT);
      if (str != NULL)
	{
	  found = 1;
	  exp->hwc_default = true;
	}
      str = attrs->getValue (SP_JCMD_NOIDLE);
      if (str != NULL)
	{
	  found = 1;
	  exp->commentq->append (new Emsg (CMSG_COMMENT,
					   GTXT ("*** Note: experiment does not have events from idle CPUs")));
	}
      str = attrs->getValue (SP_JCMD_FAKETIME);
      if (str != NULL)
	{
	  found = 1;
	  exp->timelineavail = false;
	  exp->commentq->append (new Emsg (CMSG_COMMENT,
					   GTXT ("*** Note: experiment does not have timestamps; timeline unavailable")));
	}
      str = attrs->getValue (SP_JCMD_DELAYSTART);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.start_delay = strdup (str);
	}
      str = attrs->getValue (SP_JCMD_TERMINATE);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.terminate = strdup (str);
	}
      str = attrs->getValue (SP_JCMD_PAUSE_SIG);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.pause_sig = strdup (str);
	}
      str = attrs->getValue (SP_JCMD_SAMPLE_PERIOD);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.sample_periodic = 1;
	  exp->coll_params.sample_timer = atoi (str);
	}
      str = attrs->getValue (SP_JCMD_SAMPLE_SIG);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.sample_sig = str;
	}
      str = attrs->getValue (SP_JCMD_SRCHPATH);
      if (str != NULL)
	{
	  found = 1;
	  StringBuilder sb;
	  sb.sprintf (GTXT ("Search path: %s"), str);
	  exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	  dbeSession->add_classpath ((char*) str);
	}
      str = attrs->getValue (SP_JCMD_LINETRACE);
      if (str != NULL)
	{
	  found = 1;
	  exp->coll_params.linetrace = strdup (str);
	}

      str = attrs->getValue (SP_JCMD_COLLENV);
      if (str != NULL)
	{
	  found = 1;
	  StringBuilder sb;
	  sb.sprintf (GTXT ("  Data collection environment variable: %s"), str);
	  exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	}
      if (found == 0)
	{
	  int nattr = attrs->getLength ();
	  if (nattr != 0)
	    {
	      fprintf (stderr, "XXX Unexpected setting found; %d attributes:\n",
		       nattr);
	      for (int k = 0; k < nattr; k++)
		{
		  const char *qn = attrs->getQName (k);
		  const char *vl = attrs->getValue (k);
		  fprintf (stderr, "XXX      %s = %s\n", qn, vl);
		}
	    }
	}
      // END OF CODE FOR "setting"
    }
  else if (strcmp (qName, SP_TAG_SYSTEM) == 0)
    {
      pushElem (EL_SYSTEM);
      const char *str = attrs->getValue (NTXT ("hostname"));
      if (str != NULL)
	exp->hostname = strdup (str);
      str = attrs->getValue (NTXT ("os"));
      if (str != NULL)
	{
	  exp->os_version = strdup (str);
	  /* For Linux experiments expect sparse thread ID's */
	  if (strncmp (str, NTXT ("SunOS"), 5) != 0)
	    exp->sparse_threads = true;
	}
      str = attrs->getValue (NTXT ("arch"));
      if (str != NULL)
	{
	  if (strcmp (str, "i86pc") == 0 || strcmp (str, "i686") == 0
	      || strcmp (str, "x86_64") == 0)
	    exp->platform = Intel;
	  else if (strcmp (str, "aarch64") == 0)
	    exp->platform = Aarch64;
	  else
	    exp->platform = Sparc;
	  exp->need_swap_endian = (DbeSession::platform == Sparc) ?
		  (exp->platform != Sparc) : (exp->platform == Sparc);
	  exp->architecture = strdup (str);
	}
      str = attrs->getValue (NTXT ("pagesz"));
      if (str != NULL)
	exp->page_size = atoi (str);
      str = attrs->getValue (NTXT ("npages"));
      if (str != NULL)
	exp->npages = atoi (str);
    }
  else if (strcmp (qName, SP_TAG_POWERM) == 0)
    pushElem (EL_POWERM);
  else if (strcmp (qName, SP_TAG_FREQUENCY) == 0)
    {
      pushElem (EL_FREQUENCY);
      const char *str = attrs->getValue (NTXT ("clk"));
      if (str != NULL)
	exp->set_clock (atoi (str));
      // check for frequency_scaling or turbo_mode recorded from libcollector under dbx
      str = attrs->getValue (NTXT ("frequency_scaling"));
      const char *str2 = attrs->getValue (NTXT ("turbo_mode"));
      if (str != NULL || str2 != NULL)
	exp->varclock = 1;
    }
  else if (strcmp (qName, SP_TAG_CPU) == 0)
    {
      pushElem (EL_CPU);
      exp->ncpus++;
      const char *str = attrs->getValue (NTXT ("clk"));
      if (str != NULL)
	{
	  int clk = atoi (str);
	  if (exp->maxclock == 0)
	    {
	      exp->minclock = clk;
	      exp->maxclock = clk;
	    }
	  else
	    {
	      if (clk < exp->minclock)
		exp->minclock = clk;
	      if (clk > exp->maxclock)
		exp->maxclock = clk;
	    }
	  exp->clock = clk;
	}
      // check for frequency_scaling or turbo_mode
      str = attrs->getValue (NTXT ("frequency_scaling"));
      const char *str2 = attrs->getValue (NTXT ("turbo_mode"));
      if (str != NULL || str2 != NULL)
	exp->varclock = 1;
    }
  else if (strcmp (qName, SP_TAG_PROCESS) == 0)
    {
      pushElem (EL_PROCESS);
      const char *str = attrs->getValue (NTXT ("wsize"));
      if (str != NULL)
	{
	  int wsz = atoi (str);
	  if (wsz == 32)
	    exp->wsize = W32;
	  else if (wsz == 64)
	    exp->wsize = W64;
	}
      str = attrs->getValue (NTXT ("pid"));
      if (str != NULL)
	exp->pid = atoi (str);
      str = attrs->getValue (NTXT ("ppid"));
      if (str != NULL)
	exp->ppid = atoi (str);
      str = attrs->getValue (NTXT ("pgrp"));
      if (str != NULL)
	exp->pgrp = atoi (str);
      str = attrs->getValue (NTXT ("sid"));
      if (str != NULL)
	exp->sid = atoi (str);
      str = attrs->getValue (NTXT ("cwd"));
      if (str != NULL)
	exp->ucwd = strdup (str);
      str = attrs->getValue (NTXT ("pagesz"));
      if (str != NULL)
	exp->page_size = atoi (str);
    }
  else if (strcmp (qName, SP_TAG_EVENT) == 0)
    { // Start code for event
      pushElem (EL_EVENT);
      hrtime_t ts = (hrtime_t) 0;
      const char *str = attrs->getValue (NTXT ("tstamp"));
      if (str != NULL)
	ts = parseTStamp (str);
      str = attrs->getValue (NTXT ("kind"));
      if (str != NULL)
	{
	  if (strcmp (str, SP_JCMD_RUN) == 0)
	    {
	      exp->broken = 0;
	      exp->exp_start_time = ts;
	      str = attrs->getValue (NTXT ("time"));
	      if (str != NULL)
		exp->start_sec = atoll (str);
	      str = attrs->getValue (NTXT ("pid"));
	      if (str != NULL)
		exp->pid = atoi (str);
	      str = attrs->getValue (NTXT ("ppid"));
	      if (str != NULL)
		exp->ppid = atoi (str);
	      str = attrs->getValue (NTXT ("pgrp"));
	      if (str != NULL)
		exp->pgrp = atoi (str);
	      str = attrs->getValue (NTXT ("sid"));
	      if (str != NULL)
		exp->sid = atoi (str);
	      exp->status = Experiment::INCOMPLETE;
	    }
	  else if (strcmp (str, SP_JCMD_ARCHIVE) == 0)
	    {
	      StringBuilder sb;
	      sb.sprintf (GTXT ("gp-archive run: XXXXXXX"));
	      exp->pprocq->append (new Emsg (CMSG_WARN, sb));
	    }
	  else if (strcmp (str, SP_JCMD_SAMPLE) == 0)
	    {
	      exp->update_last_event (exp->exp_start_time + ts); // ts is 0-based
	      str = attrs->getValue (NTXT ("id"));
	      int id = str ? atoi (str) : -1;
	      char *label = dbe_strdup (attrs->getValue (NTXT ("label")));
	      exp->process_sample_cmd (NULL, ts, id, label);
	    }
	  else if (strcmp (str, SP_JCMD_EXIT) == 0)
	    {
	      // don't treat EXIT as an event w.r.t. last_event and non_paused_time
	      exp->status = Experiment::SUCCESS;
	    }
	  else if (strcmp (str, SP_JCMD_CERROR) == 0)
	    {
	      mkind = CMSG_ERROR;
	      str = attrs->getValue (NTXT ("id"));
	      if (str != NULL)
		{
		  mnum = atoi (str);
		}
	      str = attrs->getValue (NTXT ("ec"));
	      if (str != NULL)
		{
		  mec = atoi (str);
		}
	    }
	  else if (strcmp (str, SP_JCMD_CWARN) == 0)
	    {
	      mkind = CMSG_WARN;
	      str = attrs->getValue (NTXT ("id"));
	      if (str != NULL)
		mnum = atoi (str);
	    }
	  else if (strcmp (str, SP_JCMD_COMMENT) == 0)
	    {
	      mkind = CMSG_COMMENT;
	      str = attrs->getValue (NTXT ("id"));
	      if (str != NULL)
		mnum = atoi (str);
	      str = attrs->getValue (NTXT ("text"));
	      if (str != NULL)
		{
		  StringBuilder sb;
		  sb.sprintf (GTXT ("*** Note: %s"), str);
		  exp->commentq->append (new Emsg (CMSG_COMMENT, sb));
		}
	    }
	  else if (strcmp (str, SP_JCMD_DESC_START) == 0)
	    {
	      char *variant = toStr (attrs, NTXT ("variant"));
	      char *lineage = toStr (attrs, NTXT ("lineage"));
	      int follow = toInt (attrs, NTXT ("follow"));
	      char *msg = toStr (attrs, NTXT ("msg"));
	      exp->process_desc_start_cmd (NULL, ts, variant, lineage, follow, msg);
	    }
	  else if (strcmp (str, SP_JCMD_DESC_STARTED) == 0)
	    {
	      char *variant = toStr (attrs, NTXT ("variant"));
	      char *lineage = toStr (attrs, NTXT ("lineage"));
	      int follow = toInt (attrs, NTXT ("follow"));
	      char *msg = toStr (attrs, NTXT ("msg"));
	      exp->process_desc_started_cmd (NULL, ts, variant, lineage, follow, msg);
	    }
	  else if (strcmp (str, SP_JCMD_EXEC_START) == 0)
	    {
	      // if successful, acts like experiment termination - no "exit" entry will follow
	      exp->update_last_event (exp->exp_start_time + ts); // ts is 0-based
	      char *variant = toStr (attrs, NTXT ("variant"));
	      char *lineage = toStr (attrs, NTXT ("lineage"));
	      int follow = toInt (attrs, NTXT ("follow"));
	      char *msg = toStr (attrs, NTXT ("msg"));
	      exp->process_desc_start_cmd (NULL, ts, variant, lineage, follow, msg);
	      exp->exec_started = true;
	    }
	  else if (strcmp (str, SP_JCMD_EXEC_ERROR) == 0)
	    {
	      exp->update_last_event (exp->exp_start_time + ts); // ts is 0-based
	      char *variant = toStr (attrs, NTXT ("variant"));
	      char *lineage = toStr (attrs, NTXT ("lineage"));
	      int follow = toInt (attrs, NTXT ("follow"));
	      char *msg = toStr (attrs, NTXT ("msg"));
	      exp->process_desc_started_cmd (NULL, ts, variant, lineage, follow, msg);
	      exp->exec_started = false;
	    }
	  else if (strcmp (str, SP_JCMD_JTHRSTART) == 0)
	    {
	      char *name = dbe_strdup (attrs->getValue (NTXT ("name")));
	      char *grpname = dbe_strdup (attrs->getValue (NTXT ("grpname")));
	      char *prntname = dbe_strdup (attrs->getValue (NTXT ("prntname")));
	      str = attrs->getValue (NTXT ("tid"));
	      uint64_t tid = str ? strtoull (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("jthr"));
	      Vaddr jthr = str ? strtoull (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("jenv"));
	      Vaddr jenv = str ? strtoull (str, NULL, 0) : 0;
	      exp->process_jthr_start_cmd (NULL, name, grpname, prntname, tid, jthr, jenv, ts);
	    }
	  else if (strcmp (str, SP_JCMD_JTHREND) == 0)
	    {
	      str = attrs->getValue (NTXT ("tid"));
	      uint64_t tid = str ? strtoull (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("jthr"));
	      Vaddr jthr = str ? strtoull (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("jenv"));
	      Vaddr jenv = str ? strtoull (str, NULL, 0) : 0;
	      exp->process_jthr_end_cmd (NULL, tid, jthr, jenv, ts);
	    }
	  else if (strcmp (str, SP_JCMD_GCEND) == 0)
	    {
	      if (exp->getDataDescriptor (DATA_GCEVENT) == NULL)
		exp->newDataDescriptor (DATA_GCEVENT);
	      exp->process_gc_end_cmd (ts);
	    }
	  else if (strcmp (str, SP_JCMD_GCSTART) == 0)
	    {
	      if (exp->getDataDescriptor (DATA_GCEVENT) == NULL)
		exp->newDataDescriptor (DATA_GCEVENT);
	      exp->process_gc_start_cmd (ts);
	    }
	  else if (strcmp (str, SP_JCMD_PAUSE) == 0)
	    {
	      if (exp->resume_ts != MAX_TIME)
		{
		  // data collection was active
		  hrtime_t delta = ts - exp->resume_ts;
		  exp->non_paused_time += delta;
		  exp->resume_ts = MAX_TIME; // collection is paused
		}
	      StringBuilder sb;
	      str = attrs->getValue (NTXT ("name"));
	      if (str == NULL)
		sb.sprintf (GTXT ("Pause: %ld.%09ld"), (long) (ts / NANOSEC),
			    (long) (ts % NANOSEC));
	      else
		sb.sprintf (GTXT ("Pause (%s): %ld.%09ld"), str,
			    (long) (ts / NANOSEC), (long) (ts % NANOSEC));
	      exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	    }
	  else if (strcmp (str, SP_JCMD_RESUME) == 0)
	    {
	      if (exp->resume_ts == MAX_TIME)
		// data collection was paused
		exp->resume_ts = ts; // remember start time
	      StringBuilder sb;
	      sb.sprintf (GTXT ("Resume: %ld.%09ld"), (long) (ts / NANOSEC), (long) (ts % NANOSEC));
	      exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	      if (exp->exp_start_time == ZERO_TIME)
		exp->exp_start_time = ts;
	    }
	  else if (strcmp (str, SP_JCMD_THREAD_PAUSE) == 0)
	    {
	      str = attrs->getValue (NTXT ("tid"));
	      uint64_t tid = str ? strtoull (str, NULL, 0) : 0;
	      StringBuilder sb;
	      sb.sprintf (GTXT ("Thread %llu pause: %ld.%09ld"), (unsigned long long) tid,
			  (long) (ts / NANOSEC), (long) (ts % NANOSEC));
	      exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	    }
	  else if (strcmp (str, SP_JCMD_THREAD_RESUME) == 0)
	    {
	      str = attrs->getValue (NTXT ("tid"));
	      uint64_t tid = str ? strtoull (str, NULL, 0) : 0;
	      StringBuilder sb;
	      sb.sprintf (GTXT ("Thread %llu resume: %ld.%09ld"), (unsigned long long) tid,
			  (long) (ts / NANOSEC), (long) (ts % NANOSEC));
	      exp->runlogq->append (new Emsg (CMSG_COMMENT, sb));
	    }
	  else if (strcmp (str, NTXT ("map")) == 0)
	    {
	      ts += exp->exp_start_time;
	      str = attrs->getValue (NTXT ("vaddr"));
	      Vaddr vaddr = str ? strtoull (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("size"));
	      int msize = str ? atoi (str) : 0;
	      str = attrs->getValue (NTXT ("foffset"));
	      int64_t offset = str ? strtoll (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("modes"));
	      int64_t modes = str ? strtoll (str, NULL, 0) : 0;
	      str = attrs->getValue (NTXT ("chksum"));
	      int64_t chksum = 0;
	      if (str)
		chksum = Elf::normalize_checksum (strtoll (str, NULL, 0));
	      char *name = (char *) attrs->getValue (NTXT ("name"));
	      str = attrs->getValue (NTXT ("object"));
	      if (strcmp (str, NTXT ("segment")) == 0)
		{
		  if (strcmp (name, NTXT ("LinuxKernel")) == 0)
		    exp->process_Linux_kernel_cmd (ts);
		  else
		    exp->process_seg_map_cmd (NULL, ts, vaddr, msize, 0,
					      offset, modes, chksum, name);
		}
	      else if (strcmp (str, NTXT ("function")) == 0)
		{
		  exp->process_fn_load_cmd (dynfuncModule, name, vaddr, msize, ts);
		  dynfuncModule = NULL;
		}
	      else if (strcmp (str, NTXT ("dynfunc")) == 0)
		{
		  if (dynfuncModule == NULL)
		    {
		      dynfuncModule = dbeSession->createModule (exp->get_dynfunc_lo (DYNFUNC_SEGMENT), name);
		      dynfuncModule->flags |= MOD_FLAG_UNKNOWN;
		      dynfuncModule->set_file_name (dbe_strdup (dynfuncModule->getMainSrc ()->get_name ()));
		    }
		  (void) exp->create_dynfunc (dynfuncModule,
					      (char*) attrs->getValue (NTXT ("funcname")), vaddr, msize);
		}
	      else if (strcmp (str, NTXT ("jcm")) == 0)
		{
		  str = attrs->getValue (NTXT ("methodId"));
		  Vaddr mid = str ? strtoull (str, NULL, 0) : 0;
		  exp->process_jcm_load_cmd (NULL, mid, vaddr, msize, ts);
		}
	    }
	  else if (strcmp (str, NTXT ("unmap")) == 0)
	    {
	      ts += exp->exp_start_time;
	      str = attrs->getValue (NTXT ("vaddr"));
	      Vaddr vaddr = str ? strtoull (str, NULL, 0) : 0;
	      exp->process_seg_unmap_cmd (NULL, ts, vaddr);
	    }
	}
      // end of code for event
    }
  else if (strcmp (qName, SP_TAG_PROFILE) == 0)
    {
      pushElem (EL_PROFILE);
      const char *str = attrs->getValue (NTXT ("name"));
      if (str == NULL)
	return;
      if (strcmp (str, NTXT ("profile")) == 0)
	{
	  exp->coll_params.profile_mode = 1;
	  str = attrs->getValue (NTXT ("numstates"));
	  if (str != NULL)
	    exp->coll_params.lms_magic_id = atoi (str);
	  str = attrs->getValue (NTXT ("ptimer"));
	  if (str != NULL)
	    exp->coll_params.ptimer_usec = atoi (str); // microseconds

	  PropDescr *mstate_prop = NULL;
	  char * stateNames [/*LMS_NUM_STATES*/] = LMS_STATE_STRINGS;
	  char * stateUNames[/*LMS_NUM_STATES*/] = LMS_STATE_USTRINGS;
	  {
	    dDscr = exp->newDataDescriptor (DATA_CLOCK);
	    PropDescr *prop = new PropDescr (PROP_MSTATE, NTXT ("MSTATE"));
	    prop->uname = dbe_strdup (GTXT ("Thread state"));
	    prop->vtype = TYPE_UINT32;
	    // (states added below)
	    dDscr->addProperty (prop);
	    mstate_prop = prop;

	    prop = new PropDescr (PROP_NTICK, NTXT ("NTICK"));
	    prop->uname = dbe_strdup (GTXT ("Number of Profiling Ticks"));
	    prop->vtype = TYPE_UINT32;
	    dDscr->addProperty (prop);
	  }

	  switch (exp->coll_params.lms_magic_id)
	    {
	    case LMS_MAGIC_ID_SOLARIS:
	      exp->register_metric (Metric::CP_TOTAL);
	      exp->register_metric (Metric::CP_TOTAL_CPU);
	      exp->register_metric (Metric::CP_LMS_USER);
	      exp->register_metric (Metric::CP_LMS_SYSTEM);
	      exp->register_metric (Metric::CP_LMS_TRAP);
	      exp->register_metric (Metric::CP_LMS_DFAULT);
	      exp->register_metric (Metric::CP_LMS_TFAULT);
	      exp->register_metric (Metric::CP_LMS_KFAULT);
	      exp->register_metric (Metric::CP_LMS_STOPPED);
	      exp->register_metric (Metric::CP_LMS_WAIT_CPU);
	      exp->register_metric (Metric::CP_LMS_SLEEP);
	      exp->register_metric (Metric::CP_LMS_USER_LOCK);
	      for (int ii = 0; ii < LMS_NUM_SOLARIS_MSTATES; ii++)
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
	      break;
	    case LMS_MAGIC_ID_ERKERNEL_KERNEL:
	      exp->register_metric (Metric::CP_KERNEL_CPU);
	      {
		int ii = LMS_KERNEL_CPU;
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
	      }
	      break;
	    case LMS_MAGIC_ID_ERKERNEL_USER:
	      exp->register_metric (Metric::CP_TOTAL_CPU);
	      exp->register_metric (Metric::CP_LMS_USER);
	      exp->register_metric (Metric::CP_LMS_SYSTEM);
	      {
		int ii = LMS_KERNEL_CPU;
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
		ii = LMS_USER;
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
		ii = LMS_SYSTEM;
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
	      }
	      break;
	    case LMS_MAGIC_ID_LINUX:
	      exp->register_metric (Metric::CP_TOTAL_CPU);
	      {
		int ii = LMS_LINUX_CPU;
		mstate_prop->addState (ii, stateNames[ii], stateUNames[ii]);
	      }
	      break;
	    default:
	      // odd
	      break;
	    }
	}
      else if (strcmp (str, NTXT ("heaptrace")) == 0)
	{
	  exp->coll_params.heap_mode = 1;
	  exp->leaklistavail = true;
	  exp->heapdataavail = true;
	  exp->register_metric (Metric::HEAP_ALLOC_BYTES);
	  exp->register_metric (Metric::HEAP_ALLOC_CNT);
	  exp->register_metric (Metric::HEAP_LEAK_BYTES);
	  exp->register_metric (Metric::HEAP_LEAK_CNT);
	  dDscr = exp->newDataDescriptor (DATA_HEAP);
	}
      else if (strcmp (str, NTXT ("iotrace")) == 0)
	{
	  exp->coll_params.io_mode = 1;
	  exp->iodataavail = true;
	  exp->register_metric (Metric::IO_READ_TIME);
	  exp->register_metric (Metric::IO_READ_BYTES);
	  exp->register_metric (Metric::IO_READ_CNT);
	  exp->register_metric (Metric::IO_WRITE_TIME);
	  exp->register_metric (Metric::IO_WRITE_BYTES);
	  exp->register_metric (Metric::IO_WRITE_CNT);
	  exp->register_metric (Metric::IO_OTHER_TIME);
	  exp->register_metric (Metric::IO_OTHER_CNT);
	  exp->register_metric (Metric::IO_ERROR_TIME);
	  exp->register_metric (Metric::IO_ERROR_CNT);
	  dDscr = exp->newDataDescriptor (DATA_IOTRACE);
	}
      else if (strcmp (str, NTXT ("synctrace")) == 0)
	{
	  exp->coll_params.sync_mode = 1;
	  str = attrs->getValue (NTXT ("threshold"));
	  if (str != NULL)
	    exp->coll_params.sync_threshold = atoi (str);
	  str = attrs->getValue (NTXT ("scope"));
	  if (str != NULL)
	    exp->coll_params.sync_scope = atoi (str);
	  else  // Should only happen with old experiments; use the old default
	    exp->coll_params.sync_scope = SYNCSCOPE_NATIVE | SYNCSCOPE_JAVA;
	  exp->register_metric (Metric::SYNC_WAIT_TIME);
	  exp->register_metric (Metric::SYNC_WAIT_COUNT);
	  dDscr = exp->newDataDescriptor (DATA_SYNCH);
	}
      else if (strcmp (str, NTXT ("omptrace")) == 0)
	{
	  exp->coll_params.omp_mode = 1;
	  dDscr = exp->newDataDescriptor (DATA_OMP, DDFLAG_NOSHOW);
	}
      else if (strcmp (str, NTXT ("hwcounter")) == 0)
	{
	  str = attrs->getValue (NTXT ("cpuver"));
	  int cpuver = str ? atoi (str) : 0;
	  char *counter = dbe_strdup (attrs->getValue (NTXT ("hwcname")));
	  char *int_name = dbe_strdup (attrs->getValue (NTXT ("int_name"))); // may not be present
	  str = attrs->getValue (NTXT ("interval"));
	  int interval = str ? atoi (str) : 0;
	  str = attrs->getValue (NTXT ("tag"));
	  int tag = str ? atoi (str) : 0;
	  str = attrs->getValue (NTXT ("memop"));
	  int i_tpc = str ? atoi (str) : 0;
	  char *modstr = dbe_strdup (attrs->getValue (NTXT ("modstr")));
	  exp->process_hwcounter_cmd (NULL, cpuver, counter, int_name, interval, tag, i_tpc, modstr);
	  dDscr = exp->newDataDescriptor (DATA_HWC);
	}
      else if (strcmp (str, NTXT ("hwsimctr")) == 0)
	{
	  int cpuver = toInt (attrs, NTXT ("cpuver"));
	  char *hwcname = dbe_strdup (attrs->getValue (NTXT ("hwcname")));
	  char *int_name = dbe_strdup (attrs->getValue (NTXT ("int_name")));
	  char *metric = dbe_strdup (attrs->getValue (NTXT ("metric")));
	  int reg = toInt (attrs, NTXT ("reg_num"));
	  int interval = toInt (attrs, NTXT ("interval"));
	  int timecvt = toInt (attrs, NTXT ("timecvt"));
	  int i_tpc = toInt (attrs, NTXT ("memop"));
	  int tag = toInt (attrs, NTXT ("tag"));
	  exp->process_hwsimctr_cmd (NULL, cpuver, hwcname, int_name, metric, reg,
				     interval, timecvt, i_tpc, tag);
	  dDscr = exp->newDataDescriptor (DATA_HWC);
	}
      else if (strcmp (str, NTXT ("dversion")) == 0)
	exp->dversion = dbe_strdup (attrs->getValue (NTXT ("version")));
      else if (strcmp (str, NTXT ("jprofile")) == 0)
	{
	  exp->has_java = true;
	  str = attrs->getValue (NTXT ("jversion"));
	  if (str != NULL)
	    exp->jversion = strdup (str);
	}
      else if (strcmp (str, NTXT ("datarace")) == 0)
	{
	  exp->coll_params.race_mode = 1;
	  exp->racelistavail = true;
	  str = attrs->getValue (NTXT ("scheme"));
	  exp->coll_params.race_stack = str ? atoi (str) : 0;
	  exp->register_metric (Metric::RACCESS);
	  dDscr = exp->newDataDescriptor (DATA_RACE);
	}
      else if (strcmp (str, NTXT ("deadlock")) == 0)
	{
	  exp->coll_params.deadlock_mode = 1;
	  exp->deadlocklistavail = true;
	  exp->register_metric (Metric::DEADLOCKS);
	  dDscr = exp->newDataDescriptor (DATA_DLCK);
	}
    }
    /* XXX -- obsolete tag, but is still written to experiments */
  else if (strcmp (qName, SP_TAG_DATAPTR) == 0)
    {
      pushElem (EL_DATAPTR);
      return;
    }
  else if (strcmp (qName, SP_TAG_PROFDATA) == 0)
    {
      pushElem (EL_PROFDATA);
      // SS12 HWC experiments are not well structured
      const char *fname = attrs->getValue (NTXT ("fname"));
      if (fname && strcmp (fname, SP_HWCNTR_FILE) == 0)
	dDscr = exp->newDataDescriptor (DATA_HWC);
    }
  else if (strcmp (qName, SP_TAG_PROFPCKT) == 0)
    {
      pushElem (EL_PROFPCKT);
      const char *str = attrs->getValue (NTXT ("kind")); // see Pckt_type
      int kind = str ? atoi (str) : -1;
      if (kind < 0)
	return;
      if (exp->coll_params.omp_mode == 1)
	{
	  if (kind == OMP_PCKT)
	    dDscr = exp->newDataDescriptor (DATA_OMP, DDFLAG_NOSHOW);
	  else if (kind == OMP2_PCKT)
	    dDscr = exp->newDataDescriptor (DATA_OMP2, DDFLAG_NOSHOW);
	  else if (kind == OMP3_PCKT)
	    dDscr = exp->newDataDescriptor (DATA_OMP3, DDFLAG_NOSHOW);
	  else if (kind == OMP4_PCKT)
	    dDscr = exp->newDataDescriptor (DATA_OMP4, DDFLAG_NOSHOW);
	  else if (kind == OMP5_PCKT)
	    dDscr = exp->newDataDescriptor (DATA_OMP5, DDFLAG_NOSHOW);
	}
      pDscr = exp->newPacketDescriptor (kind, dDscr);
      return;
    }
  else if (strcmp (qName, SP_TAG_FIELD) == 0)
    {
      pushElem (EL_FIELD);
      if (pDscr != NULL)
	{
	  const char *name = attrs->getValue (NTXT ("name"));
	  if (name == NULL)
	    return;
	  int propID = dbeSession->registerPropertyName (name);
	  propDscr = new PropDescr (propID, name);
	  FieldDescr *fldDscr = new FieldDescr (propID, name);

	  const char *str = attrs->getValue (NTXT ("type"));
	  if (str)
	    {
	      if (strcmp (str, NTXT ("INT32")) == 0)
		fldDscr->vtype = TYPE_INT32;
	      else if (strcmp (str, NTXT ("UINT32")) == 0)
		fldDscr->vtype = TYPE_UINT32;
	      else if (strcmp (str, NTXT ("INT64")) == 0)
		fldDscr->vtype = TYPE_INT64;
	      else if (strcmp (str, NTXT ("UINT64")) == 0)
		fldDscr->vtype = TYPE_UINT64;
	      else if (strcmp (str, NTXT ("STRING")) == 0)
		fldDscr->vtype = TYPE_STRING;
	      else if (strcmp (str, NTXT ("DOUBLE")) == 0)
		fldDscr->vtype = TYPE_DOUBLE;
	      else if (strcmp (str, NTXT ("DATE")) == 0)
		{
		  fldDscr->vtype = TYPE_DATE;
		  const char *fmt = attrs->getValue (NTXT ("format"));
		  fldDscr->format = strdup (fmt ? fmt : "");
		}
	    }
	  propDscr->vtype = fldDscr->vtype;

	  // TYPE_DATE is converted to TYPE_UINT64 in propDscr
	  if (fldDscr->vtype == TYPE_DATE)
	    propDscr->vtype = TYPE_UINT64;

	  // Fix some types until they are fixed in libcollector
	  if (propID == PROP_VIRTPC || propID == PROP_PHYSPC)
	    {
	      if (fldDscr->vtype == TYPE_INT32)
		propDscr->vtype = TYPE_UINT32;
	      else if (fldDscr->vtype == TYPE_INT64)
		propDscr->vtype = TYPE_UINT64;
	    }

	  // The following props get mapped to 32-bit values in readPacket
	  if (propID == PROP_CPUID || propID == PROP_THRID
	      || propID == PROP_LWPID)
	    propDscr->vtype = TYPE_UINT32; // override experiment property

	  str = attrs->getValue (NTXT ("uname"));
	  if (str)
	    propDscr->uname = strdup (PTXT ((char*) str));
	  str = attrs->getValue (NTXT ("noshow"));
	  if (str && atoi (str) != 0)
	    propDscr->flags |= PRFLAG_NOSHOW;

	  if (dDscr == NULL)
	    {
	      StringBuilder sb;
	      sb.sprintf (GTXT ("*** Error: data parsing failed. Log file is corrupted."));
	      exp->warnq->append (new Emsg (CMSG_ERROR, sb));
	      throw new SAXException (sb.toString ());
	    }

	  dDscr->addProperty (propDscr);
	  str = attrs->getValue (NTXT ("offset"));
	  if (str)
	    fldDscr->offset = atoi (str);
	  pDscr->addField (fldDscr);
	}
    }
  else if (strcmp (qName, SP_TAG_STATE) == 0)
    {
      pushElem (EL_STATE);
      if (propDscr != NULL)
	{
	  const char *str = attrs->getValue (NTXT ("value"));
	  int value = str ? atoi (str) : -1;
	  str = attrs->getValue (NTXT ("name"));
	  const char *ustr = attrs->getValue (NTXT ("uname"));
	  propDscr->addState (value, str, ustr);
	}
    }
  else if (strcmp (qName, SP_TAG_DTRACEFATAL) == 0)
    pushElem (EL_DTRACEFATAL);
  else
    {
      StringBuilder sb;
      sb.sprintf (GTXT ("*** Warning: unrecognized element %s"), qName);
      exp->warnq->append (new Emsg (CMSG_WARN, sb));
      pushElem (EL_NONE);
    }
}

void
Experiment::ExperimentHandler::characters (char *ch, int start, int length)
{
  switch (curElem)
    {
    case EL_COLLECTOR:
      exp->cversion = dbe_strndup (ch + start, length);
      break;
    case EL_PROCESS:
      exp->process_arglist_cmd (NULL, dbe_strndup (ch + start, length));
      break;
    case EL_EVENT:
      free (text);
      text = dbe_strndup (ch + start, length);
      break;
    default:
      break;
    }
}

void
Experiment::ExperimentHandler::endElement (char*, char*, char*)
{
  if (curElem == EL_EVENT && mkind >= 0 && mnum >= 0)
    {
      char *str;
      if (mec > 0)
	str = dbe_sprintf ("%s -- %s", text != NULL ? text : "", strerror (mec));
      else
	str = dbe_sprintf ("%s", text != NULL ? text : "");
      Emsg *msg = new Emsg (mkind, mnum, str);
      if (mkind == CMSG_WARN)
	{
	  if (mnum != COL_WARN_FSTYPE
	      || dbeSession->check_ignore_fs_warn () == false)
	    exp->warnq->append (msg);
	  else
	    exp->commentq->append (msg);
	}
      else if (mkind == CMSG_ERROR || mkind == CMSG_FATAL)
	exp->errorq->append (msg);
      else if (mkind == CMSG_COMMENT)
	exp->commentq->append (msg);
      else
	delete msg;
      mkind = (Cmsg_warn) - 1;
      mnum = -1;
      mec = -1;
    }
  else if (curElem == EL_PROFILE)
    dDscr = NULL;
  else if (curElem == EL_PROFPCKT)
    pDscr = NULL;
  else if (curElem == EL_FIELD)
    propDscr = NULL;
  free (text);
  text = NULL;
  popElem ();
}

void
Experiment::ExperimentHandler::error (SAXParseException *e)
{
  StringBuilder sb;
  sb.sprintf (GTXT ("%s at line %d, column %d"),
	      e->getMessage (), e->getLineNumber (), e->getColumnNumber ());
  char *msg = sb.toString ();
  SAXException *e1 = new SAXException (msg);
  free (msg);
  throw ( e1);
}

//-------------------------------------------------- Experiment

Experiment::Experiment ()
{
  groupId = 0;
  userExpId = expIdx = -1;
  founder_exp = NULL;
  baseFounder = NULL;
  children_exps = new Vector<Experiment*>;
  loadObjs = new Vector<LoadObject*>;
  loadObjMap = new StringMap<LoadObject*>(128, 128);
  sourcesMap = NULL;

  // Initialize configuration information.
  status = FAILURE;
  start_sec = 0;
  mtime = 0;
  hostname = NULL;
  username = NULL;
  architecture = NULL;
  os_version = NULL;
  uarglist = NULL;
  utargname = NULL;
  ucwd = NULL;
  cversion = NULL;
  dversion = NULL;
  jversion = NULL;
  exp_maj_version = 0;
  exp_min_version = 0;
  platform = Unknown;
  wsize = Wnone;
  page_size = 4096;
  npages = 0;
  stack_base = 0xf0000000;
  broken = 1;
  obsolete = 0;
  hwc_bogus = 0;
  hwc_lost_int = 0;
  hwc_scanned = 0;
  hwc_default = false;
  invalid_packet = 0;

  // clear HWC event stats
  dsevents = 0;
  dsnoxhwcevents = 0;

  memset (&coll_params, 0, sizeof (coll_params));
  ncpus = 0;
  minclock = 0;
  maxclock = 0;
  clock = 0;
  varclock = 0;
  exec_started = false;
  timelineavail = true;
  leaklistavail = false;
  heapdataavail = false;
  iodataavail = false;
  dataspaceavail = false;
  ifreqavail = false;
  racelistavail = false;
  deadlocklistavail = false;
  ompavail = false;
  tiny_threshold = -1;
  pid = 0;
  ppid = 0;
  pgrp = 0;
  sid = 0;

  gc_duration = ZERO_TIME;
  exp_start_time = ZERO_TIME; // not known.  Wall-clock hrtime (not zero based)
  last_event = ZERO_TIME; // not known.  Wall-clock hrtime (not zero based)
  non_paused_time = 0; // 0 non-paused time (will sum as experiment is processed)
  resume_ts = 0; // by default, collection is "resumed" (not paused) from time=0
  need_swap_endian = false;
  exp_rel_start_time_set = false;
  exp_rel_start_time = ZERO_TIME;
  has_java = false;
  hex_field_width = 8;
  hw_cpuver = CPUVER_UNDEFINED;
  machinemodel = NULL;
  expt_name = NULL;
  arch_name = NULL;
  fndr_arch_name = NULL;
  dyntext_name = NULL;
  logFile = NULL;

  dataDscrs = new Vector<DataDescriptor*>;
  for (int i = 0; i < DATA_LAST; ++i)
    dataDscrs->append (NULL);

  pcktDscrs = new Vector<PacketDescriptor*>;
  blksz = PROFILE_BUFFER_CHUNK;
  jthreads = new Vector<JThread*>;
  jthreads_idx = new Vector<JThread*>;
  gcevents = new Vector<GCEvent*>;
  gcevent_last_used = (GCEvent *) NULL;
  heapUnmapEvents = new Vector<UnmapChunk*>;
  cstack = NULL;
  cstackShowHide = NULL;
  frmpckts = new Vector<RawFramePacket*>;
  typedef DefaultMap2D<uint32_t, hrtime_t, uint64_t> OmpMap0;
  mapPRid = new OmpMap0 (OmpMap0::Interval);
  typedef DefaultMap2D<uint32_t, hrtime_t, void*> OmpMap;
  mapPReg = new OmpMap (OmpMap::Interval);
  mapTask = new OmpMap (OmpMap::Interval);
  openMPdata = NULL;
  archiveMap = NULL;
  nnodes = 0;
  nchunks = 0;
  chunks = 0;
  uidHTable = NULL;
  uidnodes = new Vector<UIDnode*>;
  mrecs = new Vector<MapRecord*>;
  samples = new Vector<Sample*>;
  sample_last_used = (Sample *) NULL;
  first_sample_label = (char*) NULL;
  fDataMap = NULL;
  vFdMap = NULL;
  resolveFrameInfo = true;
  discardTiny = false;
  init ();
}

Experiment::~Experiment ()
{
  fini ();
  free (coll_params.linetrace);
  for (int i = 0; i < MAX_HWCOUNT; i++)
    {
      free (coll_params.hw_aux_name[i]);
      free (coll_params.hw_username[i]);
    }
  free (hostname);
  free (username);
  free (architecture);
  free (os_version);
  free (uarglist);
  free (utargname);
  free (ucwd);
  free (cversion);
  free (dversion);
  free (jversion);
  delete logFile;
  free (expt_name);
  free (arch_name);
  free (fndr_arch_name);
  free (dyntext_name);
  delete jthreads_idx;
  delete cstack;
  delete cstackShowHide;
  delete mapPRid;
  delete mapPReg;
  delete mapTask;
  delete openMPdata;
  destroy_map (DbeFile *, archiveMap);
  delete[] uidHTable;
  delete uidnodes;
  delete mrecs;
  delete children_exps;
  delete loadObjs;
  delete loadObjMap;
  delete sourcesMap;
  free (first_sample_label);
  free (machinemodel);

  dataDscrs->destroy ();
  delete dataDscrs;
  pcktDscrs->destroy ();
  delete pcktDscrs;
  jthreads->destroy ();
  delete jthreads;
  gcevents->destroy ();
  delete gcevents;
  heapUnmapEvents->destroy ();
  delete heapUnmapEvents;
  frmpckts->destroy ();
  delete frmpckts;
  samples->destroy ();
  delete samples;
  delete fDataMap;
  delete vFdMap;

  for (long i = 0; i < nchunks; i++)
    delete[] chunks[i];
  delete[] chunks;
}

void
Experiment::init_cache ()
{
  if (smemHTable)
    return;
  smemHTable = new SegMem*[HTableSize];
  instHTable = new DbeInstr*[HTableSize];
  for (int i = 0; i < HTableSize; i++)
    {
      smemHTable[i] = NULL;
      instHTable[i] = NULL;
    }
  uidHTable = new UIDnode*[HTableSize];
  for (int i = 0; i < HTableSize; i++)
    uidHTable[i] = NULL;

  cstack = CallStack::getInstance (this);
  cstackShowHide = CallStack::getInstance (this);
}

void
Experiment::init ()
{
  userLabels = NULL;
  seg_items = new Vector<SegMem*>;
  maps = new PRBTree ();
  jmaps = NULL; // used by JAVA_CLASSES only
  jmidHTable = NULL;
  smemHTable = NULL;
  instHTable = NULL;
  min_thread = (uint64_t) - 1;
  max_thread = 0;
  thread_cnt = 0;
  min_lwp = (uint64_t) - 1;
  max_lwp = 0;
  lwp_cnt = 0;
  min_cpu = (uint64_t) - 1;
  max_cpu = 0;
  cpu_cnt = 0;

  commentq = new Emsgqueue (NTXT ("commentq"));
  runlogq = new Emsgqueue (NTXT ("runlogq"));
  errorq = new Emsgqueue (NTXT ("errorq"));
  warnq = new Emsgqueue (NTXT ("warnq"));
  notesq = new Emsgqueue (NTXT ("notesq"));
  pprocq = new Emsgqueue (NTXT ("pprocq"));
  ifreqq = NULL;

  metrics = new Vector<BaseMetric*>;
  tagObjs = new Vector<Vector<Histable*>*>;
  tagObjs->store (PROP_THRID, new Vector<Histable*>);
  tagObjs->store (PROP_LWPID, new Vector<Histable*>);
  tagObjs->store (PROP_CPUID, new Vector<Histable*>);
  tagObjs->store (PROP_EXPID, new Vector<Histable*>);
  sparse_threads = false;
}

void
Experiment::fini ()
{
  seg_items->destroy ();
  delete seg_items;
  delete maps;
  delete jmaps;
  delete[] smemHTable;
  delete[] instHTable;
  delete jmidHTable;
  delete commentq;
  delete runlogq;
  delete errorq;
  delete warnq;
  delete notesq;
  delete pprocq;
  if (ifreqq != NULL)
    {
      delete ifreqq;
      ifreqq = NULL;
    }

  int index;
  BaseMetric *mtr;
  Vec_loop (BaseMetric*, metrics, index, mtr)
  {
    dbeSession->drop_metric (mtr);
  }
  delete metrics;
  tagObjs->fetch (PROP_THRID)->destroy ();
  tagObjs->fetch (PROP_LWPID)->destroy ();
  tagObjs->fetch (PROP_CPUID)->destroy ();
  tagObjs->fetch (PROP_EXPID)->destroy ();
  tagObjs->destroy ();
  delete tagObjs;
}

// These are the data files which can be read in parallel
// for multiple sub-experiments.
// Postpone calling resolve_frame_info()
void
Experiment::read_experiment_data (bool read_ahead)
{

  read_frameinfo_file ();
  if (read_ahead)
    {
      resolveFrameInfo = false;
      (void) get_profile_events ();
      resolveFrameInfo = true;
    }
}

Experiment::Exp_status
Experiment::open_epilogue ()
{

  // set up mapping for tagObj(PROP_EXPID)
  (void) mapTagValue (PROP_EXPID, userExpId);

  post_process ();
  if (last_event != ZERO_TIME)
    { // if last_event is known
      StringBuilder sb;
      hrtime_t ts = last_event - exp_start_time;
      sb.sprintf (GTXT ("Experiment Ended: %ld.%09ld\nData Collection Duration: %ld.%09ld"),
		  (long) (ts / NANOSEC), (long) (ts % NANOSEC),
		  (long) (non_paused_time / NANOSEC),
		  (long) (non_paused_time % NANOSEC));
      runlogq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // Check for incomplete experiment, and inform the user
  if (status == INCOMPLETE)
    {
      if (exec_started == true)
	// experiment ended with the exec, not abnormally
	status = SUCCESS;
      else
	{
	  char * cmnt = GTXT ("*** Note: experiment was not closed");
	  commentq->append (new Emsg (CMSG_COMMENT, cmnt));
	  // runlogq->append(new Emsg(CMSG_COMMENT, cmnt));
	}
    }
  // write a descriptive header for the experiment
  write_header ();
  return status;
}

Experiment::Exp_status
Experiment::open (char *path)
{

  // Find experiment directory
  if (find_expdir (path) != SUCCESS)
    // message will have been queued and status set
    return status;

  // Get creation time for experiment
  dbe_stat_t st;
  if (dbe_stat (path, &st) == 0)
    mtime = st.st_mtime;

  // Read the warnings file
  read_warn_file ();

  // Open the log file
  read_log_file ();
  if (status == SUCCESS && last_event // last event is initialized
      && (last_event - exp_start_time) / 1000000 < tiny_threshold)
    {
      // Process "tiny_threshold" (SP_ANALYZER_DISCARD_TINY_EXPERIMENTS)
      // At this point, we've only processed log.xml.
      // Note: if an experiment terminated abnormally, last_event will not yet
      //   represent events from clock profiling and other metrics.
      //   Other events will often have timestamps after the last log.xml entry.
      discardTiny = true;
      return status;
    }
  if (status == FAILURE)
    {
      if (logFile->get_status () == ExperimentFile::EF_FAILURE)
	{
	  Emsg *m = new Emsg (CMSG_FATAL, GTXT ("*** Error: log file in experiment cannot be read"));
	  errorq->append (m);
	}
      else if (fetch_errors () == NULL)
	{
	  if (broken == 1)
	    {
	      Emsg *m = new Emsg (CMSG_FATAL, GTXT ("*** Error: log does not show target starting"));
	      errorq->append (m);
	    }
	  else
	    {
	      Emsg *m = new Emsg (CMSG_FATAL, GTXT ("*** Error: log file in experiment could not be parsed"));
	      errorq->append (m);
	    }
	}
      return status;
    }
  init_cache ();
  if (varclock != 0)
    {
      StringBuilder sb;
      sb.sprintf (
		  GTXT ("*** Warning: system has variable clock frequency, which may cause variable execution times and inaccurate conversions of cycle counts into time."));
      warnq->append (new Emsg (CMSG_WARN, sb));
    }

  // Read the notes file
  read_notes_file ();
  read_labels_file ();
  read_archives ();

  // The log file shows experiment started
  read_java_classes_file ();

  read_map_file ();

  // Dyntext file has to be processed after loadobjects file
  // as we need to be able to map (vaddr,ts) to dynamic functions.
  read_dyntext_file ();

  // Read the overview file and create samples.
  // Profiling data hasn't been read yet so we may have
  // events after the last recorded sample.
  // We'll create a fake sample to cover all those
  // events later.
  read_overview_file ();

  // Check if instruction frequency data is available
  read_ifreq_file ();

  // Check if OMP data is available
  read_omp_file ();

  return status;
}

/* XXX -- update() is a no-op now, but may be needed for auto-update */
Experiment::Exp_status
Experiment::update ()
{
  return status;
}

void
Experiment::append (LoadObject *lo)
{
  loadObjs->append (lo);
  char *obj_name = lo->get_pathname ();
  char *bname = get_basename (obj_name);
  loadObjMap->put (obj_name, lo);
  loadObjMap->put (bname, lo);
  if (lo->flags & SEG_FLAG_EXE)
    loadObjMap->put (COMP_EXE_NAME, lo);
}

void
Experiment::read_notes_file ()
{
  Emsg *m;

  // Open log file:
  char *fname = dbe_sprintf (NTXT ("%s/%s"), expt_name, SP_NOTES_FILE);
  FILE *f = fopen (fname, NTXT ("r"));
  free (fname);
  if (f == NULL)
    return;
  if (!dbeSession->is_interactive ())
    {
      m = new Emsg (CMSG_COMMENT, NTXT ("Notes:"));
      notesq->append (m);
    }

  while (1)
    {
      char str[MAXPATHLEN];
      char *e = fgets (str, ((int) sizeof (str)) - 1, f);
      if (e == NULL)
	{
	  if (!dbeSession->is_interactive ())
	    {
	      m = new Emsg (CMSG_COMMENT,
			    "============================================================");
	      notesq->append (m);
	    }
	  break;
	}
      size_t i = strlen (str);
      if (i > 0 && str[i - 1] == '\n')
	// remove trailing nl
	str[i - 1] = 0;
      m = new Emsg (CMSG_COMMENT, str);
      notesq->append (m);
    }
  (void) fclose (f);
}

int
Experiment::save_notes (char* text, bool handle_file)
{
  if (handle_file)
    {
      FILE *fnotes;
      char *fname = dbe_sprintf (NTXT ("%s/%s"), expt_name, SP_NOTES_FILE);
      fnotes = fopen (fname, NTXT ("w"));
      free (fname);
      if (fnotes != NULL)
	{
	  (void) fprintf (fnotes, NTXT ("%s"), text);
	  fclose (fnotes);
	}
      else
	return 1; // Cannot write file
    }
  notesq->clear ();
  Emsg *m = new Emsg (CMSG_COMMENT, text);
  notesq->append (m);

  return 0;
}

int
Experiment::delete_notes (bool handle_file)
{
  if (handle_file)
    {
      char *fname = dbe_sprintf (NTXT ("%s/%s"), expt_name, SP_NOTES_FILE);
      if (unlink (fname) != 0)
	{
	  free (fname);
	  return 1; // Cannot delete file
	}
      free (fname);
    }
  notesq->clear ();
  return 0;
}

int
Experiment::read_warn_file ()
{
  int local_status = SUCCESS;

  ExperimentFile *warnFile = new ExperimentFile (this, SP_WARN_FILE);
  if (warnFile == NULL)
    return FAILURE;
  if (!warnFile->open ())
    {
      delete warnFile;
      return FAILURE;
    }
  SAXParserFactory *factory = SAXParserFactory::newInstance ();
  SAXParser *saxParser = factory->newSAXParser ();
  DefaultHandler *dh = new ExperimentHandler (this);
  try
    {
      saxParser->parse ((File*) warnFile->fh, dh);
    }
  catch (SAXException *e)
    {
      // Fatal error in the parser
      StringBuilder sb;
      sb.sprintf (NTXT ("%s: %s"), SP_WARN_FILE, e->getMessage ());
      char *str = sb.toString ();
      Emsg *m = new Emsg (CMSG_FATAL, str);
      errorq->append (m);
      local_status = FAILURE;
      delete e;
    }
  delete warnFile;
  delete dh;
  delete saxParser;
  delete factory;

  return local_status;
}

int
Experiment::read_log_file ()
{
  if (logFile == NULL)
    logFile = new ExperimentFile (this, SP_LOG_FILE);
  if (!logFile->open ())
    {
      status = FAILURE;
      return status;
    }

  SAXParserFactory *factory = SAXParserFactory::newInstance ();
  SAXParser *saxParser = factory->newSAXParser ();
  DefaultHandler *dh = new ExperimentHandler (this);
  try
    {
      saxParser->parse ((File*) logFile->fh, dh);
    }
  catch (SAXException *e)
    {
      // Fatal error in the parser
      StringBuilder sb;
      if (obsolete == 1)
	sb.sprintf (NTXT ("%s"), e->getMessage ());
      else
	sb.sprintf (NTXT ("%s: %s"), SP_LOG_FILE, e->getMessage ());
      char *str = sb.toString ();
      Emsg *m = new Emsg (CMSG_FATAL, str);
      errorq->append (m);
      status = FAILURE;
      delete e;
    }
  logFile->close ();
  dbeSession->register_metric (GTXT ("IPC"), GTXT ("Instructions Per Cycle"),
			       NTXT ("insts/cycles"));
  dbeSession->register_metric (GTXT ("CPI"), GTXT ("Cycles Per Instruction"),
			       NTXT ("cycles/insts"));
  dbeSession->register_metric (GTXT ("K_IPC"),
			       GTXT ("Kernel Instructions Per Cycle"),
			       NTXT ("K_insts/K_cycles"));
  dbeSession->register_metric (GTXT ("K_CPI"),
			       GTXT ("Kernel Cycles Per Instruction"),
			       NTXT ("K_cycles/K_insts"));

  delete dh;
  delete saxParser;
  delete factory;

  return status;
}

////////////////////////////////////////////////////////////////////////////////
//  class Experiment::ExperimentLabelsHandler
//

class Experiment::ExperimentLabelsHandler : public DefaultHandler
{
public:

  ExperimentLabelsHandler (Experiment *_exp)
  {
    exp = _exp;
  }

  ~ExperimentLabelsHandler () { };
  void startDocument () { }
  void endDocument () { }
  void endElement (char * /*uri*/, char * /*localName*/, char * /*qName*/) { }
  void characters (char * /*ch*/, int /*start*/, int /*length*/) { }
  void ignorableWhitespace (char*, int, int) { }
  void error (SAXParseException * /*e*/) { }

  void startElement (char *uri, char *localName, char *qName, Attributes *attrs);

private:

  inline const char *
  s2s (const char *s)
  {
    return s ? s : "NULL";
  }

  Experiment *exp;
  char *hostname;
  hrtime_t time, tstamp;
};

void
Experiment::ExperimentLabelsHandler::startElement (char*, char*, char *qName,
						   Attributes *attrs)
{
  DEBUG_CODE if (DEBUG_SAXPARSER) dump_startElement (qName, attrs);
  if (qName == NULL || strcmp (qName, NTXT ("id")) != 0)
    return;
  char *name = NULL, *all_times = NULL, *comment = NULL, *hostName = NULL;
  long startSec = 0;
  //    long tm_zone = 0;
  hrtime_t startHrtime = (hrtime_t) 0;
  long long lbl_ts = 0;
  int relative = 0;
  timeval start_tv;
  start_tv.tv_usec = start_tv.tv_sec = 0;
  for (int i = 0, sz = attrs ? attrs->getLength () : 0; i < sz; i++)
    {
      const char *qn = attrs->getQName (i);
      const char *vl = attrs->getValue (i);
      if (strcmp (qn, NTXT ("name")) == 0)
	name = dbe_xml2str (vl);
      else if (strcmp (qn, NTXT ("cmd")) == 0)
	all_times = dbe_xml2str (vl);
      else if (strcmp (qn, NTXT ("comment")) == 0)
	comment = dbe_xml2str (vl);
      else if (strcmp (qn, NTXT ("relative")) == 0)
	relative = atoi (vl);
      else if (strcmp (qn, NTXT ("hostname")) == 0)
	hostName = dbe_xml2str (vl);
      else if (strcmp (qn, NTXT ("time")) == 0)
	startSec = atol (vl);
      else if (strcmp (qn, NTXT ("tstamp")) == 0)
	startHrtime = parseTStamp (vl);
      else if (strcmp (qn, NTXT ("lbl_ts")) == 0)
	{
	  if (*vl == '-')
	    lbl_ts = -parseTStamp (vl + 1);
	  else
	    lbl_ts = parseTStamp (vl);
	}
    }
  if (name == NULL || hostName == NULL || (all_times == NULL && comment == NULL))
    {
      free (name);
      free (hostName);
      free (all_times);
      free (comment);
      return;
    }
  UserLabel *lbl = new UserLabel (name);
  lbl->comment = comment;
  lbl->hostname = hostName;
  lbl->start_sec = startSec;
  lbl->start_hrtime = startHrtime;
  exp->userLabels->append (lbl);
  if (all_times)
    {
      lbl->all_times = all_times;
      lbl->start_tv = start_tv;
      lbl->relative = relative;
      if (relative == UserLabel::REL_TIME)
	lbl->atime = lbl_ts;
      else
	{ // relative == UserLabel::CUR_TIME
	  long long delta = 0;
	  if (exp->hostname && strcmp (lbl->hostname, exp->hostname) == 0)
	    delta = lbl_ts + (lbl->start_hrtime - exp->exp_start_time);
	  else
	    for (int i = 0; i < exp->userLabels->size (); i++)
	      {
		UserLabel *firstLbl = exp->userLabels->fetch (i);
		if (strcmp (lbl->hostname, firstLbl->hostname) == 0)
		  {
		    delta = lbl_ts + (lbl->start_hrtime - firstLbl->start_hrtime) +
			    ((long long) (firstLbl->start_sec - exp->start_sec)) * NANOSEC;
		    break;
		  }
	      }
	  lbl->atime = delta > 0 ? delta : 0;
	}
    }
}

static int
sortUserLabels (const void *a, const void *b)
{
  UserLabel *l1 = *((UserLabel **) a);
  UserLabel *l2 = *((UserLabel **) b);
  int v = dbe_strcmp (l1->name, l2->name);
  if (v != 0)
    return v;
  if (l1->atime < l2->atime)
    return -1;
  else if (l1->atime > l2->atime)
    return 1;
  if (l1->id < l2->id)
    return -1;
  else if (l1->id > l2->id)
    return 1;
  return 0;
}

static char *
append_string (char *s, char *str)
{
  if (s == NULL)
    return dbe_strdup (str);
  char *new_s = dbe_sprintf (NTXT ("%s %s"), s, str);
  free (s);
  return new_s;
}

void
Experiment::read_labels_file ()
{
  ExperimentFile *fp = new ExperimentFile (this, SP_LABELS_FILE);
  if (!fp->open ())
    {
      delete fp;
      return;
    }
  userLabels = new Vector<UserLabel*>();
  SAXParserFactory *factory = SAXParserFactory::newInstance ();
  SAXParser *saxParser = factory->newSAXParser ();
  DefaultHandler *dh = new ExperimentLabelsHandler (this);
  try
    {
      saxParser->parse ((File*) fp->fh, dh);
    }
  catch (SAXException *e)
    {
      // Fatal error in the parser
      StringBuilder sb;
      sb.sprintf (NTXT ("%s: %s"), SP_LABELS_FILE, e->getMessage ());
      char *str = sb.toString ();
      Emsg *m = new Emsg (CMSG_FATAL, str);
      errorq->append (m);
      delete e;
    }
  fp->close ();
  delete fp;
  delete dh;
  delete saxParser;
  delete factory;

  userLabels->sort (sortUserLabels);
  UserLabel::dump ("After sortUserLabels:", userLabels);
  UserLabel *ulbl = NULL;
  for (int i = 0, sz = userLabels->size (); i < sz; i++)
    {
      UserLabel *lbl = userLabels->fetch (i);
      if (ulbl == NULL)
	ulbl = new UserLabel (lbl->name);
      else if (dbe_strcmp (lbl->name, ulbl->name) != 0)
	{ // new Label
	  ulbl->register_user_label (groupId);
	  if (ulbl->expr == NULL)
	    delete ulbl;
	  ulbl = new UserLabel (lbl->name);
	}
      if (lbl->all_times)
	{
	  if (strncmp (lbl->all_times, NTXT ("start"), 5) == 0)
	    {
	      if (!ulbl->start_f)
		{
		  ulbl->start_f = true;
		  ulbl->timeStart = lbl->atime;
		}
	    }
	  else
	    { // stop
	      if (!ulbl->start_f)
		continue;
	      ulbl->all_times = append_string (ulbl->all_times, lbl->all_times);
	      ulbl->stop_f = true;
	      ulbl->timeStop = lbl->atime;
	      ulbl->gen_expr ();
	    }
	}
      if (lbl->comment != NULL)
	ulbl->comment = append_string (ulbl->comment, lbl->comment);
    }
  if (ulbl)
    {
      ulbl->register_user_label (groupId);
      if (ulbl->expr == NULL)
	delete ulbl;
    }
  Destroy (userLabels);
}

void
Experiment::read_archives ()
{
  if (founder_exp)
    return;
  char *allocated_str = NULL;
  char *nm = get_arch_name ();
  DIR *exp_dir = opendir (nm);
  if (exp_dir == NULL)
    {
      if (founder_exp == NULL)
	{
	  // Check if the user uses a subexperiment only
	  nm = dbe_sprintf (NTXT ("%s/../%s"), expt_name, SP_ARCHIVES_DIR);
	  exp_dir = opendir (nm);
	  if (exp_dir == NULL)
	    {
	      free (nm);
	      return;
	    }
	  allocated_str = nm;
	}
      else
	return;
    }

  StringBuilder sb;
  sb.append (nm);
  sb.append ('/');
  int dlen = sb.length ();
  free (allocated_str);
  archiveMap = new StringMap<DbeFile *>();

  struct dirent *entry = NULL;
  while ((entry = readdir (exp_dir)) != NULL)
    {
      char *dname = entry->d_name;
      if (dname[0] == '.'
	  && (dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0')))
	// skip links to ./ or ../
	continue;
      sb.setLength (dlen);
      sb.append (dname);
      char *fnm = sb.toString ();
      DbeFile *df = new DbeFile (fnm);
      df->set_location (fnm);
      df->filetype |= DbeFile::F_FILE;
      df->inArchive = true;
      df->experiment = this;
      archiveMap->put (dname, df);
      free (fnm);
    }
  closedir (exp_dir);
}

static char *
gen_file_name (const char *packet_name, const char *src_name)
{
  char *fnm, *bname = get_basename (packet_name);
  if (bname == packet_name)
    fnm = dbe_strdup (src_name);
  else
    fnm = dbe_sprintf ("%.*s%s", (int) (bname - packet_name),
		       packet_name, src_name);

  // convert "java.lang.Object/Integer.java" => "java/lang/Object/Integer.java"
  bname = get_basename (fnm);
  for (char *s = fnm; s < bname; s++)
    if (*s == '.')
      *s = '/';
  return fnm;
}

static char *
get_jlass_name (const char *nm)
{
  // Convert "Ljava/lang/Object;" => "java/lang/Object.class"
  if (*nm == 'L')
    {
      size_t len = strlen (nm);
      if (nm[len - 1] == ';')
	return dbe_sprintf ("%.*s.class", (int) (len - 2), nm + 1);
    }
  return dbe_strdup (nm);
}

static char *
get_jmodule_name (const char *nm)
{
  // convert "Ljava/lang/Object;" => "java.lang.Object"
  if (*nm == 'L')
    {
      size_t len = strlen (nm);
      if (nm[len - 1] == ';')
	{
	  char *mname = dbe_sprintf (NTXT ("%.*s"), (int) (len - 2), nm + 1);
	  for (char *s = mname; *s; s++)
	    if (*s == '/')
	      *s = '.';
	  return mname;
	}
    }
  return dbe_strdup (nm);
}

LoadObject *
Experiment::get_j_lo (const char *className, const char *fileName)
{
  char *class_name = get_jlass_name (className);
  Dprintf (DUMP_JCLASS_READER,
	"Experiment::get_j_lo: className='%s' class_name='%s' fileName='%s'\n",
	   STR (className), STR (class_name), STR (fileName));
  LoadObject *lo = loadObjMap->get (class_name);
  if (lo == NULL)
    {
      lo = createLoadObject (class_name, fileName);
      lo->type = LoadObject::SEG_TEXT;
      lo->mtime = (time_t) 0;
      lo->size = 0;
      lo->set_platform (Java, wsize);
      lo->dbeFile->filetype |= DbeFile::F_FILE | DbeFile::F_JAVACLASS;
      append (lo);
      Dprintf (DUMP_JCLASS_READER,
	       "Experiment::get_j_lo: creates '%s' location='%s'\n",
	       STR (lo->get_name ()), STR (lo->dbeFile->get_location (false)));
    }
  free (class_name);
  return lo;
}

Module *
Experiment::get_jclass (const char *className, const char *fileName)
{
  LoadObject *lo = get_j_lo (className, NULL);
  char *mod_name = get_jmodule_name (className);
  Module *mod = lo->find_module (mod_name);
  if (mod == NULL)
    {
      mod = dbeSession->createClassFile (mod_name);
      mod->loadobject = lo;
      if (strcmp (fileName, NTXT ("<Unknown>")) != 0)
	mod->set_file_name (gen_file_name (lo->get_pathname (), fileName));
      else
	mod->set_file_name (dbe_strdup (fileName));
      lo->append_module (mod);
      mod_name = NULL;
    }
  else if (mod->file_name && (strcmp (mod->file_name, "<Unknown>") == 0)
	   && strcmp (fileName, "<Unknown>") != 0)
    mod->set_file_name (gen_file_name (lo->get_pathname (), fileName));
  Dprintf (DUMP_JCLASS_READER,
	"Experiment::get_jclass: class_name='%s' mod_name='%s' fileName='%s'\n",
	   mod->loadobject->get_pathname (), mod->get_name (), mod->file_name);
  free (mod_name);
  return mod;
}

#define ARCH_STRLEN(s) ( ( strlen(s) + 4 ) & ~0x3 )

int
Experiment::read_java_classes_file ()
{
  char *data_file_name = dbe_sprintf (NTXT ("%s/%s"), expt_name, SP_JCLASSES_FILE);
  Data_window *dwin = new Data_window (data_file_name);
  free (data_file_name);
  if (dwin->not_opened ())
    {
      delete dwin;
      return INCOMPLETE;
    }
  dwin->need_swap_endian = need_swap_endian;
  jmaps = new PRBTree ();
  jmidHTable = new DbeCacheMap<unsigned long long, JMethod>;

  hrtime_t cur_loaded = 0;
  Module *cur_mod = NULL;
  for (int64_t offset = 0;;)
    {
      CM_Packet *cpkt = (CM_Packet*) dwin->bind (offset, sizeof (CM_Packet));
      if (cpkt == NULL)
	break;
      uint16_t v16 = (uint16_t) cpkt->tsize;
      size_t cpktsize = dwin->decode (v16);
      cpkt = (CM_Packet*) dwin->bind (offset, cpktsize);
      if ((cpkt == NULL) || (cpktsize == 0))
	{
	  char *buf = dbe_sprintf (GTXT ("archive file malformed %s"),
				   arch_name);
	  errorq->append (new Emsg (CMSG_ERROR, buf));
	  free (buf);
	  break;
	}
      v16 = (uint16_t) cpkt->type;
      v16 = dwin->decode (v16);
      switch (v16)
	{
	case ARCH_JCLASS:
	  {
	    ARCH_jclass *ajcl = (ARCH_jclass*) cpkt;
	    uint64_t class_id = dwin->decode (ajcl->class_id);
	    char *className = ((char*) ajcl) + sizeof (*ajcl);
	    char *fileName = className + ARCH_STRLEN (className);
	    Dprintf (DUMP_JCLASS_READER,
		     "read_java_classes_file: ARCH_JCLASS(Ox%x)"
		     "class_id=Ox%llx className='%s' fileName='%s' \n",
		     (int) v16, (long long) class_id, className, fileName);
	    cur_mod = NULL;
	    if (*className == 'L')
	      { // Old libcollector generated '[' (one array dimension).
		cur_mod = get_jclass (className, fileName);
		cur_loaded = dwin->decode (ajcl->tstamp);
		jmaps->insert (class_id, cur_loaded, cur_mod);
	      }
	    break;
	  }
	case ARCH_JCLASS_LOCATION:
	  {
	    ARCH_jclass_location *ajcl = (ARCH_jclass_location *) cpkt;
	    uint64_t class_id = dwin->decode (ajcl->class_id);
	    char *className = ((char*) ajcl) + sizeof (*ajcl);
	    char *fileName = className + ARCH_STRLEN (className);
	    Dprintf (DUMP_JCLASS_READER,
		     "read_java_classes_file: ARCH_JCLASS_LOCATION(Ox%x)"
		     "class_id=Ox%llx className='%s' fileName='%s' \n",
		     (int) v16, (long long) class_id, className, fileName);
	    get_j_lo (className, fileName);
	    break;
	  }
	case ARCH_JMETHOD:
	  {
	    if (cur_mod == NULL)
	      break;
	    ARCH_jmethod *ajmt = (ARCH_jmethod*) cpkt;
	    uint64_t method_id = dwin->decode (ajmt->method_id);
	    char *s_name = ((char*) ajmt) + sizeof (*ajmt);
	    char *s_signature = s_name + ARCH_STRLEN (s_name);
	    char *fullname = dbe_sprintf ("%s.%s", cur_mod->get_name (), s_name);
	    Dprintf (DUMP_JCLASS_READER,
		     "read_java_classes_file: ARCH_JMETHOD(Ox%x) "
		     "method_id=Ox%llx name='%s' signature='%s' fullname='%s'\n",
		     (int) v16, (long long) method_id, s_name,
		     s_signature, fullname);
	    JMethod *jmthd = cur_mod->find_jmethod (fullname, s_signature);
	    if (jmthd == NULL)
	      {
		jmthd = dbeSession->createJMethod ();
		jmthd->size = (unsigned) - 1; // unknown until later (maybe)
		jmthd->module = cur_mod;
		jmthd->set_signature (s_signature);
		jmthd->set_name (fullname);
		cur_mod->functions->append (jmthd);
		cur_mod->loadobject->functions->append (jmthd);
		Dprintf (DUMP_JCLASS_READER,
		    "read_java_classes_file: ARCH_JMETHOD CREATE fullname=%s\n",
			 fullname);
	      }
	    jmaps->insert (method_id, cur_loaded, jmthd);
	    free (fullname);
	    break;
	  }
	default:
	  Dprintf (DUMP_JCLASS_READER,
		   "read_java_classes_file: type=Ox%x (%d) cpktsize=%d\n",
		   (int) v16, (int) v16, (int) cpktsize);
	  break; // ignore unknown packets
	}
      offset += cpktsize;
    }
  delete dwin;
  return SUCCESS;
}

void
Experiment::read_map_file ()
{
  ExperimentFile *mapFile = new ExperimentFile (this, SP_MAP_FILE);
  if (!mapFile->open ())
    {
      delete mapFile;
      return;
    }

  SAXParserFactory *factory = SAXParserFactory::newInstance ();
  SAXParser *saxParser = factory->newSAXParser ();
  DefaultHandler *dh = new ExperimentHandler (this);
  try
    {
      saxParser->parse ((File*) mapFile->fh, dh);
    }
  catch (SAXException *e)
    {
      // Fatal error in the parser
      StringBuilder sb;
      sb.sprintf (NTXT ("%s: %s"), SP_MAP_FILE, e->getMessage ());
      char *str = sb.toString ();
      Emsg *m = new Emsg (CMSG_FATAL, str);
      errorq->append (m);
      status = FAILURE;
      free (str);
      delete e;
    }
  delete mapFile;
  delete dh;
  delete saxParser;
  delete factory;

  for (int i = 0, sz = mrecs ? mrecs->size () : 0; i < sz; i++)
    {
      MapRecord *mrec = mrecs->fetch (i);
      SegMem *smem, *sm_lo, *sm_hi;
      switch (mrec->kind)
	{
	case MapRecord::LOAD:
	  smem = new SegMem;
	  smem->base = mrec->base;
	  smem->size = mrec->size;
	  smem->load_time = mrec->ts;
	  smem->unload_time = MAX_TIME;
	  smem->obj = mrec->obj;
	  smem->set_file_offset (mrec->foff);
	  seg_items->append (smem); // add to the master list

	  // Check if the new segment overlaps other active segments
	  sm_lo = (SegMem*) maps->locate (smem->base, smem->load_time);
	  if (sm_lo && sm_lo->base + sm_lo->size > smem->base)
	    {
	      // check to see if it is a duplicate record: same address and size, and
	      if ((smem->base == sm_lo->base) && (smem->size == sm_lo->size))
		{
		  // addresses and sizes match, check name
		  if (strstr (smem->obj->get_name (), sm_lo->obj->get_name ()) != NULL
		      || strstr (sm_lo->obj->get_name (), smem->obj->get_name ()) != NULL)
		    // this is a duplicate; just move on the the next map record
		    continue;
		  fprintf (stderr,
			   GTXT ("*** Warning: Segment `%s' loaded with same address, size as `%s' [0x%llx-0x%llx]\n"),
			   smem->obj->get_name (), sm_lo->obj->get_name (),
			   sm_lo->base, sm_lo->base + sm_lo->size);
		}

	      // Not a duplicate; implicitly unload the old one
	      //     Note: implicit unloading causes high <Unknown>
	      //           when such overlapping is bogus
	      StringBuilder sb;
	      sb.sprintf (GTXT ("*** Warning: Segment %s [0x%llx-0x%llx] overlaps %s [0x%llx-0x%llx], which has been implicitly unloaded"),
			  smem->obj->get_name (), smem->base, smem->base + smem->size,
			  sm_lo->obj->get_name (), sm_lo->base, sm_lo->base + sm_lo->size);
	      warnq->append (new Emsg (CMSG_WARN, sb));
	    }

	  // now look for other segments with which this might overlap
	  sm_hi = (SegMem*) maps->locate_up (smem->base, smem->load_time);
	  while (sm_hi && sm_hi->base < smem->base + smem->size)
	    {

	      // Note: implicit unloading causes high <Unknown> when such overlapping is bogus
	      // maps->remove( sm_hi->base, smem->load_time );
	      StringBuilder sb;
	      sb.sprintf (GTXT ("*** Warning: Segment %s [0x%llx-0x%llx] overlaps %s [0x%llx-0x%llx], which has been implicitly unloaded"),
			  smem->obj->get_name (), smem->base,
			  smem->base + smem->size, sm_hi->obj->get_name (),
			  sm_hi->base, sm_hi->base + sm_hi->size);
	      warnq->append (new Emsg (CMSG_WARN, sb));
	      sm_hi = (SegMem*) maps->locate_up (sm_hi->base + sm_hi->size,
						 smem->load_time);
	    }

	  maps->insert (smem->base, smem->load_time, smem);
	  break;
	case MapRecord::UNLOAD:
	  smem = (SegMem*) maps->locate (mrec->base, mrec->ts);
	  if (smem && smem->base == mrec->base)
	    {
	      smem->unload_time = mrec->ts;
	      maps->remove (mrec->base, mrec->ts);
	    }
	  break;
	}
    }
  mrecs->destroy ();

  // See if there are comments or warnings for a load object;
  // if so, queue them to Experiment
  for (long i = 0, sz = loadObjs ? loadObjs->size () : 0; i < sz; i++)
    {
      LoadObject *lo = loadObjs->get (i);
      for (Emsg *m = lo->fetch_warnings (); m; m = m->next)
	warnq->append (m->get_warn (), m->get_msg ());
      for (Emsg *m = lo->fetch_comments (); m; m = m->next)
	commentq->append (m->get_warn (), m->get_msg ());
    }
}

void
Experiment::read_frameinfo_file ()
{
  init_cache ();
  char *base_name = get_basename (expt_name);
  char *msg = dbe_sprintf (GTXT ("Loading CallStack Data: %s"), base_name);
  read_data_file ("data." SP_FRINFO_FILE, msg);
  free (msg);
  frmpckts->sort (frUidCmp);
  uidnodes->sort (uidNodeCmp);
}

void
Experiment::read_omp_preg ()
{
  // Parallel region descriptions
  DataDescriptor *pregDdscr = getDataDescriptor (DATA_OMP4);
  if (pregDdscr == NULL)
    return;
  DataView *pregData = pregDdscr->createView ();
  pregData->sort (PROP_CPRID); // omptrace PROP_CPRID

  // OpenMP enter parreg events
  DataDescriptor *dDscr = getDataDescriptor (DATA_OMP2);
  if (dDscr == NULL || dDscr->getSize () == 0)
    {
      delete pregData;
      return;
    }

  char *idxname = NTXT ("OMP_preg");
  delete dbeSession->indxobj_define (idxname, GTXT ("OpenMP Parallel Region"),
				     NTXT ("CPRID"), NULL, NULL);
  int idxtype = dbeSession->findIndexSpaceByName (idxname);
  if (idxtype < 0)
    {
      delete pregData;
      return;
    }
  ompavail = true;

  // Pre-create parallel region with id == 0
  Histable *preg0 = dbeSession->createIndexObject (idxtype, (int64_t) 0);
  preg0->set_name (dbe_strdup (GTXT ("Implicit OpenMP Parallel Region")));

  // Take care of the progress bar
  char *msg = dbe_sprintf (GTXT ("Processing OpenMP Parallel Region Data: %s"),
  get_basename (expt_name));
  theApplication->set_progress (0, msg);
  free (msg);
  long deltaReport = 1000;
  long nextReport = 0;
  long errors_found = 0;
  Vector<Histable*> pregs;

  long size = dDscr->getSize ();
  for (long i = 0; i < size; ++i)
    {
      if (i == nextReport)
	{
	  int percent = (int) (i * 100 / size);
	  if (percent > 0)
	    theApplication->set_progress (percent, NULL);
	  nextReport += deltaReport;
	}

      uint32_t thrid = dDscr->getIntValue (PROP_THRID, i);
      hrtime_t tstamp = dDscr->getLongValue (PROP_TSTAMP, i);
      uint64_t cprid = dDscr->getLongValue (PROP_CPRID, i); // omptrace CPRID
      mapPRid->put (thrid, tstamp, cprid);

      pregs.reset ();
      /*
       * We will use 2 pointers to make sure there is no loop.
       * First pointer "curpreg" goes to the next element,
       * second pointer "curpreg_loop_control" goes to the next->next element.
       * If these pointers have the same value - there is a loop.
       */
      uint64_t curpreg_loop_control = cprid;
      Datum tval_loop_control;
      if (curpreg_loop_control != 0)
	{
	  tval_loop_control.setUINT64 (curpreg_loop_control);
	  long idx = pregData->getIdxByVals (&tval_loop_control, DataView::REL_EQ);
	  if (idx < 0)
	    curpreg_loop_control = 0;
	  else
	    curpreg_loop_control = pregData->getLongValue (PROP_PPRID, idx);
	}
      for (uint64_t curpreg = cprid; curpreg != 0;)
	{
	  Histable *val = NULL;
	  Datum tval;
	  tval.setUINT64 (curpreg);
	  long idx = pregData->getIdxByVals (&tval, DataView::REL_EQ);
	  if (idx < 0)
	    break;
	  /*
	   * Check if there is a loop
	   */
	  if (0 != curpreg_loop_control)
	    {
	      if (curpreg == curpreg_loop_control)
		{
		  errors_found++;
		  if (1 == errors_found)
		    {
		      Emsg *m = new Emsg (CMSG_WARN, GTXT ("*** Warning: circular links in OMP regions; data may not be correct."));
		      warnq->append (m);
		    }
		  break;
		}
	    }
	  uint64_t pragmapc = pregData->getLongValue (PROP_PRPC, idx);
	  DbeInstr *instr = map_Vaddr_to_PC (pragmapc, tstamp);
	  if (instr == NULL)
	    {
	      break;
	    }
	  val = instr;
	  DbeLine *dbeline = (DbeLine*) instr->convertto (Histable::LINE);
	  if (dbeline->lineno > 0)
	    {
	      if (instr->func->usrfunc)
		dbeline = dbeline->sourceFile->find_dbeline
			(instr->func->usrfunc, dbeline->lineno);
	      dbeline->set_flag (DbeLine::OMPPRAGMA);
	      val = dbeline;
	    }
	  val = dbeSession->createIndexObject (idxtype, val);
	  pregs.append (val);

	  curpreg = pregData->getLongValue (PROP_PPRID, idx);
	  /*
	   * Update curpreg_loop_control
	   */
	  if (0 != curpreg_loop_control)
	    {
	      tval_loop_control.setUINT64 (curpreg_loop_control);
	      idx = pregData->getIdxByVals
		      (&tval_loop_control, DataView::REL_EQ);
	      if (idx < 0)
		curpreg_loop_control = 0;
	      else
		{
		  curpreg_loop_control = pregData->getLongValue
			  (PROP_PPRID, idx);
		  tval_loop_control.setUINT64 (curpreg_loop_control);
		  idx = pregData->getIdxByVals
			  (&tval_loop_control, DataView::REL_EQ);
		  if (idx < 0)
		    curpreg_loop_control = 0;
		  else
		    curpreg_loop_control = pregData->getLongValue
			    (PROP_PPRID, idx);
		}
	    }
	}
      pregs.append (preg0);
      void *prstack = cstack->add_stack (&pregs);
      mapPReg->put (thrid, tstamp, prstack);
    }
  theApplication->set_progress (0, NTXT (""));
  delete pregData;
}

void
Experiment::read_omp_task ()
{
  // Task description
  DataDescriptor *taskDataDdscr = getDataDescriptor (DATA_OMP5);
  if (taskDataDdscr == NULL)
    return;

  //7035272: previously, DataView was global; now it's local...is this OK?
  DataView *taskData = taskDataDdscr->createView ();
  taskData->sort (PROP_TSKID); // omptrace PROP_TSKID

  // OpenMP enter task events
  DataDescriptor *dDscr = getDataDescriptor (DATA_OMP3);
  if (dDscr == NULL || dDscr->getSize () == 0)
    {
      delete taskData;
      return;
    }

  char *idxname = NTXT ("OMP_task");
  // delete a possible error message. Ugly.
  delete dbeSession->indxobj_define (idxname, GTXT ("OpenMP Task"), NTXT ("TSKID"), NULL, NULL);
  int idxtype = dbeSession->findIndexSpaceByName (idxname);
  if (idxtype < 0)
    {
      delete taskData;
      return;
    }
  ompavail = true;

  // Pre-create task with id == 0
  Histable *task0 = dbeSession->createIndexObject (idxtype, (int64_t) 0);
  task0->set_name (dbe_strdup (GTXT ("OpenMP Task from Implicit Parallel Region")));

  // Take care of the progress bar
  char *msg = dbe_sprintf (GTXT ("Processing OpenMP Task Data: %s"), get_basename (expt_name));
  theApplication->set_progress (0, msg);
  free (msg);
  long deltaReport = 1000;
  long nextReport = 0;

  Vector<Histable*> tasks;
  long size = dDscr->getSize ();
  long errors_found = 0;
  for (long i = 0; i < size; ++i)
    {
      if (i == nextReport)
	{
	  int percent = (int) (i * 100 / size);
	  if (percent > 0)
	    theApplication->set_progress (percent, NULL);
	  nextReport += deltaReport;
	}

      uint32_t thrid = dDscr->getIntValue (PROP_THRID, i);
      hrtime_t tstamp = dDscr->getLongValue (PROP_TSTAMP, i);
      uint64_t tskid = dDscr->getLongValue (PROP_TSKID, i); //omptrace TSKID
      tasks.reset ();
      /*
       * We will use 2 pointers to make sure there is no loop.
       * First pointer "curtsk" goes to the next element,
       * second pointer "curtsk_loop_control" goes to the next->next element.
       * If these pointers have the same value - there is a loop.
       */
      uint64_t curtsk_loop_control = tskid;
      Datum tval_loop_control;
      if (curtsk_loop_control != 0)
	{
	  tval_loop_control.setUINT64 (curtsk_loop_control);
	  long idx = taskData->getIdxByVals (&tval_loop_control, DataView::REL_EQ);
	  if (idx < 0)
	    curtsk_loop_control = 0;
	  else
	    curtsk_loop_control = taskData->getLongValue (PROP_PTSKID, idx);
	}
      for (uint64_t curtsk = tskid; curtsk != 0;)
	{
	  Histable *val = NULL;

	  Datum tval;
	  tval.setUINT64 (curtsk);
	  long idx = taskData->getIdxByVals (&tval, DataView::REL_EQ);
	  if (idx < 0)
	    break;
	  /*
	   * Check if there is a loop
	   */
	  if (0 != curtsk_loop_control)
	    {
	      if (curtsk == curtsk_loop_control)
		{
		  errors_found++;
		  if (1 == errors_found)
		    {
		      Emsg *m = new Emsg (CMSG_WARN, GTXT ("*** Warning: circular links in OMP tasks; data may not be correct."));
		      warnq->append (m);
		    }
		  break;
		}
	    }
	  uint64_t pragmapc = taskData->getLongValue (PROP_PRPC, idx);
	  DbeInstr *instr = map_Vaddr_to_PC (pragmapc, tstamp);
	  if (instr == NULL)
	    break;
	  val = instr;
	  DbeLine *dbeline = (DbeLine*) instr->convertto (Histable::LINE);
	  if (dbeline->lineno > 0)
	    {
	      if (instr->func->usrfunc)
		dbeline = dbeline->sourceFile->find_dbeline
			(instr->func->usrfunc, dbeline->lineno);
	      dbeline->set_flag (DbeLine::OMPPRAGMA);
	      val = dbeline;
	    }
	  val = dbeSession->createIndexObject (idxtype, val);
	  tasks.append (val);

	  curtsk = taskData->getLongValue (PROP_PTSKID, idx);
	  /*
	   * Update curtsk_loop_control
	   */
	  if (0 != curtsk_loop_control)
	    {
	      tval_loop_control.setUINT64 (curtsk_loop_control);
	      idx = taskData->getIdxByVals (&tval_loop_control, DataView::REL_EQ);
	      if (idx < 0)
		curtsk_loop_control = 0;
	      else
		{
		  curtsk_loop_control = taskData->getLongValue (PROP_PTSKID, idx);
		  tval_loop_control.setUINT64 (curtsk_loop_control);
		  idx = taskData->getIdxByVals (&tval_loop_control,
						DataView::REL_EQ);
		  if (idx < 0)
		    curtsk_loop_control = 0;
		  else
		    curtsk_loop_control = taskData->getLongValue (PROP_PTSKID,
								  idx);
		}
	    }
	}
      tasks.append (task0);
      void *tskstack = cstack->add_stack (&tasks);
      mapTask->put (thrid, tstamp, tskstack);
    }
  theApplication->set_progress (0, NTXT (""));
  delete taskData;
}

void
Experiment::read_omp_file ()
{
  // DATA_OMP2 table is common between OpenMP 2.5 and 3.0 profiling
  DataDescriptor *dDscr = getDataDescriptor (DATA_OMP2);
  if (dDscr == NULL)
    return;
  if (dDscr->getSize () == 0)
    {
      char *base_name = get_basename (expt_name);
      char *msg = dbe_sprintf (GTXT ("Loading OpenMP Data: %s"), base_name);
      read_data_file (SP_OMPTRACE_FILE, msg);
      free (msg);

      // OpenMP fork events
      dDscr = getDataDescriptor (DATA_OMP);
      long sz = dDscr->getSize ();
      if (sz > 0)
	{
	  // progress bar
	  msg = dbe_sprintf (GTXT ("Processing OpenMP Parallel Region Data: %s"),
			     base_name);
	  theApplication->set_progress (0, msg);
	  free (msg);
	  long deltaReport = 5000;
	  long nextReport = 0;
	  for (int i = 0; i < sz; ++i)
	    {
	      if (i == nextReport)
		{
		  int percent = (int) (i * 100 / sz);
		  if (percent > 0)
		    theApplication->set_progress (percent, NULL);
		  nextReport += deltaReport;
		}
	      uint32_t thrid = dDscr->getIntValue (PROP_THRID, i);
	      hrtime_t tstamp = dDscr->getLongValue (PROP_TSTAMP, i);
	      uint64_t cprid = dDscr->getLongValue (PROP_CPRID, i); //omptrace
	      mapPRid->put (thrid, tstamp, cprid);
	    }
	  theApplication->set_progress (0, NTXT (""));

	  ompavail = true;
	  openMPdata = dDscr->createView ();
	  openMPdata->sort (PROP_CPRID); // omptrace PROP_CPRID

	  // thread enters parreg events
	  dDscr = getDataDescriptor (DATA_OMP2);
	  sz = dDscr->getSize ();

	  // progress bar
	  msg = dbe_sprintf (GTXT ("Processing OpenMP Parallel Region Data: %s"),
			     base_name);
	  theApplication->set_progress (0, msg);
	  free (msg);
	  deltaReport = 5000;
	  nextReport = 0;

	  for (int i = 0; i < sz; ++i)
	    {
	      if (i == nextReport)
		{
		  int percent = (int) (i * 100 / sz);
		  if (percent > 0)
		    theApplication->set_progress (percent, NULL);
		  nextReport += deltaReport;
		}
	      uint32_t thrid = dDscr->getIntValue (PROP_THRID, i);
	      hrtime_t tstamp = dDscr->getLongValue (PROP_TSTAMP, i);
	      uint64_t cprid = dDscr->getLongValue (PROP_CPRID, i); //omptrace
	      mapPRid->put (thrid, tstamp, cprid);
	    }
	  theApplication->set_progress (0, NTXT (""));
	}
      else
	{
	  read_omp_preg ();
	  read_omp_task ();
	}
      if (ompavail && coll_params.profile_mode)
	{
	  dbeSession->status_ompavail = 1;
	  register_metric (Metric::OMP_WORK);
	  register_metric (Metric::OMP_WAIT);
	  register_metric (Metric::OMP_OVHD);
	  if (coll_params.lms_magic_id == LMS_MAGIC_ID_SOLARIS)
	    register_metric (Metric::OMP_MASTER_THREAD);
	}
    }
}

void
Experiment::read_ifreq_file ()
{
  char *fname = dbe_sprintf (NTXT ("%s/%s"), expt_name, SP_IFREQ_FILE);
  FILE *f = fopen (fname, NTXT ("r"));
  free (fname);
  if (f == NULL)
    {
      ifreqavail = false;
      return;
    }
  ifreqavail = true;
  ifreqq = new Emsgqueue (NTXT ("ifreqq"));

  while (1)
    {
      Emsg *m;
      char str[MAXPATHLEN];
      char *e = fgets (str, ((int) sizeof (str)) - 1, f);
      if (e == NULL)
	{
	  // end the list from the experiment
	  m = new Emsg (CMSG_COMMENT,
			GTXT ("============================================================"));
	  ifreqq->append (m);
	  break;
	}
      // get the string
      size_t i = strlen (str);
      if (i > 0 && str[i - 1] == '\n')
	// remove trailing nl
	str[i - 1] = 0;
      // and append it
      m = new Emsg (CMSG_COMMENT, str);
      ifreqq->append (m);
    }
  (void) fclose (f);
}

Experiment *
Experiment::getBaseFounder ()
{
  if (baseFounder)
    return baseFounder;
  Experiment *founder = this;
  Experiment *parent = founder->founder_exp;
  while (parent)
    {
      founder = parent;
      parent = founder->founder_exp;
    }
  baseFounder = founder;
  return baseFounder;
}

hrtime_t
Experiment::getRelativeStartTime ()
{
  if (exp_rel_start_time_set)
    return exp_rel_start_time;
  Experiment *founder = getBaseFounder ();
  hrtime_t child_start = this->getStartTime ();
  hrtime_t founder_start = founder->getStartTime ();
  exp_rel_start_time = child_start - founder_start;
  if (child_start == 0 && founder_start)
    exp_rel_start_time = 0;     // when descendents have incomplete log.xml
  exp_rel_start_time_set = true;
  return exp_rel_start_time;
}

DataDescriptor *
Experiment::get_raw_events (int data_id)
{
  DataDescriptor *dDscr;
  switch (data_id)
    {
    case DATA_CLOCK:
      dDscr = get_profile_events ();
      break;
    case DATA_SYNCH:
      dDscr = get_sync_events ();
      break;
    case DATA_HWC:
      dDscr = get_hwc_events ();
      break;
    case DATA_HEAP:
      dDscr = get_heap_events ();
      break;
    case DATA_HEAPSZ:
      dDscr = get_heapsz_events ();
      break;
    case DATA_IOTRACE:
      dDscr = get_iotrace_events ();
      break;
    case DATA_RACE:
      dDscr = get_race_events ();
      break;
    case DATA_DLCK:
      dDscr = get_deadlock_events ();
      break;
    case DATA_SAMPLE:
      dDscr = get_sample_events ();
      break;
    case DATA_GCEVENT:
      dDscr = get_gc_events ();
      break;
    default:
      dDscr = NULL;
      break;
    }
  return dDscr;
}

int
Experiment::base_data_id (int data_id)
{
  switch (data_id)
    {
    case DATA_HEAPSZ:
      return DATA_HEAP; // DATA_HEAPSZ DataView is based on DATA_HEAP's DataView
    default:
      break;
    }
  return data_id;
}

DataView *
Experiment::create_derived_data_view (int data_id, DataView *dview)
{
  // dview contains filtered packets
  switch (data_id)
    {
    case DATA_HEAPSZ:
      return create_heapsz_data_view (dview);
    default:
      break;
    }
  return NULL;
}

DataDescriptor *
Experiment::get_profile_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_CLOCK);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () == 0)
    {
      char *base_name = get_basename (expt_name);
      char *msg = dbe_sprintf (GTXT ("Loading Profile Data: %s"), base_name);
      read_data_file (SP_PROFILE_FILE, msg);
      free (msg);
      add_evt_time_to_profile_events (dDscr);
      resolve_frame_info (dDscr);
    }
  else if (!dDscr->isResolveFrInfoDone ())
    resolve_frame_info (dDscr);
  return dDscr;
}

void
Experiment::add_evt_time_to_profile_events (DataDescriptor *dDscr)
{
  if (coll_params.lms_magic_id != LMS_MAGIC_ID_SOLARIS)
    return;

  DataView *dview = dDscr->createView ();
  dview->sort (PROP_THRID, PROP_TSTAMP);

  // add PROP_EVT_TIME
  PropDescr* tmp_propDscr = new PropDescr (PROP_EVT_TIME, "EVT_TIME");
  tmp_propDscr->uname = dbe_strdup (GTXT ("Event duration"));
  tmp_propDscr->vtype = TYPE_INT64;
  dDscr->addProperty (tmp_propDscr);

  long sz = dview->getSize ();
  long long ptimer_usec = get_params ()->ptimer_usec;
  for (long i = 0; i < sz; i++)
    {
      int next_sample;
      int jj;
      {
	hrtime_t this_tstamp = dview->getLongValue (PROP_TSTAMP, i);
	long this_thrid = dview->getLongValue (PROP_THRID, i);
	for (jj = i + 1; jj < sz; jj++)
	  {
	    hrtime_t tmp_tstamp = dview->getLongValue (PROP_TSTAMP, jj);
	    if (tmp_tstamp != this_tstamp)
	      break;
	    long tmp_thrid = dview->getLongValue (PROP_THRID, jj);
	    if (tmp_thrid != this_thrid)
	      break;
	  }
	next_sample = jj;
      }

      long nticks = 0;
      for (jj = i; jj < next_sample; jj++)
	nticks += dview->getLongValue (PROP_NTICK, jj);
      if (nticks <= 1)
	continue; // no duration

      nticks--;
      hrtime_t duration = ptimer_usec * 1000LL * nticks; // nanoseconds
      for (jj = i; jj < next_sample; jj++)
	dview->setValue (PROP_EVT_TIME, jj, duration);
      i = jj - 1;
    }
  delete dview;
}

DataDescriptor *
Experiment::get_sync_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_SYNCH);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () > 0)
    return dDscr;

  // fetch data
  {
    char *base_name = get_basename (expt_name);
    char *msg = dbe_sprintf (GTXT ("Loading Synctrace Data: %s"), base_name);
    read_data_file (SP_SYNCTRACE_FILE, msg);
    free (msg);
    resolve_frame_info (dDscr);
  }

  // check for PROP_EVT_TIME
  PropDescr *tmp_propDscr = dDscr->getProp (PROP_EVT_TIME);
  if (tmp_propDscr)
    return dDscr;

  // add PROP_EVT_TIME
  tmp_propDscr = new PropDescr (PROP_EVT_TIME, "EVT_TIME");
  tmp_propDscr->uname = dbe_strdup (GTXT ("Event duration"));
  tmp_propDscr->vtype = TYPE_INT64;
  dDscr->addProperty (tmp_propDscr);

  long sz = dDscr->getSize ();
  for (long i = 0; i < sz; i++)
    {
      uint64_t event_duration = dDscr->getLongValue (PROP_TSTAMP, i);
      event_duration -= dDscr->getLongValue (PROP_SRQST, i);
      dDscr->setValue (PROP_EVT_TIME, i, event_duration);
    }
  return dDscr;
}

DataDescriptor *
Experiment::get_hwc_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_HWC);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () == 0)
    {
      char *base_name = get_basename (expt_name);
      char *msg = dbe_sprintf (GTXT ("Loading HW Profile Data: %s"), base_name);

      // clear HWC event stats
      dsevents = 0;
      dsnoxhwcevents = 0;
      read_data_file (SP_HWCNTR_FILE, msg);
      free (msg);
      resolve_frame_info (dDscr);

      // describe the HW counters in PropDescr
      PropDescr *prop = dDscr->getProp (PROP_HWCTAG);
      if (prop)
	{
	  Collection_params *cparam = get_params ();
	  if (cparam->hw_mode != 0)
	    for (int aux = 0; aux < MAX_HWCOUNT; aux++)
	      if (cparam->hw_aux_name[aux])
		{
		  const char* cmdname = cparam->hw_aux_name[aux];
		  const char* uname = cparam->hw_username[aux];
		  prop->addState (aux, cmdname, uname);
		}
	}
      else
	assert (0);

      double dserrrate = 100.0 * ((double) dsnoxhwcevents) / ((double) dsevents);
      if ((dsevents > 0) && (dserrrate > 10.0))
	{
	  // warn the user that rate is high
	  StringBuilder sb;
	  if (dbeSession->check_ignore_no_xhwcprof ())
	    sb.sprintf (
			GTXT ("Warning: experiment %s has %.1f%%%% (%lld of %lld) dataspace events that were accepted\n  without verification; data may be incorrect or misleading\n  recompile with -xhwcprof and rerecord to get better data\n"),
			base_name, dserrrate, (long long) dsnoxhwcevents,
			(long long) dsevents);
	  else
	    sb.sprintf (
			GTXT ("Warning: experiment %s has %.1f%%%% (%lld of %lld) dataspace events that could not be verified\n  recompile with -xhwcprof and rerecord to get better data\n"),
			base_name, dserrrate, (long long) dsnoxhwcevents,
			(long long) dsevents);
	  errorq->append (new Emsg (CMSG_WARN, sb));
	}

      // see if we've scanned the data
      if (hwc_scanned == 0)
	{
	  // no, scan the packets to see how many are bogus, or represent lost interrupts
	  long hwc_cnt = 0;

	  // loop over the packets, counting the bad ones
	  if (hwc_bogus != 0 || hwc_lost_int != 0)
	    {
	      // hwc counter data had bogus packets and/or packets reflecting lost interrupts
	      double bogus_rate = 100. * (double) hwc_bogus / (double) hwc_cnt;
	      if (bogus_rate > 5.)
		{
		  StringBuilder sb;
		  sb.sprintf (
			      GTXT ("WARNING: Too many invalid HW counter profile events (%ld/%ld = %3.2f%%) in experiment %d (`%s'); data may be unreliable"),
			      (long) hwc_bogus, (long) hwc_cnt, bogus_rate,
			      (int) userExpId, base_name);
		  Emsg *m = new Emsg (CMSG_WARN, sb);
		  warnq->append (m);
		}
	      hwc_scanned = 1;
	    }
	}
    }
  return dDscr;
}

DataDescriptor *
Experiment::get_iotrace_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_IOTRACE);
  if (dDscr == NULL)
    return NULL;

  if (dDscr->getSize () > 0)
    return dDscr;

  char *base_name = get_basename (expt_name);
  char *msg = dbe_sprintf (GTXT ("Loading IO Trace Data: %s"), base_name);
  read_data_file (SP_IOTRACE_FILE, msg);
  free (msg);

  if (dDscr->getSize () == 0)
    return dDscr;
  resolve_frame_info (dDscr);

  // check for PROP_EVT_TIME
  PropDescr *tmp_propDscr = dDscr->getProp (PROP_EVT_TIME);
  if (tmp_propDscr)
    return dDscr;

  // add PROP_EVT_TIME
  tmp_propDscr = new PropDescr (PROP_EVT_TIME, "EVT_TIME");
  tmp_propDscr->uname = dbe_strdup (GTXT ("Event duration"));
  tmp_propDscr->vtype = TYPE_INT64;
  dDscr->addProperty (tmp_propDscr);

  // add PROP_IOVFD
  tmp_propDscr = new PropDescr (PROP_IOVFD, "IOVFD");
  tmp_propDscr->uname = dbe_strdup (GTXT ("Virtual File Descriptor"));
  tmp_propDscr->vtype = TYPE_INT64;
  dDscr->addProperty (tmp_propDscr);

  delete fDataMap;
  fDataMap = new DefaultMap<int64_t, FileData*>;

  delete vFdMap;
  vFdMap = new DefaultMap<int, int64_t>;

  static int64_t virtualFd = 0;

  FileData *fData;
  virtualFd += 10;
  fData = fDataMap->get (VIRTUAL_FD_STDIN);
  if (fData == NULL)
    {
      fData = new FileData (STDIN_FILENAME);
      fData->setVirtualFd (VIRTUAL_FD_STDIN);
      fData->id = VIRTUAL_FD_STDIN;
      fData->setFileDes (STDIN_FD);
      fDataMap->put (VIRTUAL_FD_STDIN, fData);
      vFdMap->put (STDIN_FD, VIRTUAL_FD_STDIN);
    }

  fData = fDataMap->get (VIRTUAL_FD_STDOUT);
  if (fData == NULL)
    {
      fData = new FileData (STDOUT_FILENAME);
      fData->setVirtualFd (VIRTUAL_FD_STDOUT);
      fData->id = VIRTUAL_FD_STDOUT;
      fData->setFileDes (STDOUT_FD);
      fDataMap->put (VIRTUAL_FD_STDOUT, fData);
      vFdMap->put (STDOUT_FD, VIRTUAL_FD_STDOUT);
    }

  fData = fDataMap->get (VIRTUAL_FD_STDERR);
  if (fData == NULL)
    {
      fData = new FileData (STDERR_FILENAME);
      fData->setVirtualFd (VIRTUAL_FD_STDERR);
      fData->id = VIRTUAL_FD_STDERR;
      fData->setFileDes (STDERR_FD);
      fDataMap->put (VIRTUAL_FD_STDERR, fData);
      vFdMap->put (STDERR_FD, VIRTUAL_FD_STDERR);
    }

  fData = fDataMap->get (VIRTUAL_FD_OTHERIO);
  if (fData == NULL)
    {
      fData = new FileData (OTHERIO_FILENAME);
      fData->setVirtualFd (VIRTUAL_FD_OTHERIO);
      fData->id = VIRTUAL_FD_OTHERIO;
      fData->setFileDes (OTHERIO_FD);
      fDataMap->put (VIRTUAL_FD_OTHERIO, fData);
    }

  DataView *dview = dDscr->createView ();
  dview->sort (PROP_TSTAMP);
  long sz = dview->getSize ();
  for (long i = 0; i < sz; i++)
    {
      hrtime_t event_duration = dview->getLongValue (PROP_TSTAMP, i);
      hrtime_t event_start = dview->getLongValue (PROP_IORQST, i);
      if (event_start > 0)
	event_duration -= event_start;
      else
	event_duration = 0;
      dview->setValue (PROP_EVT_TIME, i, event_duration);

      int32_t fd = -1;
      int64_t vFd = VIRTUAL_FD_NONE;
      char *fName = NULL;
      int32_t origFd = -1;
      StringBuilder *sb = NULL;
      FileData *fDataOrig = NULL;
      FileSystem_type fsType;

      IOTrace_type ioType = (IOTrace_type) dview->getIntValue (PROP_IOTYPE, i);
      switch (ioType)
	{
	case READ_TRACE:
	case WRITE_TRACE:
	case READ_TRACE_ERROR:
	case WRITE_TRACE_ERROR:
	  fd = dview->getIntValue (PROP_IOFD, i);
	  vFd = vFdMap->get (fd);
	  if (vFd == 0 || vFd == VIRTUAL_FD_NONE
	      || (fData = fDataMap->get (vFd)) == NULL)
	    {
	      fData = new FileData (UNKNOWNFD_FILENAME);
	      fData->setVirtualFd (virtualFd);
	      fData->setFsType ("N/A");
	      fData->setFileDes (fd);
	      fDataMap->put (virtualFd, fData);
	      vFdMap->put (fd, virtualFd);
	      vFd = virtualFd;
	      virtualFd++;
	    }
	  dview->setValue (PROP_IOVFD, i, vFd);
	  break;
	case OPEN_TRACE:
	  fName = NULL;
	  sb = (StringBuilder*) dview->getObjValue (PROP_IOFNAME, i);
	  if (sb != NULL && sb->length () > 0)
	    fName = sb->toString ();
	  fd = dview->getIntValue (PROP_IOFD, i);
	  origFd = dview->getIntValue (PROP_IOOFD, i);
	  fsType = (FileSystem_type) dview->getIntValue (PROP_IOFSTYPE, i);

	  if (fName != NULL)
	    {
	      fData = new FileData (fName);
	      fDataMap->put (virtualFd, fData);
	      vFdMap->put (fd, virtualFd);
	      fData->setFileDes (fd);
	      fData->setFsType (fsType);
	      fData->setVirtualFd (virtualFd);
	      vFd = virtualFd;
	      virtualFd++;
	    }
	  else if (origFd > 0)
	    {
	      vFd = vFdMap->get (origFd);
	      if (vFd == 0 || vFd == VIRTUAL_FD_NONE)
		{
		  Dprintf (DEBUG_IO,
			   "*** Error I/O tracing: (open) cannot get the virtual file descriptor, fd=%d  origFd=%d\n",
			   fd, origFd);
		  continue;
		}
	      else if ((fDataOrig = fDataMap->get (vFd)) == NULL)
		{
		  Dprintf (DEBUG_IO,
			   "*** Error IO tracing: (open) cannot get original FileData object, fd=%d  origFd=%d\n",
			   fd, origFd);
		  continue;
		}
	      else
		{
		  fName = fDataOrig->getFileName ();
		  fData = new FileData (fName);
		  fData->setFileDes (fd);
		  fData->setFsType (fDataOrig->getFsType ());
		  fData->setVirtualFd (virtualFd);
		  fDataMap->put (virtualFd, fData);
		  vFdMap->put (fd, virtualFd);
		  vFd = virtualFd;
		  virtualFd++;
		}
	    }
	  else if (fd >= 0)
	    {
	      vFd = vFdMap->get (fd);
	      if (vFd == 0 || vFd == VIRTUAL_FD_NONE
		  || (fData = fDataMap->get (vFd)) == NULL)
		{
		  fData = new FileData (UNKNOWNFD_FILENAME);
		  fData->setVirtualFd (virtualFd);
		  fData->setFsType ("N/A");
		  fData->setFileDes (fd);
		  fDataMap->put (virtualFd, fData);
		  vFdMap->put (fd, virtualFd);
		  vFd = virtualFd;
		  virtualFd++;
		}
	    }
	  else
	    {
	      Dprintf (DEBUG_IO,
		       NTXT ("*** Error IO tracing: (open) unknown open IO type, fd=%d  origFd=%d\n"), fd, origFd);
	      continue;
	    }

	  dview->setValue (PROP_IOVFD, i, vFd);
	  break;

	case OPEN_TRACE_ERROR:
	  fName = NULL;

	  sb = (StringBuilder*) dview->getObjValue (PROP_IOFNAME, i);
	  if (sb != NULL && sb->length () > 0)
	    fName = sb->toString ();
	  fd = dview->getIntValue (PROP_IOFD, i);
	  origFd = dview->getIntValue (PROP_IOOFD, i);
	  fsType = (FileSystem_type) dview->getIntValue (PROP_IOFSTYPE, i);

	  if (fName != NULL)
	    {
	      fData = new FileData (fName);
	      fDataMap->put (virtualFd, fData);
	      fData->setFileDes (fd);
	      fData->setFsType (fsType);
	      fData->setVirtualFd (virtualFd);
	      vFd = virtualFd;
	      virtualFd++;
	    }
	  else if (origFd > 0)
	    {
	      vFd = vFdMap->get (origFd);
	      if (vFd == 0 || vFd == VIRTUAL_FD_NONE)
		{
		  Dprintf (DEBUG_IO,
			   "*** Error IO tracing: (open error) cannot get the virtual file descriptor, fd=%d  origFd=%d\n",
			   fd, origFd);
		  continue;
		}
	      else if ((fDataOrig = fDataMap->get (vFd)) == NULL)
		{
		  Dprintf (DEBUG_IO,
			   "*** Error IO tracing: (open error) cannot get original FileData object, fd=%d  origFd=%d\n",
			   fd, origFd);
		  continue;
		}
	      else
		{
		  fName = fDataOrig->getFileName ();
		  fData = new FileData (fName);
		  fData->setFileDes (fd);
		  fData->setFsType (fDataOrig->getFsType ());
		  fData->setVirtualFd (virtualFd);
		  fDataMap->put (virtualFd, fData);
		  vFd = virtualFd;
		  virtualFd++;
		}
	    }

	  dview->setValue (PROP_IOVFD, i, vFd);
	  break;

	case CLOSE_TRACE:
	case CLOSE_TRACE_ERROR:
	  fd = dview->getIntValue (PROP_IOFD, i);
	  vFd = vFdMap->get (fd);
	  if (vFd == 0 || vFd == VIRTUAL_FD_NONE)
	    {
	      Dprintf (DEBUG_IO,
		       "*** Error IO tracing: (close) cannot get the virtual file descriptor, fd=%d\n",
		       fd);
	      continue;
	    }
	  fData = fDataMap->get (vFd);
	  if (fData == NULL)
	    {
	      Dprintf (DEBUG_IO,
		       "*** Error IO tracing: (close) cannot get the FileData object, fd=%d\n",
		       fd);
	      continue;
	    }

	  vFdMap->put (fd, VIRTUAL_FD_NONE);
	  dview->setValue (PROP_IOVFD, i, vFd);
	  break;

	case OTHERIO_TRACE:
	case OTHERIO_TRACE_ERROR:
	  vFd = VIRTUAL_FD_OTHERIO;
	  fData = fDataMap->get (vFd);
	  if (fData == NULL)
	    {
	      Dprintf (DEBUG_IO,
		       "*** Error IO tracing: (other IO) cannot get the FileData object\n");
	      continue;
	    }

	  dview->setValue (PROP_IOVFD, i, vFd);
	  break;
	case IOTRACETYPE_LAST:
	  break;
	}
    }

  delete dview;

  return dDscr;
}

DataDescriptor *
Experiment::get_heap_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_HEAP);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () > 0)
    return dDscr;

  char *base_name = get_basename (expt_name);
  char *msg = dbe_sprintf (GTXT ("Loading Heap Trace Data: %s"), base_name);
  read_data_file (SP_HEAPTRACE_FILE, msg);
  free (msg);

  if (dDscr->getSize () == 0)
    return dDscr;
  resolve_frame_info (dDscr);

  // Match FREE to MALLOC
  PropDescr *prop = new PropDescr (PROP_HLEAKED, NTXT ("HLEAKED"));
  prop->uname = dbe_strdup (GTXT ("Bytes Leaked"));
  prop->vtype = TYPE_UINT64;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_HMEM_USAGE, NTXT ("HMEM_USAGE"));
  prop->uname = dbe_strdup (GTXT ("Heap Memory Usage"));
  prop->vtype = TYPE_UINT64;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_HFREED, NTXT ("HFREED"));
  prop->uname = dbe_strdup (GTXT ("Bytes Freed"));
  prop->vtype = TYPE_UINT64;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_HCUR_ALLOCS, NTXT ("HCUR_ALLOCS"));
  prop->uname = dbe_strdup (GTXT ("Net Bytes Allocated"));
  prop->vtype = TYPE_INT64;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_HCUR_LEAKS, NTXT ("HCUR_LEAKS"));
  prop->uname = dbe_strdup (GTXT ("Net Bytes Leaked"));
  prop->vtype = TYPE_UINT64;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_HCUR_NET_ALLOC, NTXT ("HCUR_NET_ALLOC"));
  prop->vtype = TYPE_INT64;
  prop->flags = DDFLAG_NOSHOW;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_DDSCR_LNK, NTXT ("DDSCR_LNK"));
  prop->vtype = TYPE_UINT64;
  prop->flags = DDFLAG_NOSHOW;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_VOIDP_OBJ, NTXT ("VOIDP_OBJ"));
  prop->vtype = TYPE_OBJ;
  prop->flags = DDFLAG_NOSHOW;
  dDscr->addProperty (prop);

  prop = new PropDescr (PROP_TSTAMP2, NTXT ("TSTAMP2"));
  prop->uname = dbe_strdup (GTXT ("End Timestamp (nanoseconds)"));
  prop->vtype = TYPE_UINT64;
  prop->flags = DDFLAG_NOSHOW;
  dDscr->addProperty (prop);

  DataView *dview = dDscr->createView ();
  dview->sort (PROP_TSTAMP);

  // Keep track of memory usage
  Size memoryUsage = 0;

  HeapMap *heapmap = new HeapMap ();
  long sz = dview->getSize ();
  for (long i = 0; i < sz; i++)
    {

      Heap_type mtype = (Heap_type) dview->getIntValue (PROP_HTYPE, i);
      Vaddr vaddr = dview->getULongValue (PROP_HVADDR, i);
      Vaddr ovaddr = dview->getULongValue (PROP_HOVADDR, i);
      Size hsize = dview->getULongValue (PROP_HSIZE, i);
      hrtime_t tstamp = dview->getLongValue (PROP_TSTAMP, i);

      switch (mtype)
	{
	case MALLOC_TRACE:
	  dview->setValue (PROP_TSTAMP2, i, (uint64_t) MAX_TIME);
	  if (vaddr)
	    {
	      dview->setValue (PROP_HLEAKED, i, hsize);
	      heapmap->allocate (vaddr, i + 1);

	      // Increase heap size
	      memoryUsage += hsize;
	      dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);
	    }
	  break;

	case FREE_TRACE:
	  if (vaddr)
	    {
	      long idx = heapmap->deallocate (vaddr) - 1;
	      if (idx >= 0)
		{
		  // Decrease heap size
		  Size leaked = dview->getLongValue (PROP_HLEAKED, idx);
		  memoryUsage -= leaked;
		  dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);

		  Size alloc = dview->getLongValue (PROP_HSIZE, idx);
		  // update allocation
		  dview->setValue (PROP_HLEAKED, idx, (uint64_t) 0);
		  dview->setValue (PROP_TSTAMP2, idx, tstamp);
		  dview->setValue (PROP_DDSCR_LNK, idx, dview->getIdByIdx (i) + 1);
		  // update this event
		  dview->setValue (PROP_HFREED, i, alloc);
		}
	    }
	  break;

	case REALLOC_TRACE:
	  dview->setValue (PROP_TSTAMP2, i, (uint64_t) MAX_TIME);
	  if (ovaddr)
	    {
	      long idx = heapmap->deallocate (ovaddr) - 1;
	      if (idx >= 0)
		{
		  // Decrease heap size
		  Size leaked = dview->getLongValue (PROP_HLEAKED, idx);
		  memoryUsage -= leaked;
		  dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);

		  Size alloc = dview->getLongValue (PROP_HSIZE, idx);
		  // update allocation
		  dview->setValue (PROP_HLEAKED, idx, (uint64_t) 0);
		  dview->setValue (PROP_TSTAMP2, idx, tstamp);
		  dview->setValue (PROP_DDSCR_LNK, idx, dview->getIdByIdx (i) + 1);
		  // update this event
		  dview->setValue (PROP_HFREED, i, alloc);
		}
	    }
	  if (vaddr)
	    {
	      dview->setValue (PROP_HLEAKED, i, hsize);
	      heapmap->allocate (vaddr, i + 1);

	      // Increase heap size
	      memoryUsage += hsize;
	      dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);
	    }
	  break;
	case MMAP_TRACE:
	case MUNMAP_TRACE:
	  // Adjust the size to be multiple of page_size
	  //hsize = (( hsize - 1 ) / page_size + 1 ) * page_size;
	  if (vaddr)
	    {
	      UnmapChunk *list;
	      if (mtype == MMAP_TRACE)
		{
		  dview->setValue (PROP_TSTAMP2, i, (uint64_t) MAX_TIME);
		  dview->setValue (PROP_HLEAKED, i, hsize);
		  list = heapmap->mmap (vaddr, hsize, i);

		  // Increase heap size
		  memoryUsage += hsize;
		  dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);
		}
	      else
		{ // MUNMAP_TRACE
		  list = heapmap->munmap (vaddr, hsize);

		  // Set allocation size to zero
		  // Note: We're currently reusing PROP_HSIZE to mean allocation size
		  // If we ever need to save the original HSIZE, we'll need to
		  // create a new PROP_* to represent event allocation size
		  //
		  //	For now, tuck the original size away as HOVADDR
		  dview->setValue (PROP_HOVADDR, i, (uint64_t) hsize);
		  dview->setValue (PROP_HSIZE, i, (uint64_t) 0);
		}
	      Size total_freed = 0;
	      while (list)
		{
		  long idx = list->val;
		  total_freed += list->size;
		  Size leaked = dview->getLongValue (PROP_HLEAKED, idx);

		  // Decrease heap size
		  memoryUsage -= list->size;
		  dview->setValue (PROP_HMEM_USAGE, i, memoryUsage);

		  Size leak_update = leaked - list->size;
		  // update allocation
		  dview->setValue (PROP_HLEAKED, idx, leak_update);
		  // update allocation's list of frees
		  {
		    UnmapChunk *copy = new UnmapChunk;
		    heapUnmapEvents->append (copy);
		    copy->val = dview->getIdByIdx (i);
		    copy->size = list->size;
		    copy->next = (UnmapChunk *) dview->getObjValue (PROP_VOIDP_OBJ, idx);
		    dview->setObjValue (PROP_VOIDP_OBJ, idx, copy);
		  }
		  if (leak_update <= 0)
		    if (leak_update == 0)
		      dview->setValue (PROP_TSTAMP2, idx, tstamp);
		  UnmapChunk *t = list;
		  list = list->next;
		  delete t;
		}
	      // update this event
	      if (total_freed)
		// only need to write value if it is non-zero
		dview->setValue (PROP_HFREED, i, total_freed);
	    }
	  break;
	  // ignoring HEAPTYPE_LAST, which will never be recorded
	case HEAPTYPE_LAST:
	  break;
	}
    }
  delete heapmap;
  delete dview;

  return dDscr;
}

DataDescriptor *
Experiment::get_heapsz_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_HEAPSZ);
  if (dDscr)
    return dDscr;
  dDscr = get_heap_events (); // derived from DATA_HEAP
  if (dDscr == NULL)
    return NULL;
  dDscr = newDataDescriptor (DATA_HEAPSZ, 0, dDscr);
  return dDscr;
}

static void
update_heapsz_packet (std::set<long> &pkt_id_set, DataView *dview,
		      long alloc_pkt_id, int64_t net_alloc, uint64_t leaks)
{
  // pkt_id_set: set is updated to include packet
  // alloc_pkt_id: data descriptor id (NOT dview idx)
  // net_alloc: adjustment to net allocation for this packet (note: signed value)
  // leaks: leak bytes to attribute to alloc_pkt_id
  std::pair < std::set<long>::iterator, bool> ret;
  ret = pkt_id_set.insert (alloc_pkt_id); // add to set
  bool new_to_set = ret.second; // was not in set
  if (!new_to_set)
    {
      // Has been seen before, update values
      net_alloc += dview->getDataDescriptorValue (PROP_HCUR_NET_ALLOC, alloc_pkt_id);
      if (leaks)
	{
	  uint64_t old = dview->getDataDescriptorValue (PROP_HCUR_LEAKS, alloc_pkt_id);
	  if (old != 0)
	    leaks = old;
	}
    }
  dview->setDataDescriptorValue (PROP_HCUR_NET_ALLOC, alloc_pkt_id, net_alloc);
  dview->setDataDescriptorValue (PROP_HCUR_LEAKS, alloc_pkt_id, leaks);
}

DataView *
Experiment::create_heapsz_data_view (DataView *heap_dview)
{
  // heap_dview has DATA_HEAP _filtered_ packets.
  // This creates, populates, and returns DATA_HEAPSZ DataView
  DataDescriptor *dDscr = get_heapsz_events ();
  if (dDscr == NULL)
    return NULL;
  std::set<long> pkt_id_set;
  DataView *dview = heap_dview;
  long sz = dview->getSize ();
  for (long i = 0; i < sz; i++)
    {
      int64_t hsize = (int64_t) dview->getULongValue (PROP_HSIZE, i);
      uint64_t leaks = dview->getULongValue (PROP_HLEAKED, i);
      long alloc_pkt_id = dview->getIdByIdx (i);
      update_heapsz_packet (pkt_id_set, dview, alloc_pkt_id, hsize, leaks);

      // linked free
      UnmapChunk *mmap_frees = (UnmapChunk *) dview->getObjValue (PROP_VOIDP_OBJ, i); // mmap metadata
      if (mmap_frees)
	{
	  // mmap: all frees associated with this packet
	  while (mmap_frees)
	    {
	      long free_pkt_id = mmap_frees->val;
	      int64_t free_sz = mmap_frees->size;
	      update_heapsz_packet (pkt_id_set, dview, free_pkt_id, -free_sz, 0);
	      mmap_frees = mmap_frees->next;
	    }
	}
      else
	{
	  // malloc: check for associated free
	  long free_pkt_id = dview->getLongValue (PROP_DDSCR_LNK, i) - 1;
	  if (free_pkt_id >= 0)
	    update_heapsz_packet (pkt_id_set, dview, free_pkt_id, -hsize, 0);
	}
    }

  // create a new DataView based on the filtered-in and associated free events
  std::set<long>::iterator it;
  DataView *heapsz_dview = dDscr->createExtManagedView ();
  for (it = pkt_id_set.begin (); it != pkt_id_set.end (); ++it)
    {
      long ddscr_pkt_id = *it;
      heapsz_dview->appendDataDescriptorId (ddscr_pkt_id);
    }
  compute_heapsz_data_view (heapsz_dview);
  return heapsz_dview;
}

void
Experiment::compute_heapsz_data_view (DataView *heapsz_dview)
{
  DataView *dview = heapsz_dview;

  // Keep track of memory usage
  int64_t currentAllocs = 0;
  Size currentLeaks = 0;
  dview->sort (PROP_TSTAMP);
  long sz = dview->getSize ();
  for (long i = 0; i < sz; i++)
    {
      int64_t net_alloc = dview->getLongValue (PROP_HCUR_NET_ALLOC, i);
      currentAllocs += net_alloc;
      dview->setValue (PROP_HCUR_ALLOCS, i, currentAllocs);

      Size leaks = dview->getULongValue (PROP_HCUR_LEAKS, i);
      currentLeaks += leaks;
      dview->setValue (PROP_HCUR_LEAKS, i, currentLeaks);
    }
}

void
Experiment::DBG_memuse (Sample * s)
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_HEAP);
  if (dDscr == NULL || dDscr->getSize () == 0)
    return;

  DataView *dview = dDscr->createView ();
  dview->sort (PROP_TSTAMP);
  hrtime_t ts1 = s->get_start_time ();
  hrtime_t ts2 = s->get_end_time ();

  HeapMap *heapmap = new HeapMap ();
  long sz = dview->getSize ();
  Size maxSize = 0;
  Size curSize = 0;
  hrtime_t maxTime = 0;
  for (long i = 0; i < sz; i++)
    {
      hrtime_t tstamp = dview->getLongValue (PROP_TSTAMP, i);
      if (tstamp < ts1)
	continue;
      if (tstamp >= ts2)
	break;

      Heap_type mtype = (Heap_type) dview->getIntValue (PROP_HTYPE, i);
      Vaddr vaddr = dview->getULongValue (PROP_HVADDR, i);
      Vaddr ovaddr = dview->getULongValue (PROP_HOVADDR, i);
      switch (mtype)
	{
	case REALLOC_TRACE:
	  break;
	case MALLOC_TRACE:
	  ovaddr = 0;
	  break;
	case FREE_TRACE:
	  ovaddr = vaddr;
	  vaddr = 0;
	  break;
	default:
	  vaddr = 0;
	  ovaddr = 0;
	  break;
	}
      if (ovaddr)
	{
	  long idx = heapmap->deallocate (ovaddr) - 1;
	  if (idx >= 0)
	    curSize -= dview->getULongValue (PROP_HSIZE, idx);
	}
      if (vaddr)
	{
	  heapmap->allocate (vaddr, i + 1);
	  curSize += dview->getULongValue (PROP_HSIZE, i);
	  if (curSize > maxSize)
	    {
	      maxSize = curSize;
	      maxTime = tstamp;
	    }
	}
    }
  printf ("SAMPLE=%s (id=%d) MEMUSE=%lld TSTAMP=%lld\n", s->get_start_label (),
	  s->get_number (), maxSize, maxTime - getStartTime ());
  delete dview;
  delete heapmap;
}

void
Experiment::DBG_memuse (const char *sname)
{
  for (int i = 0; i < samples->size (); ++i)
    {
      Sample *sample = samples->fetch (i);
      if (streq (sname, sample->get_start_label ()))
	{
	  DBG_memuse (sample);
	  break;
	}
    }
}

DataDescriptor *
Experiment::get_race_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_RACE);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () == 0)
    {
      char *base_name = get_basename (expt_name);
      char *msg = dbe_sprintf (GTXT ("Loading Race Data: %s"), base_name);
      read_data_file (SP_RACETRACE_FILE, msg);
      free (msg);
      resolve_frame_info (dDscr);
    }
  return dDscr;
}

DataDescriptor *
Experiment::get_deadlock_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_DLCK);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () == 0)
    {
      char *base_name = get_basename (expt_name);
      char *msg = dbe_sprintf (GTXT ("Loading Deadlocks Data: %s"), base_name);
      read_data_file (SP_DEADLOCK_FILE, msg);
      free (msg);
      resolve_frame_info (dDscr);
    }
  return dDscr;
}

DataDescriptor *
Experiment::get_sample_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_SAMPLE);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () > 0)
    return dDscr;

  // read_overview_file(); //YXXX do this here at some point instead of:
  PropDescr *tmp_propDscr;
  tmp_propDscr = new PropDescr (PROP_SMPLOBJ, NTXT ("SMPLOBJ"));
  tmp_propDscr->uname = NULL;
  tmp_propDscr->vtype = TYPE_OBJ;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_TSTAMP, NTXT ("TSTAMP"));
  tmp_propDscr->uname = dbe_strdup ("High resolution timestamp");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_SAMPLE, NTXT ("SAMPLE"));
  tmp_propDscr->uname = dbe_strdup ("Sample number");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_EVT_TIME, NTXT ("EVT_TIME"));
  tmp_propDscr->uname = dbe_strdup ("Event duration");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  long ssize = samples->size ();
  for (long ii = 0; ii < ssize; ii++)
    {
      Sample * sample = samples->fetch (ii);
      long recn = dDscr->addRecord ();
      hrtime_t sduration = sample->get_end_time () - sample->get_start_time ();
      dDscr->setObjValue (PROP_SMPLOBJ, recn, sample);
      dDscr->setValue (PROP_SAMPLE, recn, sample->get_number ());
      dDscr->setValue (PROP_TSTAMP, recn, sample->get_end_time ());
      dDscr->setValue (PROP_EVT_TIME, recn, sduration);
    }
  return dDscr;
}

DataDescriptor *
Experiment::get_gc_events ()
{
  DataDescriptor *dDscr = getDataDescriptor (DATA_GCEVENT);
  if (dDscr == NULL)
    return NULL;
  if (dDscr->getSize () > 0)
    return dDscr;

  // read_overview_file(); //YXXX do this here at some point instead of:
  PropDescr *tmp_propDscr;
  tmp_propDscr = new PropDescr (PROP_GCEVENTOBJ, NTXT ("GCEVENTOBJ"));
  tmp_propDscr->uname = NULL;
  tmp_propDscr->vtype = TYPE_OBJ;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_TSTAMP, NTXT ("TSTAMP"));
  tmp_propDscr->uname = dbe_strdup ("High resolution timestamp");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_GCEVENT, NTXT ("GCEVENT"));
  tmp_propDscr->uname = dbe_strdup ("GCEvent number");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  tmp_propDscr = new PropDescr (PROP_EVT_TIME, NTXT ("EVT_TIME"));
  tmp_propDscr->uname = dbe_strdup ("Event duration");
  tmp_propDscr->vtype = TYPE_UINT64;
  dDscr->addProperty (tmp_propDscr);

  long ssize = gcevents->size ();
  for (long ii = 0; ii < ssize; ii++)
    {
      GCEvent * gcevent = gcevents->fetch (ii);
      long recn = dDscr->addRecord ();
      hrtime_t sduration = gcevent->end - gcevent->start;
      dDscr->setObjValue (PROP_GCEVENTOBJ, recn, gcevent);
      dDscr->setValue (PROP_GCEVENT, recn, gcevent->id);
      dDscr->setValue (PROP_TSTAMP, recn, gcevent->end);
      dDscr->setValue (PROP_EVT_TIME, recn, sduration);
    }
  return dDscr;
}

void
Experiment::update_last_event (hrtime_t ts/*wall_ts*/)
{
  if (last_event == ZERO_TIME)
    {
      // not yet initialized
      last_event = ts;
    }
  if (last_event - exp_start_time < ts - exp_start_time)
    // compare deltas to avoid hrtime_t wrap
    last_event = ts;
}

void
Experiment::write_header ()
{
  StringBuilder sb;

  // write commentary to the experiment, describing the parameters
  if (dbeSession->ipc_mode || dbeSession->rdt_mode)
    {
      // In GUI: print start time at the beginning
      time_t t = (time_t) start_sec;
      char *start_time = ctime (&t);
      if (start_time != NULL)
	{
	  sb.setLength (0);
	  sb.sprintf (GTXT ("Experiment started %s"), start_time);
	  commentq->append (new Emsg (CMSG_COMMENT, sb));
	}
    }
  // write message with target arglist
  if (uarglist != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("\nTarget command (%s): '%s'"),
		  (wsize == W32 ? "32-bit" : "64-bit"), uarglist);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  sb.setLength (0);
  sb.sprintf (GTXT ("Process pid %d, ppid %d, pgrp %d, sid %d"),
	      pid, ppid, pgrp, sid);
  commentq->append (new Emsg (CMSG_COMMENT, sb));

  // add comment for user name, if set
  if (username != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("User: `%s'"), username);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for current working directory
  if (ucwd != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("Current working directory: %s"), ucwd);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for collector version string
  if (cversion != NULL)
    {
      char *wstring;
      switch (wsize)
	{
	case Wnone:
	  wstring = NTXT ("?");
	  break;
	case W32:
	  wstring = GTXT ("32-bit");
	  break;
	case W64:
	  wstring = GTXT ("64-bit");
	  break;
	default:
	  wstring = NTXT ("??");
	  break;
	}
      sb.setLength (0);
      sb.sprintf (GTXT ("Collector version: `%s'; experiment version %d.%d (%s)"),
		  cversion, exp_maj_version, exp_min_version, wstring);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for driver version string (er_kernel)
  if (dversion != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("Kernel driver version: `%s'"), dversion);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  if (jversion != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("JVM version: `%s'"), jversion);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for hostname, parameters
  if (hostname == NULL)
    hostname = dbe_strdup (GTXT ("unknown"));
  if (os_version == NULL)
    os_version = dbe_strdup (GTXT ("unknown"));
  if (architecture == NULL)
    architecture = dbe_strdup (GTXT ("unknown"));
  sb.setLength (0);
  sb.sprintf (GTXT ("Host `%s', OS `%s', page size %d, architecture `%s'"),
	      hostname, os_version, page_size, architecture);
  commentq->append (new Emsg (CMSG_COMMENT, sb));

  sb.setLength (0);
  if (maxclock != minclock)
    {
      clock = maxclock;
      sb.sprintf (
		  GTXT ("  %d CPUs, with clocks ranging from %d to %d MHz.; max of %d MHz. assumed"),
		  ncpus, minclock, maxclock, clock);
    }
  else
    sb.sprintf (GTXT ("  %d CPU%s, clock speed %d MHz."),
		ncpus, (ncpus == 1 ? NTXT ("") : "s"), clock);
  commentq->append (new Emsg (CMSG_COMMENT, sb));

  // add comment for machine memory size
  if (page_size > 0 && npages > 0)
    {
      long long memsize = ((long long) npages * page_size) / (1024 * 1024);
      sb.setLength (0);
      sb.sprintf (GTXT ("  Memory: %d pages @  %d = %lld MB."),
		  npages, page_size, memsize);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for machine memory size
  if (machinemodel != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Machine model: %s"), machinemodel);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }

  // add comment for start time
  time_t t = (time_t) start_sec;
  char *p = ctime (&t);
  sb.setLength (0);
  if (p != NULL)
    sb.sprintf (GTXT ("Experiment started %s"), p);
  else
    sb.sprintf (GTXT ("\nExperiment start not recorded"));
  write_coll_params ();
  commentq->append (new Emsg (CMSG_COMMENT, sb));
  commentq->appendqueue (runlogq);
  runlogq->mark_clear ();
}

void
Experiment::write_coll_params ()
{
  StringBuilder sb;

  // now write the various collection parameters as comments
  sb.setLength (0);
  sb.append (GTXT ("Data collection parameters:"));
  commentq->append (new Emsg (CMSG_COMMENT, sb));
  if (coll_params.profile_mode == 1)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Clock-profiling, interval = %d microsecs."),
		  (int) (coll_params.ptimer_usec));
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.sync_mode == 1)
    {
      sb.setLength (0);
      char *scope_str = NTXT ("");
      switch (coll_params.sync_scope)
	{
	case 0:
	  scope_str = GTXT ("Native- and Java-APIs");
	  break;
	case SYNCSCOPE_JAVA:
	  scope_str = GTXT ("JAVA-APIs");
	  break;
	case SYNCSCOPE_NATIVE:
	  scope_str = GTXT ("Native-APIs");
	  break;
	case SYNCSCOPE_JAVA | SYNCSCOPE_NATIVE:
	  scope_str = GTXT ("Native- and Java-APIs");
	  break;
	}
      if (coll_params.sync_threshold < 0)
	sb.sprintf (GTXT ("  Synchronization tracing, threshold = %d microsecs. (calibrated); %s"),
		    -coll_params.sync_threshold, scope_str);
      else
	sb.sprintf (GTXT ("  Synchronization tracing, threshold = %d microsecs.; %s"),
		    coll_params.sync_threshold, scope_str);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.heap_mode == 1)
    {
      sb.setLength (0);
      sb.append (GTXT ("  Heap tracing"));
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.io_mode == 1)
    {
      sb.setLength (0);
      sb.append (GTXT ("  IO tracing"));
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.race_mode == 1)
    {
      sb.setLength (0);
      char *race_stack_name;
      switch (coll_params.race_stack)
	{
	case 0:
	  race_stack_name = GTXT ("dual-stack");
	  break;
	case 1:
	  race_stack_name = GTXT ("single-stack");
	  break;
	case 2:
	  race_stack_name = GTXT ("leaf");
	  break;
	default:
	  abort ();
	}
      sb.sprintf (GTXT ("  Datarace detection, %s"), race_stack_name);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.deadlock_mode == 1)
    {
      sb.setLength (0);
      sb.append (GTXT ("  Deadlock detection"));
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.hw_mode == 1)
    {
      sb.setLength (0);
      if (hwc_default == true)
	sb.append (GTXT ("  HW counter-profiling (default); counters:"));
      else
	sb.append (GTXT ("  HW counter-profiling; counters:"));
      commentq->append (new Emsg (CMSG_COMMENT, sb));
      for (int i = 0; i < MAX_HWCOUNT; i++)
	{
	  if (!coll_params.hw_aux_name[i])
	    continue;
	  sb.setLength (0);
	  sb.sprintf (GTXT ("    %s, tag %d, interval %d, memop %d"),
		      coll_params.hw_aux_name[i], i,
		      coll_params.hw_interval[i], coll_params.hw_tpc[i]);
	  commentq->append (new Emsg (CMSG_COMMENT, sb));
	}
    }
  if (coll_params.sample_periodic == 1)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Periodic sampling, %d secs."),
		  coll_params.sample_timer);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.limit != 0)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Experiment size limit, %d"),
		  coll_params.limit);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.linetrace != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Follow descendant processes from: %s"),
		  coll_params.linetrace);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.pause_sig != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Pause signal %s"), coll_params.pause_sig);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.sample_sig != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Sample signal %s"), coll_params.sample_sig);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.start_delay != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Data collection delay start %s seconds"), coll_params.start_delay);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  if (coll_params.terminate != NULL)
    {
      sb.setLength (0);
      sb.sprintf (GTXT ("  Data collection termination after %s seconds"), coll_params.terminate);
      commentq->append (new Emsg (CMSG_COMMENT, sb));
    }
  // add a blank line after data description
  commentq->append (new Emsg (CMSG_COMMENT, NTXT ("")));
}


/*
 *    Raw packet processing
 */
static int
check_mstate (char *ptr, PacketDescriptor *pDscr, int arg)
{
  switch (arg)
    {
    case PROP_UCPU:
    case PROP_SCPU:
    case PROP_TRAP:
    case PROP_TFLT:
    case PROP_DFLT:
    case PROP_KFLT:
    case PROP_ULCK:
    case PROP_TSLP:
    case PROP_WCPU:
    case PROP_TSTP:
      break;
    default:
      return 0;
    }
  Vector<FieldDescr*> *fields = pDscr->getFields ();
  for (int i = 0, sz = fields->size (); i < sz; i++)
    {
      FieldDescr *fDscr = fields->fetch (i);
      if (fDscr->propID == arg)
	return *((int*) (ptr + fDscr->offset));
    }
  return 0;
}

#define PACKET_ALIGNMENT 4

uint64_t
Experiment::readPacket (Data_window *dwin, Data_window::Span *span)
{
  Common_packet *rcp = (Common_packet *) dwin->bind (span,
						    sizeof (CommonHead_packet));
  uint16_t v16;
  uint64_t size = 0;
  if (rcp)
    {
      if ((((long) rcp) % PACKET_ALIGNMENT) != 0)
	{
	  invalid_packet++;
	  size = PROFILE_BUFFER_CHUNK - span->offset % PROFILE_BUFFER_CHUNK;
	  return size;
	}
      v16 = (uint16_t) rcp->tsize;
      size = dwin->decode (v16);
      if (size == 0)
	{
	  size = PROFILE_BUFFER_CHUNK - span->offset % PROFILE_BUFFER_CHUNK;
	  return size;
	}
      rcp = (Common_packet *) dwin->bind (span, size);
    }
  if (rcp == NULL)
    return 0;

  if ((((long) rcp) % PACKET_ALIGNMENT) != 0)
    {
      invalid_packet++;
      size = PROFILE_BUFFER_CHUNK - span->offset % PROFILE_BUFFER_CHUNK;
      return size;
    }
  v16 = (uint16_t) rcp->type;
  uint32_t rcptype = dwin->decode (v16);
  if (rcptype == EMPTY_PCKT)
    return size;
  if (rcptype == FRAME_PCKT)
    {
      RawFramePacket *fp = new RawFramePacket;
      fp->uid = dwin->decode (((Frame_packet*) rcp)->uid);
      fp->uidn = NULL;
      fp->uidj = NULL;
      fp->omp_uid = NULL;
      fp->omp_state = 0;
      char *ptr = (char*) rcp + dwin->decode (((Frame_packet*) rcp)->hsize);
      if ((((long) ptr) % PACKET_ALIGNMENT) != 0)
	{
	  invalid_packet++;
	  delete fp;
	  return size;
	}
      v16 = (uint16_t) ((Frame_packet*) rcp)->tsize;
      char *end = (char*) rcp + dwin->decode (v16);
      for (; ptr < end;)
	{
	  Common_info *cinfo = (Common_info*) ptr;
	  uint32_t hsize = dwin->decode (cinfo->hsize);
	  if (hsize == 0 || ptr + hsize > end)
	    break;
	  int kind = dwin->decode (cinfo->kind);
	  bool compressed = false;
	  if (kind & COMPRESSED_INFO)
	    {
	      compressed = true;
	      kind &= ~COMPRESSED_INFO;
	    }
	  switch (kind)
	    {
	    case STACK_INFO:
	      {
		char *stack = ptr + sizeof (Stack_info);
		size_t stack_size = hsize - sizeof (Stack_info);
		uint64_t uidn = dwin->decode (((Stack_info*) cinfo)->uid);
		if (stack_size <= 0)
		  {
		    fp->uidn = get_uid_node (uidn);
		    break;
		  }
		uint64_t link_uid = (uint64_t) 0;
		if (compressed)
		  {
		    stack_size -= sizeof (uint64_t);
		    unsigned char *s = (unsigned char*) (stack + stack_size);
		    int shift = 0;
		    for (size_t i = 0; i<sizeof (link_uid); i++)
		      {
			link_uid |= (uint64_t) * s++ << shift;
			shift += 8;
		      }
		  }
		if (wsize == W32)
		  fp->uidn = add_uid (dwin, uidn,
				      (int) (stack_size / sizeof (uint32_t)),
				      (uint32_t*) stack, link_uid);
		else
		  fp->uidn = add_uid (dwin, uidn,
				      (int) (stack_size / sizeof (uint64_t)),
				      (uint64_t*) stack, link_uid);
		break;
	      }
	    case JAVA_INFO:
	      {
		char *stack = ptr + sizeof (Java_info);
		size_t stack_size = hsize - sizeof (Java_info);
		uint64_t uidj = dwin->decode (((Java_info*) cinfo)->uid);
		if (stack_size <= 0)
		  {
		    fp->uidj = get_uid_node (uidj);
		    break;
		  }

		uint64_t link_uid = (uint64_t) 0;
		if (compressed)
		  {
		    stack_size -= sizeof (uint64_t);
		    unsigned char *s = (unsigned char*) (stack + stack_size);
		    int shift = 0;
		    for (size_t i = 0; i<sizeof (link_uid); i++)
		      {
			link_uid |= (uint64_t) * s++ << shift;
			shift += 8;
		      }
		  }
		if (wsize == W32)
		  fp->uidj = add_uid (dwin, uidj,
				      (int) (stack_size / sizeof (uint32_t)),
				      (uint32_t*) stack, link_uid);
		else
		  {
		    // bug 6909545: garbage in 64-bit JAVA_INFO
		    char *nstack = (char*) malloc (stack_size);
		    char *dst = nstack;
		    char *srcmax = stack + stack_size - sizeof (uint64_t);
		    for (char *src = stack; src <= srcmax;)
		      {
			int64_t val = dwin->decode (*(int32_t*) src);
			*(uint64_t*) dst = dwin->decode (val);
			src += sizeof (uint64_t);
			dst += sizeof (uint64_t);
			if (src > srcmax)
			  {
			    fprintf (stderr, "er_print: Experiment::readPacket: Error in data: src=%llx greater than %llx\n",
				     (long long) src, (long long) srcmax);
			    break;
			  }
			*(uint64_t*) dst = *(uint64_t*) src;
			src += sizeof (uint64_t);
			dst += sizeof (uint64_t);
		      }
		    fp->uidj = add_uid (dwin, uidj,
					(int) (stack_size / sizeof (uint64_t)),
					(uint64_t*) nstack, link_uid);
		    free (nstack);
		  }
		break;
	      }
	    case OMP_INFO:
	      fp->omp_state = dwin->decode (((OMP_info*) ptr)->omp_state);
	      break;
	    case OMP2_INFO:
	      {
		uint64_t omp_uid = dwin->decode (((OMP2_info*) ptr)->uid);
		fp->omp_uid = get_uid_node (omp_uid);
		fp->omp_state = dwin->decode (((OMP2_info*) ptr)->omp_state);
		break;
	      }
	    default:
	      break;
	    }
	  ptr += hsize;
	}
      frmpckts->append (fp);
      return size;
    }
  else if (rcptype == UID_PCKT)
    {
      Uid_packet *uidp = (Uid_packet*) rcp;
      uint64_t uid = dwin->decode (uidp->uid);
      char *arr_bytes = (char*) (uidp + 1);
      v16 = (uint16_t) rcp->tsize;
      size_t arr_length = dwin->decode (v16) - sizeof (Uid_packet);
      if (arr_length <= 0)
	return size;
      uint64_t link_uid = (uint64_t) 0;
      if (dwin->decode (uidp->flags) & COMPRESSED_INFO)
	{
	  arr_length -= sizeof (uint64_t);
	  unsigned char *s = (unsigned char*) (arr_bytes + arr_length);
	  int shift = 0;
	  for (size_t i = 0; i<sizeof (link_uid); i++)
	    {
	      link_uid |= (uint64_t) * s++ << shift;
	      shift += 8;
	    }
	}
      if (wsize == W32)
	add_uid (dwin, uid, (int) (arr_length / sizeof (uint32_t)),
		 (uint32_t*) arr_bytes, link_uid);
      else
	add_uid (dwin, uid, (int) (arr_length / sizeof (uint64_t)),
		 (uint64_t*) arr_bytes, link_uid);
      return size;
    }

  PacketDescriptor *pcktDescr = getPacketDescriptor (rcptype);
  if (pcktDescr == NULL)
    return size;
  DataDescriptor *dataDescr = pcktDescr->getDataDescriptor ();
  if (dataDescr == NULL)
    return size;

  /* omazur: TBR START -- old experiment */
  if (rcptype == PROF_PCKT)
    {
      // For backward compatibility with older SS12 experiments
      int numstates = get_params ()->lms_magic_id; // ugly, for old experiments
      if (numstates > LMS_NUM_SOLARIS_MSTATES)
	numstates = LMS_NUM_SOLARIS_MSTATES;
      for (int i = 0; i < numstates; i++)
	if (check_mstate ((char*) rcp, pcktDescr, PROP_UCPU + i))
	  readPacket (dwin, (char*) rcp, pcktDescr, dataDescr, PROP_UCPU + i,
		      size);
    }
  else
    readPacket (dwin, (char*) rcp, pcktDescr, dataDescr, 0, size);
  return size;
}

void
Experiment::readPacket (Data_window *dwin, char *ptr, PacketDescriptor *pDscr,
			DataDescriptor *dDscr, int arg, uint64_t pktsz)
{
  union Value
  {
    uint32_t val32;
    uint64_t val64;
  } *v;

  long recn = dDscr->addRecord ();
  Vector<FieldDescr*> *fields = pDscr->getFields ();
  int sz = fields->size ();
  for (int i = 0; i < sz; i++)
    {
      FieldDescr *field = fields->fetch (i);
      v = (Value*) (ptr + field->offset);
      if (field->propID == arg)
	{
	  dDscr->setValue (PROP_NTICK, recn, dwin->decode (v->val32));
	  dDscr->setValue (PROP_MSTATE, recn, (uint32_t) (field->propID - PROP_UCPU));
	}
      if (field->propID == PROP_THRID || field->propID == PROP_LWPID
	  || field->propID == PROP_CPUID)
	{
	  uint64_t tmp64 = 0;
	  switch (field->vtype)
	    {
	    case TYPE_INT32:
	    case TYPE_UINT32:
	      tmp64 = dwin->decode (v->val32);
	      break;
	    case TYPE_INT64:
	    case TYPE_UINT64:
	      tmp64 = dwin->decode (v->val64);
	      break;
	    case TYPE_STRING:
	    case TYPE_DOUBLE:
	    case TYPE_OBJ:
	    case TYPE_DATE:
	    case TYPE_BOOL:
	    case TYPE_ENUM:
	    case TYPE_LAST:
	    case TYPE_NONE:
	      break;
	    }
	  uint32_t tag = mapTagValue ((Prop_type) field->propID, tmp64);
	  dDscr->setValue (field->propID, recn, tag);
	}
      else
	{
	  switch (field->vtype)
	    {
	    case TYPE_INT32:
	    case TYPE_UINT32:
	      dDscr->setValue (field->propID, recn, dwin->decode (v->val32));
	      break;
	    case TYPE_INT64:
	    case TYPE_UINT64:
	      dDscr->setValue (field->propID, recn, dwin->decode (v->val64));
	      break;
	    case TYPE_STRING:
	      {
		int len = (int) (pktsz - field->offset);
		if ((len > 0) && (ptr[field->offset] != 0))
		  {
		    StringBuilder *sb = new StringBuilder ();
		    sb->append (ptr + field->offset, 0, len);
		    dDscr->setObjValue (field->propID, recn, sb);
		  }
		break;
	      }
	      // ignoring the following cases (why?)
	    case TYPE_DOUBLE:
	    case TYPE_OBJ:
	    case TYPE_DATE:
	    case TYPE_BOOL:
	    case TYPE_ENUM:
	    case TYPE_LAST:
	    case TYPE_NONE:
	      break;
	    }
	}
    }
}

#define PROG_BYTE 102400 // update progress bar every PROG_BYTE bytes

void
Experiment::read_data_file (const char *fname, const char *msg)
{
  Data_window::Span span;
  off64_t total_len, remain_len;
  char *progress_bar_msg;
  int progress_bar_percent = -1;

  char *data_file_name = dbe_sprintf (NTXT ("%s/%s"), expt_name, fname);
  Data_window *dwin = new Data_window (data_file_name);
  // Here we can call stat(data_file_name) to get file size,
  // and call a function to reallocate vectors for clock profiling data
  free (data_file_name);
  if (dwin->not_opened ())
    {
      delete dwin;
      return;
    }
  dwin->need_swap_endian = need_swap_endian;

  span.offset = 0;
  span.length = dwin->get_fsize ();
  total_len = remain_len = span.length;
  progress_bar_msg = dbe_sprintf (NTXT ("%s %s"), NTXT ("  "), msg);
  invalid_packet = 0;
  for (;;)
    {
      uint64_t pcktsz = readPacket (dwin, &span);
      if (pcktsz == 0)
	break;
      // Update progress bar
      if ((span.length <= remain_len) && (remain_len > 0))
	{
	  int percent = (int) (100 * (total_len - remain_len) / total_len);
	  if (percent > progress_bar_percent)
	    {
	      progress_bar_percent += 10;
	      theApplication->set_progress (percent, progress_bar_msg);
	    }
	  remain_len -= PROG_BYTE;
	}
      span.length -= pcktsz;
      span.offset += pcktsz;
    }
  delete dwin;

  if (invalid_packet)
    {
      StringBuilder sb;
      sb.sprintf (GTXT ("WARNING: There are %d invalid packet(s) in the %s file"),
		  invalid_packet, fname);
      Emsg *m = new Emsg (CMSG_WARN, sb);
      warnq->append (m);
    }

  theApplication->set_progress (0, NTXT (""));
  free (progress_bar_msg);
}

int
Experiment::read_overview_file ()
{
  char *data_file_name = dbe_sprintf ("%s/%s", expt_name, SP_OVERVIEW_FILE);
  Data_window *dwin = new Data_window (data_file_name);
  free (data_file_name);
  if (dwin->not_opened ())
    {
      delete dwin;
      return 0;
    }
  dwin->need_swap_endian = need_swap_endian;
  newDataDescriptor (DATA_SAMPLE);

  Data_window::Span span;
  span.offset = 0;
  span.length = dwin->get_fsize ();

  PrUsage *data = NULL, *data_prev = NULL;
  Sample *sample;
  int sample_number = 1;

  int64_t prDataSize;
  if (wsize == W32)
    prDataSize = PrUsage::bind32Size ();
  else
    prDataSize = PrUsage::bind64Size ();

  while (span.length > 0)
    {
      data_prev = data;
      data = new PrUsage ();

      void *dw = dwin->bind (&span, prDataSize);
      if ((dw == NULL) || (prDataSize > span.length))
	{
	  Emsg *m = new Emsg (CMSG_ERROR, GTXT ("Warning: overview data file can't be read"));
	  warnq->append (m);
	  status = FAILURE;
	  delete dwin;
	  return status;
	}

      if (wsize == W32)
	data->bind32 (dw, need_swap_endian);
      else
	data->bind64 (dw, need_swap_endian);
      span.length -= prDataSize;
      span.offset += prDataSize;

      // Skip the first packet
      if (data_prev == NULL)
	continue;
      if (sample_number > samples->size ())
	{ // inconsistent log/overview
	  sample = new Sample (sample_number);
	  char * label = GTXT ("<unknown>");
	  sample->start_label = dbe_strdup (label);
	  sample->end_label = dbe_strdup (label);
	  samples->append (sample);
	}
      else
	sample = samples->fetch (sample_number - 1);
      sample_number++;
      sample->start_time = data_prev->pr_tstamp + 1;
      sample->end_time = data->pr_tstamp;
      sample->prusage = data_prev;

      data_prev->pr_rtime = data->pr_rtime - data_prev->pr_rtime;
      data_prev->pr_utime = data->pr_utime - data_prev->pr_utime;
      data_prev->pr_stime = data->pr_stime - data_prev->pr_stime;
      data_prev->pr_ttime = data->pr_ttime - data_prev->pr_ttime;
      data_prev->pr_tftime = data->pr_tftime - data_prev->pr_tftime;
      data_prev->pr_dftime = data->pr_dftime - data_prev->pr_dftime;
      data_prev->pr_kftime = data->pr_kftime - data_prev->pr_kftime;
      data_prev->pr_ltime = data->pr_ltime - data_prev->pr_ltime;
      data_prev->pr_slptime = data->pr_slptime - data_prev->pr_slptime;
      data_prev->pr_wtime = data->pr_wtime - data_prev->pr_wtime;
      data_prev->pr_stoptime = data->pr_stoptime - data_prev->pr_stoptime;
      data_prev->pr_minf = data->pr_minf - data_prev->pr_minf;
      data_prev->pr_majf = data->pr_majf - data_prev->pr_majf;
      data_prev->pr_nswap = data->pr_nswap - data_prev->pr_nswap;
      data_prev->pr_inblk = data->pr_inblk - data_prev->pr_inblk;
      data_prev->pr_oublk = data->pr_oublk - data_prev->pr_oublk;
      data_prev->pr_msnd = data->pr_msnd - data_prev->pr_msnd;
      data_prev->pr_mrcv = data->pr_mrcv - data_prev->pr_mrcv;
      data_prev->pr_sigs = data->pr_sigs - data_prev->pr_sigs;
      data_prev->pr_vctx = data->pr_vctx - data_prev->pr_vctx;
      data_prev->pr_ictx = data->pr_ictx - data_prev->pr_ictx;
      data_prev->pr_sysc = data->pr_sysc - data_prev->pr_sysc;
      data_prev->pr_ioch = data->pr_ioch - data_prev->pr_ioch;
      sample->get_usage (); // force validation
    }

  for (long smpNum = samples->size (); smpNum >= sample_number; smpNum--)
    {
      // overview file was truncated
      sample = samples->remove (smpNum - 1);
      delete sample;
    }

  if (data)
    {
      // Update last_event so that getEndTime() covers
      // all loadobjects, too.
      update_last_event (data->pr_tstamp);
      delete data;
    }
  delete dwin;
  return SUCCESS;
}

int
Experiment::uidNodeCmp (const void *a, const void *b)
{
  UIDnode *nd1 = *(UIDnode**) a;
  UIDnode *nd2 = *(UIDnode**) b;
  if (nd1->uid == nd2->uid)
    return 0;
  return nd1->uid < nd2->uid ? -1 : 1;
}

static uint64_t
funcAddr (uint32_t val)
{
  if (val == (uint32_t) SP_LEAF_CHECK_MARKER)
    return (uint64_t) SP_LEAF_CHECK_MARKER;
  if (val == (uint32_t) SP_TRUNC_STACK_MARKER)
    return (uint64_t) SP_TRUNC_STACK_MARKER;
  if (val == (uint32_t) SP_FAILED_UNWIND_MARKER)
    return (uint64_t) SP_FAILED_UNWIND_MARKER;
  return val;
}

Experiment::UIDnode *
Experiment::add_uid (Data_window *dwin, uint64_t uid, int size,
		     uint32_t *array, uint64_t link_uid)
{
  if (uid == (uint64_t) 0)
    return NULL;
  uint64_t val = funcAddr (dwin->decode (array[0]));
  UIDnode *node = NULL;
  UIDnode *res = get_uid_node (uid, val);
  UIDnode *next = res;
  for (int i = 0; i < size; i++)
    {
      val = funcAddr (dwin->decode (array[i]));
      if (next == NULL)
	{
	  next = get_uid_node ((uint64_t) 0, val);
	  if (node != NULL)
	    node->next = next;
	}
      node = next;
      next = node->next;
      if (node->val == 0)
	node->val = val;
      else if (node->val != val)   // Algorithmic error (should never happen)
	node->val = (uint64_t) SP_LEAF_CHECK_MARKER;
    }
  if (next == NULL && link_uid != (uint64_t) 0 && node != NULL)
    node->next = get_uid_node (link_uid);
  return res;
}

Experiment::UIDnode *
Experiment::add_uid (Data_window *dwin, uint64_t uid, int size, uint64_t *array, uint64_t link_uid)
{
  if (uid == (uint64_t) 0)
    return NULL;
  UIDnode *node = NULL;
  uint64_t val = dwin->decode (array[0]);
  UIDnode *res = get_uid_node (uid, val);
  UIDnode *next = res;
  for (int i = 0; i < size; i++)
    {
      val = dwin->decode (array[i]);
      if (next == NULL)
	{
	  next = get_uid_node ((uint64_t) 0, val);
	  if (node != NULL)
	    node->next = next;
	}
      node = next;
      next = node->next;
      if (node->val == (uint64_t) 0)
	node->val = val;
      else if (node->val != val)   // Algorithmic error (should never happen)
	node->val = (uint64_t) - 1;
    }
  if (next == NULL && link_uid != (uint64_t) 0 && node != NULL)
    node->next = get_uid_node (link_uid);
  return res;
}

Experiment::UIDnode *
Experiment::new_uid_node (uint64_t uid, uint64_t val)
{
#define NCHUNKSTEP 1024
  if (nnodes >= nchunks * CHUNKSZ)
    {
      // Reallocate Node chunk array
      UIDnode** old_chunks = chunks;
      chunks = new UIDnode*[nchunks + NCHUNKSTEP];
      memcpy (chunks, old_chunks, nchunks * sizeof (UIDnode*));
      nchunks += NCHUNKSTEP;
      delete[] old_chunks;
      // Clean future pointers
      memset (&chunks[nchunks - NCHUNKSTEP], 0, NCHUNKSTEP * sizeof (UIDnode*));
    }

  if (NULL == chunks[nnodes / CHUNKSZ])   // Allocate new chunk for nodes.
    chunks[nnodes / CHUNKSZ] = new UIDnode[CHUNKSZ];
  UIDnode *node = &chunks[nnodes / CHUNKSZ][nnodes % CHUNKSZ];
  node->uid = uid;
  node->val = val;
  node->next = NULL;
  nnodes++;
  return node;
}

Experiment::UIDnode *
Experiment::get_uid_node (uint64_t uid, uint64_t val)
{
  int hash = (((int) uid) >> 4) & (HTableSize - 1);
  if (uid != (uint64_t) 0)
    {
      UIDnode *node = uidHTable[hash];
      if (node && node->uid == uid)
	return node;
    }
  UIDnode *node = new_uid_node (uid, val);
  if (uid != (uint64_t) 0)
    {
      uidHTable[hash] = node;
      uidnodes->append (node);
    }
  return node;
}

Experiment::UIDnode *
Experiment::get_uid_node (uint64_t uid)
{
  if (uid == (uint64_t) 0)
    return NULL;
  int hash = (((int) uid) >> 4) & (HTableSize - 1);
  UIDnode *node = uidHTable[hash];
  if (node && node->uid == uid)
    return node;
  node = new_uid_node (uid, (uint64_t) 0);
  node->next = node;
  return node;
}

Experiment::UIDnode *
Experiment::find_uid_node (uint64_t uid)
{
  int hash = (((int) uid) >> 4) & (HTableSize - 1);
  UIDnode *node = uidHTable[hash];
  if (node && node->uid == uid)
    return node;
  int lt = 0;
  int rt = uidnodes->size () - 1;
  while (lt <= rt)
    {
      int md = (lt + rt) / 2;
      node = uidnodes->fetch (md);
      if (node->uid < uid)
	lt = md + 1;
      else if (node->uid > uid)
	rt = md - 1;
      else
	{
	  uidHTable[hash] = node;
	  return node;
	}
    }
  return NULL;
}

int
Experiment::frUidCmp (const void *a, const void *b)
{
  RawFramePacket *fp1 = *(RawFramePacket**) a;
  RawFramePacket *fp2 = *(RawFramePacket**) b;
  if (fp1->uid == fp2->uid)
    return 0;
  return fp1->uid < fp2->uid ? -1 : 1;
}

Experiment::RawFramePacket *
Experiment::find_frame_packet (uint64_t uid)
{
  int lt = 0;
  int rt = frmpckts->size () - 1;
  while (lt <= rt)
    {
      int md = (lt + rt) / 2;
      RawFramePacket *fp = frmpckts->fetch (md);
      if (fp->uid < uid)
	lt = md + 1;
      else if (fp->uid > uid)
	rt = md - 1;
      else
	return fp;
    }

  return NULL;
}

#define FRINFO_CACHEOPT_SIZE_LIMIT  4000000
#define FRINFO_PIPELINE_SIZE_LIMIT  500000
#define FRINFO_PIPELINE_NUM_STAGES  3

// Pipelined execution of resolve_frame_info() and add_stack().
// Since this is the largest time consuming part of loading an experiment (especially
// so for large java experiments) - executing this part as a 3 stage pipeline can
// give significant performance gain - and this concept can be aggressively applied
// to enhance the gain further in future. The three stages are:
// Phase 1:  resolve_frame_info()
// Phase 2:  first part of add_stack() where the native stack is built
// Phase 3:  second part og add_stack() where the java stack is built
// Phase 4:   insert the native and java stacks into the stack map
// The main thread operates in the first Phase and the other stages are
// operated by a ssplib sequential queue - The threads working on the queues run concurrently
// with each other and with the main thread. But within a particular queue, jobs are
// executed sequentially


// This is the second phase of the pipeline of resolve_frame_info and add_stack
//  It works on a chunk of iterations (size CSTCTX_CHUNK_SZ) and invokes add_stack()
// for each one of them

void
Experiment::resolve_frame_info (DataDescriptor *dDscr)
{
  if (!resolveFrameInfo)
    return;
  if (NULL == cstack)
    return;
  dDscr->setResolveFrInfoDone ();

  // Check for TSTAMP
  int propID = dbeSession->getPropIdByName (NTXT ("TSTAMP"));
  Data *dataTStamp = dDscr->getData (propID);
  if (dataTStamp == NULL)
    return;

  propID = dbeSession->getPropIdByName (NTXT ("FRINFO"));
  Data *dataFrinfo = dDscr->getData (propID);

  propID = dbeSession->getPropIdByName (NTXT ("THRID"));
  Data *dataThrId = dDscr->getData (propID);

  // We can get frame info either by FRINFO or by [THRID,STKIDX]
  if (dataFrinfo == NULL)
    return;

  char *propName = NTXT ("MSTACK");
  propID = dbeSession->getPropIdByName (propName);
  PropDescr *prMStack = new PropDescr (propID, propName);
  prMStack->uname = dbe_strdup (GTXT ("Machine Call Stack"));
  prMStack->vtype = TYPE_OBJ;
  dDscr->addProperty (prMStack);

  propName = NTXT ("USTACK");
  propID = dbeSession->getPropIdByName (propName);
  PropDescr *prUStack = new PropDescr (propID, propName);
  prUStack->uname = dbe_strdup (GTXT ("User Call Stack"));
  prUStack->vtype = TYPE_OBJ;
  dDscr->addProperty (prUStack);

  propName = NTXT ("XSTACK");
  propID = dbeSession->getPropIdByName (propName);
  PropDescr *prXStack = new PropDescr (propID, propName);
  prXStack->uname = dbe_strdup (GTXT ("Expert Call Stack"));
  prXStack->vtype = TYPE_OBJ;
  dDscr->addProperty (prXStack);

  propName = NTXT ("HSTACK");
  propID = dbeSession->getPropIdByName (propName);
  PropDescr *prHStack = new PropDescr (propID, propName);
  prHStack->uname = dbe_strdup (GTXT ("ShowHide Call Stack"));
  prHStack->vtype = TYPE_OBJ;
  dDscr->addProperty (prHStack);

  if (has_java)
    {
      propName = NTXT ("JTHREAD");
      propID = dbeSession->getPropIdByName (propName);
      PropDescr *prJThread = new PropDescr (propID, propName);
      prJThread->uname = dbe_strdup (GTXT ("Java Thread"));
      prJThread->vtype = TYPE_OBJ;
      dDscr->addProperty (prJThread);
    }

  if (ompavail)
    {
      PropDescr *prop = new PropDescr (PROP_OMPSTATE, NTXT ("OMPSTATE"));
      prop->uname = dbe_strdup (GTXT ("OpenMP state"));
      prop->vtype = TYPE_UINT32;
      char * stateNames [OMP_LAST_STATE] = OMP_THR_STATE_STRINGS;
      char * stateUNames[OMP_LAST_STATE] = OMP_THR_STATE_USTRINGS;
      for (int ii = 0; ii < OMP_LAST_STATE; ii++)
	prop->addState (ii, stateNames[ii], stateUNames[ii]);
      dDscr->addProperty (prop);

      // add PROP_CPRID to profiling data (not same as omptrace's PROP_CPRID)
      prop = dDscr->getProp (PROP_CPRID);
      if (prop)
	{
	  VType_type type = prop->vtype;
	  assert (type == TYPE_OBJ); //see 7040526
	}
      prop = new PropDescr (PROP_CPRID, NTXT ("CPRID")); //profiling PROP_CPRID
      prop->uname = dbe_strdup (GTXT ("OpenMP parallel region"));
      prop->vtype = TYPE_OBJ;
      dDscr->addProperty (prop);

      // add PROP_TSKID to profiling data (not same as omptrace's PROP_TSKID)
      prop = dDscr->getProp (PROP_TSKID);
      if (prop)
	{
	  VType_type type = prop->vtype;
	  assert (type == TYPE_OBJ); //see 7040526
	}
      prop = new PropDescr (PROP_TSKID, NTXT ("TSKID")); //profiling PROP_TSKID
      prop->uname = dbe_strdup (GTXT ("OpenMP task"));
      prop->vtype = TYPE_OBJ;
      dDscr->addProperty (prop);
    }
  char *progress_bar_msg = dbe_sprintf (NTXT ("%s %s: %s"), NTXT ("  "),
					GTXT ("Processing CallStack Data"),
					get_basename (expt_name));
  int progress_bar_percent = -1;
  long deltaReport = 5000;
  long nextReport = 0;

  long size = dDscr->getSize ();
  //    bool resolve_frinfo_pipelined = size > FRINFO_PIPELINE_SIZE_LIMIT && !ompavail;
  bool resolve_frinfo_pipelined = false;

  Map<uint64_t, uint64_t> *nodeCache = NULL;
  Map<uint64_t, uint64_t> *frameInfoCache = NULL;
  if (size > FRINFO_CACHEOPT_SIZE_LIMIT && dversion == NULL)
    {
      frameInfoCache = new CacheMap<uint64_t, uint64_t>;
      nodeCache = new CacheMap<uint64_t, uint64_t>;
    }

  pushCnt = popCnt = pushCnt3 = popCnt3 = 0;
  nPush = nPop = 0;

  FramePacket *fp = NULL;
  //    DbeThreadPool * threadPool = new DbeThreadPool(5);
  fp = new FramePacket;
  fp->stack = new Vector<Vaddr>;
  fp->jstack = new Vector<Vaddr>;
  fp->ompstack = new Vector<Vaddr>;
  fp->omp_state = 0;
  fp->mpi_state = 0;

  // piggyback on post-processing to calculate exp->last_event
  const hrtime_t _exp_start_time = getStartTime (); // wall clock time
  hrtime_t exp_duration = getLastEvent () == ZERO_TIME ? 0
	  : getLastEvent () - _exp_start_time; // zero-based

  int missed_fi = 0;
  int total_fi = 0;

  for (long i = 0; i < size; i++)
    {
      if (i == nextReport)
	{
	  int percent = (int) (i * 100 / size);
	  if (percent > progress_bar_percent)
	    {
	      progress_bar_percent += 10;
	      theApplication->set_progress (percent, progress_bar_msg);
	    }
	  nextReport += deltaReport;
	}

      uint32_t thrid = (uint32_t) dataThrId->fetchInt (i);
      hrtime_t tstamp = (hrtime_t) dataTStamp->fetchLong (i);

      // piggyback on post-processing to calculate exp->last_event
      {
	hrtime_t relative_timestamp = tstamp - _exp_start_time;
	if (exp_duration < relative_timestamp)
	  exp_duration = relative_timestamp;
      }
      uint64_t frinfo = (uint64_t) dataFrinfo->fetchLong (i);

      RawFramePacket *rfp = NULL;
      if (frinfo)
	{
	  // CacheMap does not work with NULL key
	  if (frameInfoCache != NULL)
	    rfp = (RawFramePacket *) frameInfoCache->get (frinfo);
	}
      if (rfp == 0)
	{
	  rfp = find_frame_packet (frinfo);
	  if (rfp != 0)
	    {
	      if (frameInfoCache != NULL)
		frameInfoCache->put (frinfo, (uint64_t) rfp);
	    }
	  else
	    missed_fi++;
	  total_fi++;
	}

      // Process OpenMP properties
      if (ompavail)
	{
	  fp->omp_state = rfp ? rfp->omp_state : 0;
	  dDscr->setValue (PROP_OMPSTATE, i, fp->omp_state);

	  fp->omp_cprid = mapPRid->get (thrid, tstamp, mapPRid->REL_EQLE);
	  void *omp_preg = mapPReg->get (thrid, tstamp, mapPReg->REL_EQLE);
	  if (!omp_preg)
	    {
	      char *idxname = NTXT ("OMP_preg");
	      int idxtype = dbeSession->findIndexSpaceByName (idxname);
	      if (idxtype != -1)
		{
		  Histable *preg0 = dbeSession->findObjectById (Histable::INDEXOBJ, idxtype, (int64_t) 0);
		  if (preg0)
		    {
		      Vector<Histable*> pregs;
		      pregs.append (preg0);
		      omp_preg = cstack->add_stack (&pregs);
		      mapPReg->put (thrid, tstamp, omp_preg);
		    }
		}
	    }
	  dDscr->setObjValue (PROP_CPRID, i, omp_preg); //profiling PROP_CPRID
	  void *omp_task = mapTask->get (thrid, tstamp, mapTask->REL_EQLE);
	  if (!omp_task)
	    {
	      char *idxname = NTXT ("OMP_task");
	      int idxtype = dbeSession->findIndexSpaceByName (idxname);
	      if (idxtype != -1)
		{
		  Histable *task0 = dbeSession->findObjectById (Histable::INDEXOBJ, idxtype, (int64_t) 0);
		  if (task0)
		    {
		      Vector<Histable*> tasks;
		      tasks.append (task0);
		      omp_task = cstack->add_stack (&tasks);
		      mapTask->put (thrid, tstamp, omp_task);
		    }
		}
	    }
	  dDscr->setObjValue (PROP_TSKID, i, omp_task); //profiling PROP_TSKID
	}
      else
	{
	  fp->omp_state = 0;
	  fp->omp_cprid = 0;
	}

      // Construct the native stack
      fp->stack->reset ();
      Vaddr leafpc = dDscr->getULongValue (PROP_LEAFPC, i);
      if (leafpc)
	fp->stack->append (leafpc);
      UIDnode *node = rfp ? rfp->uidn : NULL;
      while (node)
	{
	  if (node->next == node)
	    // this node contains link_uid
	    node = find_uid_node (node->uid);
	  else
	    {
	      fp->stack->append (node->val);
	      node = node->next;
	    }
	}
      fp->truncated = 0;
      int last = fp->stack->size () - 1;
      if (last >= 0)
	{
	  switch (fp->stack->fetch (last))
	    {
	    case SP_TRUNC_STACK_MARKER:
	      fp->truncated = (Vaddr) SP_TRUNC_STACK_MARKER;
	      fp->stack->remove (last);
	      break;
	    case SP_FAILED_UNWIND_MARKER:
	      fp->truncated = (Vaddr) SP_FAILED_UNWIND_MARKER;
	      fp->stack->remove (last);
	      break;
	    }
	}

      // Construct the Java stack
      fp->jstack->reset ();
      node = rfp ? rfp->uidj : NULL;
      while (node)
	{
	  if (node->next == node)
	    {
	      // this node contains link_uid
	      UIDnode *n = NULL;
	      if (node->uid)
		{
		  // CacheMap does not work with NULL key
		  if (nodeCache != NULL)
		    n = (UIDnode *) nodeCache->get (node->uid);
		}
	      if (n == NULL)
		{
		  n = find_uid_node (node->uid);
		  if (n != NULL)
		    {
		      if (nodeCache != NULL)
			nodeCache->put (node->uid, (uint64_t) n);
		    }
		}
	      node = n;
	    }
	  else
	    {
	      fp->jstack->append (node->val);
	      node = node->next;
	    }
	}
      fp->jtruncated = false;
      last = fp->jstack->size () - 1;
      if (last >= 1 && fp->jstack->fetch (last) == SP_TRUNC_STACK_MARKER)
	{
	  fp->jtruncated = true;
	  fp->jstack->remove (last);
	  fp->jstack->remove (last - 1);
	}

      // Construct the OpenMP stack
      if (ompavail)
	{
	  fp->ompstack->reset ();
	  if (rfp && rfp->omp_uid)
	    {
	      if (leafpc)
		fp->ompstack->append (leafpc);
	      node = rfp->omp_uid;
	      while (node)
		{
		  if (node->next == node)
		    // this node contains link_uid
		    node = find_uid_node (node->uid);
		  else
		    {
		      fp->ompstack->append (node->val);
		      node = node->next;
		    }
		}
	      fp->omptruncated = false;
	      last = fp->ompstack->size () - 1;
	      if (last >= 0)
		{
		  switch (fp->ompstack->fetch (last))
		    {
		    case SP_TRUNC_STACK_MARKER:
		      fp->omptruncated = (Vaddr) SP_TRUNC_STACK_MARKER;
		      fp->ompstack->remove (last);
		      break;
		    case SP_FAILED_UNWIND_MARKER:
		      fp->omptruncated = (Vaddr) SP_FAILED_UNWIND_MARKER;
		      fp->ompstack->remove (last);
		      break;
		    }
		}
	    }
	}
      cstack->add_stack (dDscr, i, fp, NULL);
    }

  // piggyback on post-processing to calculate exp->last_event
  {
    hrtime_t exp_end_time = _exp_start_time + exp_duration;
    update_last_event (exp_end_time);
  }

  if (missed_fi > 0)
    {
      StringBuilder sb;
      sb.sprintf (
		  GTXT ("*** Warning: %d frameinfo packets are missing from total of %d when resolving %s."),
		  missed_fi, total_fi, dDscr->getName ());
      warnq->append (new Emsg (CMSG_WARN, sb));
    }

  //    threadPool->wait_group();
  //    delete threadPool;
  theApplication->set_progress (0, NTXT (""));
  free (progress_bar_msg);
  if (!resolve_frinfo_pipelined && fp != NULL)
    {
      delete fp->ompstack;
      delete fp->jstack;
      delete fp->stack;
      delete fp;
    }
  delete frameInfoCache;
  frameInfoCache = NULL;
  delete nodeCache;
  nodeCache = NULL;
}

void
Experiment::post_process ()
{
  // update non_paused_time after final update to "last_event"
  if (resume_ts != MAX_TIME && last_event)
    {
      hrtime_t ts = last_event - exp_start_time;
      hrtime_t delta = ts - resume_ts;
      non_paused_time += delta;
      resume_ts = MAX_TIME; // collection is paused
    }

  // GC: prune events outside of experiment duration, calculate GC duration, update indices
  int index;
  GCEvent * gcevent;
  gc_duration = ZERO_TIME;
  if (gcevents != NULL)
    {
      // delete events that finish before exp_start_time or start after last_event
      for (int ii = 0; ii < gcevents->size ();)
	{
	  gcevent = gcevents->fetch (ii);
	  if (gcevent->end - exp_start_time < 0
	      || last_event - gcevent->start < 0)
	    delete gcevents->remove (ii);
	  else
	    ii++;
	}
    }
  Vec_loop (GCEvent*, gcevents, index, gcevent)
  {
    gcevent->id = index + 1; // renumber to account for any deleted events
    if (gcevent->start - exp_start_time < 0 || gcevent->start == ZERO_TIME)
      // truncate events that start before experiment start
      gcevent->start = exp_start_time;
    if (last_event - gcevent->end < 0)
      // truncate events that end after experiment end
      gcevent->end = last_event;
    gc_duration += gcevent->end - gcevent->start;
  }
}

Experiment::Exp_status
Experiment::find_expdir (char *path)
{
  // This function checks that the experiment directory
  // is of the proper form, and accessible
  dbe_stat_t sbuf;

  // Save the name
  expt_name = dbe_strdup (path);

  // Check that the name ends in .er
  size_t i = strlen (path);
  if (i > 0 && path[i - 1] == '/')
    path[--i] = '\0';

  if (i < 4 || strcmp (&path[i - 3], NTXT (".er")) != 0)
    {
      Emsg *m = new Emsg (CMSG_FATAL,
			  GTXT ("*** Error: not a valid experiment name"));
      errorq->append (m);
      status = FAILURE;
      return FAILURE;
    }

  // Check if new directory structure (i.e., no pointer file)
  if (dbe_stat (path, &sbuf))
    {
      Emsg *m = new Emsg (CMSG_FATAL, GTXT ("*** Error: experiment not found"));
      errorq->append (m);
      status = FAILURE;
      return FAILURE;
    }
  if (S_ISDIR (sbuf.st_mode) == 0)
    {
      // ignore pointer-file experiments
      Emsg *m = new Emsg (CMSG_FATAL,
			  GTXT ("*** Error: experiment was recorded with an earlier version, and can not be read"));
      errorq->append (m);
      obsolete = 1;
      status = FAILURE;
      return FAILURE;
    }
  return SUCCESS;
}

void
Experiment::purge ()
{
  // This routine will purge all of the caches of releasable storage.
  for (int i = 0; i < dataDscrs->size (); ++i)
    {
      DataDescriptor *dataDscr = dataDscrs->fetch (i);
      if (dataDscr == NULL)
	continue;
      dataDscr->reset ();
    }
  delete cstack;
  delete cstackShowHide;
  cstack = CallStack::getInstance (this);
  cstackShowHide = CallStack::getInstance (this);
}

void
Experiment::resetShowHideStack ()
{
  delete cstackShowHide;
  cstackShowHide = CallStack::getInstance (this);
}

#define GET_INT_VAL(v, s, len) \
    for (v = len = 0; isdigit(*s); s++, len++) { v = v * 10 + (*s -'0'); }

static int
dir_name_cmp (const void *a, const void *b)
{
  char *s1 = *((char **) a);
  char *s2 = *((char **) b);
  while (*s1)
    {
      if (isdigit (*s1) && isdigit (*s2))
	{
	  int v1, v2, len1, len2;
	  GET_INT_VAL (v1, s1, len1);
	  GET_INT_VAL (v2, s2, len2);
	  if (v1 != v2)
	    return v1 - v2;
	  if (len1 != len2)
	    return len2 - len1;
	  continue;
	}
      if (*s1 != *s2)
	break;
      s1++;
      s2++;
    }
  return *s1 - *s2;
}

Vector<char*> *
Experiment::get_descendants_names ()
{
  char *dir_name = get_expt_name ();
  if (dir_name == NULL)
    return NULL;
  DIR *exp_dir = opendir (dir_name);
  if (exp_dir == NULL)
    return NULL;
  Vector<char*> *exp_names = new Vector<char*>();
  for (struct dirent *entry = readdir (exp_dir); entry;
	  entry = readdir (exp_dir))
    {
      if (entry->d_name[0] == '_' || strncmp (entry->d_name, "M_r", 3) == 0)
	{
	  char *dpath = dbe_sprintf (NTXT ("%s/%s"), dir_name, entry->d_name);
	  dbe_stat_t sbuf;
	  if (dbe_stat (dpath, &sbuf) == 0 && S_ISDIR (sbuf.st_mode))
	    exp_names->append (dpath);
	  else
	    free (dpath);
	}
    }
  closedir (exp_dir);
  if (exp_names->size () == 0)
    {
      delete exp_names;
      return NULL;
    }
  exp_names->sort (dir_name_cmp);
  return exp_names;
}

bool
Experiment::create_dir (char *dname)
{
  if (mkdir (dname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == 0)
    {
      return true;
    }
  dbe_stat_t sbuf;
  if (dbe_stat (dname, &sbuf) != 0 || S_ISDIR (sbuf.st_mode) == 0)
    {
      char *buf = dbe_sprintf (GTXT ("Unable to create directory `%s'\n"),
			       dname);
      errorq->append (new Emsg (CMSG_ERROR, buf));
      free (buf);
      return false;
    }
  return true;
}

char *
Experiment::get_arch_name ()
{
  if (arch_name == NULL)
    {
      // Determine the master experiment directory.
      // omazur: should do it in a less hacky way. XXXX
      char *ptr = strstr_r (expt_name, DESCENDANT_EXPT_KEY);
      ptr = ptr ? ptr + 3 : expt_name + strlen (expt_name);
      arch_name = dbe_sprintf (NTXT ("%.*s/%s"), (int) (ptr - expt_name),
			       expt_name, SP_ARCHIVES_DIR);
    }
  return arch_name;
}

char *
Experiment::get_fndr_arch_name ()
{
  if (fndr_arch_name == NULL)
    // Determine the founder experiment directory.
    fndr_arch_name = dbe_strdup (get_arch_name ());
  return fndr_arch_name;
}

enum
{
  HASH_NAME_LEN     = 11    // (64 / 6 + 1) = 11
};

static char *
get_hash_string (char buf[HASH_NAME_LEN + 1], uint64_t hash)
{
  static const char *har =
	  "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_";
  for (int i = 0; i < HASH_NAME_LEN; i++)
    {
      buf[i] = har[hash & 0x3f];
      hash = hash >> 6;
    }
  buf[HASH_NAME_LEN] = 0;
  return buf;
}

char *
Experiment::getNameInArchive (const char *fname, bool archiveFile)
{
  char *aname = get_archived_name (fname, archiveFile);
  char *ret = dbe_sprintf (NTXT ("%s/%s"), get_arch_name (), aname);
  free (aname);
  return ret;
}

#define MAX_ARCHIVE_FILENAME_LEN    (256 - HASH_NAME_LEN - 2)

char *
Experiment::get_archived_name (const char *fname, bool archiveFile)
{
  char *bname = get_basename (fname);

  // dirname_hash:
  char dirnameHash[HASH_NAME_LEN + 1];
  // Treat "a.out" and "./a.out" equally
  uint64_t hash = bname != fname ? crc64 (fname, bname - fname)
				 : crc64 (NTXT ("./"), 2);
  get_hash_string (dirnameHash, hash);

  char *ret;
  long bname_len = dbe_sstrlen (bname);
  if (bname_len > MAX_ARCHIVE_FILENAME_LEN)
    {
      char basenameHash[HASH_NAME_LEN + 1];
      hash = crc64 (bname, bname_len);
      get_hash_string (basenameHash, hash);
      ret = dbe_sprintf ("%.*s%c%s_%s",
			 MAX_ARCHIVE_FILENAME_LEN - HASH_NAME_LEN - 1,
			 bname, archiveFile ? '.' : '_',
			 dirnameHash, basenameHash);
    }
  else
    ret = dbe_sprintf ("%s%c%s", bname, archiveFile ? '.' : '_', dirnameHash);
  return ret;
}

char *
Experiment::checkFileInArchive (const char *fname, bool archiveFile)
{
  if (archiveMap)
    {
      char *aname = get_archived_name (fname, archiveFile);
      DbeFile *df = archiveMap->get (aname);
      free (aname);
      if (df)
	return strdup (df->get_location ());
      return NULL;
    }
  if (founder_exp)
    return founder_exp->checkFileInArchive (fname, archiveFile);
  return NULL;
}


// Comparing SegMem

static int
SegMemCmp (const void *a, const void *b)
{
  SegMem *item1 = *((SegMem **) a);
  SegMem *item2 = *((SegMem **) b);
  return item1->unload_time > item2->unload_time ? 1 :
	 item1->unload_time == item2->unload_time ? 0 : -1;
}

SegMem*
Experiment::update_ts_in_maps (Vaddr addr, hrtime_t ts)
{
  Vector<SegMem *> *segMems = (Vector<SegMem *> *) maps->values ();
  if (!segMems->is_sorted ())
    {
      Dprintf (DEBUG_MAPS, NTXT ("update_ts_in_maps: segMems.size=%lld\n"), (long long) segMems->size ());
      segMems->sort (SegMemCmp);
    }
  for (int i = 0, sz = segMems ? segMems->size () : 0; i < sz; i++)
    {
      SegMem *sm = segMems->fetch (i);
      if (ts < sm->unload_time)
	{
	  for (; i < sz; i++)
	    {
	      sm = segMems->fetch (i);
	      if ((addr >= sm->base) && (addr < sm->base + sm->size))
		{
		  Dprintf (DEBUG_MAPS,
			   "update_ts_in_maps: old:%u.%09u -> %u.%09u addr=0x%08llx size=%lld\n",
			   (unsigned) (sm->load_time / NANOSEC),
			   (unsigned) (sm->load_time % NANOSEC),
			   (unsigned) (ts / NANOSEC), (unsigned) (ts % NANOSEC),
			   (unsigned long long) sm->base, (long long) sm->size);
		  maps->remove (sm->base, sm->load_time);
		  sm->load_time = ts;
		  maps->insert (sm->base, ts, sm);
		  return sm;
		}
	    }
	}
    }
  Dprintf (DEBUG_MAPS, "update_ts_in_maps: NOT FOUND %u.%09u addr=0x%08llx\n",
	   (unsigned) (ts / NANOSEC), (unsigned) (ts % NANOSEC),
	   (unsigned long long) addr);
  return NULL;
}

DbeInstr*
Experiment::map_Vaddr_to_PC (Vaddr addr, hrtime_t ts)
{
  // Look up in the hash table first
  int hash = (((int) addr) >> 8) & (HTableSize - 1);
  SegMem *si = smemHTable[hash];
  if (si == NULL || addr < si->base || addr >= si->base + si->size
      || ts < si->load_time || ts >= si->unload_time)
    {
      // Not in the hash table
      si = (SegMem*) maps->locate (addr, ts);
      if (si == NULL || addr < si->base || addr >= si->base + si->size
	  || ts < si->load_time || ts >= si->unload_time)
	{
	  si = update_ts_in_maps (addr, ts);
	  if (si == NULL)
	    return dbeSession->get_Unknown_Function ()->find_dbeinstr (PCInvlFlag, addr);
	}
      smemHTable[hash] = si;
    }

  // Calculate the file offset of 'addr'
  uint64_t f_offset = si->get_file_offset () + (addr - si->base);

  DbeInstr *instr;
  if (si->obj->get_type () == Histable::LOADOBJECT)
    {
      LoadObject *lo = (LoadObject*) si->obj;
      lo->sync_read_stabs ();
      instr = lo->find_dbeinstr (f_offset);
    }
  else
    {
      int hash2 = ((((int) addr) & 0xFFFC00) | (((int) f_offset) >> 2))
	      & (HTableSize - 1);
      instr = instHTable[hash2];
      if (instr == NULL || instr->func != si->obj || instr->addr != f_offset)
	{
	  // Not in the hash table
	  Function *fp = (Function *) si->obj;
	  instr = fp->find_dbeinstr (0, f_offset);
	  instHTable[hash2] = instr;
	}
    }
  if (!instr->func->isUsed)
    {
      instr->func->isUsed = true;
      instr->func->module->isUsed = true;
      instr->func->module->loadobject->isUsed = true;
    }
  return instr;
}

Sample *
Experiment::map_event_to_Sample (hrtime_t ts)
{
  Sample *sample;
  int index;

  // Check if the last used sample is the right one,
  // if not then find it.
  if (sample_last_used && ts >= sample_last_used->start_time
      && ts <= sample_last_used->end_time)
    return sample_last_used;

  Vec_loop (Sample*, samples, index, sample)
  {
    if ((ts >= sample->start_time) &&
	(ts <= sample->end_time))
      {
	sample_last_used = sample;
	return sample;
      }
  }
  return (Sample*) NULL;
}

GCEvent *
Experiment::map_event_to_GCEvent (hrtime_t ts)
{
  GCEvent *gcevent;
  int index;

  // Check if the last used sample is the right one,
  // if not then find it.
  if (gcevent_last_used && ts >= gcevent_last_used->start
      && ts <= gcevent_last_used->end)
    return gcevent_last_used;
  Vec_loop (GCEvent*, gcevents, index, gcevent)
  {
    if ((ts >= gcevent->start) &&
	(ts <= gcevent->end))
      {
	gcevent_last_used = gcevent;
	return gcevent;
      }
  }
  return (GCEvent*) NULL;
}

DbeInstr*
Experiment::map_jmid_to_PC (Vaddr mid, int bci, hrtime_t ts)
{
  if (mid == 0 || jmaps == NULL)
    // special case: no Java stack was recorded, bci - error code
    return dbeSession->get_JUnknown_Function ()->find_dbeinstr (0, bci);

  JMethod *jmthd = jmidHTable->get (mid);
  if (jmthd == NULL)
    {
      jmthd = (JMethod *) jmaps->locate_exact_match (mid, ts);
      if (jmthd)
	jmidHTable->put (mid, jmthd);
    }
  if (jmthd == NULL || jmthd->get_type () != Histable::FUNCTION)
    return dbeSession->get_JUnknown_Function ()->find_dbeinstr (0, (uint64_t) mid);
  return jmthd->find_dbeinstr (0, bci);
}

Emsg *
Experiment::fetch_comments ()
{
  return commentq->fetch ();
}

Emsg *
Experiment::fetch_runlogq ()
{
  return runlogq->fetch ();
}

Emsg *
Experiment::fetch_errors ()
{
  return errorq->fetch ();
}

Emsg *
Experiment::fetch_warnings ()
{
  return warnq->fetch ();
}

Emsg *
Experiment::fetch_notes ()
{
  return notesq->fetch ();
}

Emsg *
Experiment::fetch_ifreq ()
{
  return ifreqq->fetch ();
}

Emsg *
Experiment::fetch_pprocq ()
{
  return pprocq->fetch ();
}

int
Experiment::read_dyntext_file ()
{
  dyntext_name = dbe_sprintf ("%s/%s", expt_name, SP_DYNTEXT_FILE);
  Data_window *dwin = new Data_window (dyntext_name);
  if (dwin->not_opened ())
    {
      delete dwin;
      return 1;
    }
  dwin->need_swap_endian = need_swap_endian;

  Function *fp = NULL;
  char *progress_msg = NULL; // Message for the progress bar
  for (int64_t offset = 0;;)
    {
      DT_common *cpckt = (DT_common *) dwin->bind (offset, sizeof (DT_common));
      if (cpckt == NULL)
	break;
      size_t cpcktsize = dwin->decode (cpckt->size);
      cpckt = (DT_common *) dwin->bind (offset, cpcktsize);
      if (cpckt == NULL)
	break;
      switch (dwin->decode (cpckt->type))
	{
	case DT_HEADER:
	  {
	    DT_header *hdr = (DT_header*) cpckt;
	    hrtime_t ts = dwin->decode (hdr->time) + exp_start_time;
	    SegMem *si = (SegMem*) maps->locate (dwin->decode (hdr->vaddr), ts);
	    fp = si ? (Function *) si->obj : NULL;
	    if (fp && (fp->get_type () != Histable::FUNCTION
		       || !(fp->flags & FUNC_FLAG_DYNAMIC)))
	      fp = NULL;
	    break;
	  }
	case DT_CODE:
	  if (fp)
	    {
	      fp->img_fname = dyntext_name;
	      fp->img_offset = offset + sizeof (DT_common);
	      if ((platform != Intel) && (platform != Amd64))
		{ //ARCH(SPARC)
		  // Find out 'save' instruction address for SPARC
		  char *ptr = ((char*) cpckt) + sizeof (DT_common);
		  size_t img_size = cpcktsize - sizeof (DT_common);
		  for (size_t i = 0; i < img_size; i += 4)
		    if (ptr[i] == (char) 0x9d && ptr[i + 1] == (char) 0xe3)
		      {
			fp->save_addr = i;
			break;
		      }
		}
	    }
	  break;
	case DT_SRCFILE:
	  if (fp)
	    {
	      char *srcname = dbe_strndup (((char*) cpckt) + sizeof (DT_common),
					   cpcktsize - sizeof (DT_common));
	      LoadObject *ds = fp->module ? fp->module->loadobject : NULL;
	      assert (ds != NULL);
	      Module *mod = dbeSession->createModule (ds, NULL);
	      mod->set_file_name (srcname);
	      //}
	      if (fp->module)
		{
		  // It's most likely (unknown). Remove fp from it.
		  long idx = fp->module->functions->find (fp);
		  if (idx >= 0)
		    fp->module->functions->remove (idx);
		}
	      fp->module = mod;
	      mod->functions->append (fp);
	    }
	  break;
	case DT_LTABLE:
	  if (fp)
	    {
	      DT_lineno *ltab = (DT_lineno*) ((char*) cpckt + sizeof (DT_common));
	      size_t sz = (cpcktsize - sizeof (DT_common)) / sizeof (DT_lineno);
	      if (sz <= 0)
		break;
	      // Take care of the progress bar
	      static int percent = 0;
	      static long deltaReport = sz / 100; // 1000;
	      static long nextReport = 0;
	      static long progress_count = 0;
	      fp->pushSrcFile (fp->getDefSrc (), 0);
	      for (size_t i = 0; i < sz; i++)
		{
		  int lineno = dwin->decode (ltab[i].lineno);
		  if (fp->usrfunc != NULL)
		    {
		      // Update progress bar
		      if (dbeSession->is_interactive ())
			{
			  if (progress_count == nextReport)
			    {
			      if (percent < 99)
				{
				  percent++;
				  if (NULL == progress_msg)
				    {
				      progress_msg = dbe_sprintf (GTXT ("Processing Dynamic Text: %s"),
								  get_basename (expt_name));
				    }
				  theApplication->set_progress (percent, progress_msg);
				  nextReport += deltaReport;
				}
			    }
			  progress_count++;
			}
		      DbeLine *dbeline = fp->usrfunc->mapPCtoLine (lineno, NULL);
		      lineno = dbeline != NULL ? dbeline->lineno : -1;
		    }
		  fp->add_PC_info (dwin->decode (ltab[i].offset), lineno);
		}
	      fp->popSrcFile ();
	    }
	  break;
	default:
	  // skip unknown records
	  break;
	}
      offset += cpcktsize;
    }
  free (progress_msg);
  delete dwin;
  return 0;
}

uint32_t
Experiment::mapTagValue (Prop_type prop, uint64_t value)
{
  Vector<Histable*> *objs = tagObjs->fetch (prop);
  int lt = 0;
  int rt = objs->size () - 1;
  while (lt <= rt)
    {
      int md = (lt + rt) / 2;
      Other *obj = (Other*) objs->fetch (md);
      if (obj->value64 < value)
	lt = md + 1;
      else if (obj->value64 > value)
	rt = md - 1;
      else
	return obj->tag;
    }

  uint32_t tag;
  if (sparse_threads && (prop == PROP_THRID || prop == PROP_LWPID))
    tag = objs->size () + 1; // "+ 1" related to 7038295
  else
    tag = (int) value; // truncation; See 6788767

  Other *obj = new Other ();
  obj->value64 = value;
  obj->tag = tag;
  if (lt == objs->size ())
    objs->append (obj);
  else
    objs->insert (lt, obj);

  // Update min and max tags
  if (prop == PROP_LWPID)
    {
      if ((uint64_t) tag < min_lwp)
	min_lwp = (uint64_t) tag;
      if ((uint64_t) tag > max_lwp)
	max_lwp = (uint64_t) tag;
      lwp_cnt++;
    }
  else if (prop == PROP_THRID)
    {
      if ((uint64_t) tag < min_thread)
	min_thread = (uint64_t) tag;
      if ((uint64_t) tag > max_thread)
	max_thread = (uint64_t) tag;
      thread_cnt++;
    }
  else if (prop == PROP_CPUID)
    {
      // On Solaris 8, we don't get CPU id -- don't change
      if (value != (uint64_t) - 1)
	{//YXXX is this related only to solaris 8?
	  if ((uint64_t) tag < min_cpu)
	    min_cpu = (uint64_t) tag;
	  if ((uint64_t) tag > max_cpu)
	    max_cpu = (uint64_t) tag;
	}
      cpu_cnt++;
    }
  return obj->tag;
}

Vector<Histable*> *
Experiment::getTagObjs (Prop_type prop)
{
  return tagObjs->fetch (prop);
}

Histable *
Experiment::getTagObj (Prop_type prop, uint32_t tag)
{
  Vector<Histable*> *objs = tagObjs->fetch (prop);
  if (objs == NULL)
    return NULL;
  for (int i = 0; i < objs->size (); i++)
    {
      Other *obj = (Other*) objs->fetch (i);
      if (obj->tag == tag)
	return obj;
    }
  return NULL;
}

JThread *
Experiment::map_pckt_to_Jthread (uint32_t tid, hrtime_t tstamp)
{
  if (!has_java)
    return JTHREAD_DEFAULT;
  int lt = 0;
  int rt = jthreads_idx->size () - 1;
  while (lt <= rt)
    {
      int md = (lt + rt) / 2;
      JThread *jthread = jthreads_idx->fetch (md);
      if (jthread->tid < tid)
	lt = md + 1;
      else if (jthread->tid > tid)
	rt = md - 1;
      else
	{
	  for (; jthread; jthread = jthread->next)
	    if (tstamp >= jthread->start && tstamp < jthread->end)
	      return jthread;
	  break;
	}
    }

  return JTHREAD_NONE;
}

JThread*
Experiment::get_jthread (uint32_t tid)
{
  if (!has_java)
    return JTHREAD_DEFAULT;
  int lt = 0;
  int rt = jthreads_idx->size () - 1;
  while (lt <= rt)
    {
      int md = (lt + rt) / 2;
      JThread *jthread = jthreads_idx->fetch (md);
      if (jthread->tid < tid)
	lt = md + 1;
      else if (jthread->tid > tid)
	rt = md - 1;
      else
	{
	  JThread *jthread_first = jthread;
	  while ((jthread = jthread->next) != NULL)
	    if (!jthread->is_system () &&
		jthread->jthr_id < jthread_first->jthr_id)
	      jthread_first = jthread;
	  return jthread_first;
	}
    }

  return JTHREAD_NONE;
}

// SS12 experiment
DataDescriptor *
Experiment::newDataDescriptor (int data_id, int flags,
			       DataDescriptor *master_dDscr)
{
  DataDescriptor *dataDscr = NULL;
  if (data_id >= 0 && data_id < dataDscrs->size ())
    {
      dataDscr = dataDscrs->fetch (data_id);
      if (dataDscr != NULL)
	return dataDscr;
    }

  assert (data_id >= 0 && data_id < DATA_LAST);
  const char *nm = get_prof_data_type_name (data_id);
  const char *uname = get_prof_data_type_uname (data_id);

  if (master_dDscr)
    dataDscr = new DataDescriptor (data_id, nm, uname, master_dDscr);
  else
    dataDscr = new DataDescriptor (data_id, nm, uname, flags);
  dataDscrs->store (data_id, dataDscr);
  return dataDscr;
}

Vector<DataDescriptor*> *
Experiment::getDataDescriptors ()
{
  Vector<DataDescriptor*> *result = new Vector<DataDescriptor*>;
  for (int i = 0; i < dataDscrs->size (); ++i)
    {
      DataDescriptor *dd;
      dd = get_raw_events (i); // force data fetch
      if (dd != NULL)
	result->append (dd);
    }
  return result;
}

DataDescriptor *
Experiment::getDataDescriptor (int data_id)
{
  if (data_id < 0 || data_id >= dataDscrs->size ())
    return NULL;
  return dataDscrs->fetch (data_id);
}

PacketDescriptor *
Experiment::newPacketDescriptor (int kind, DataDescriptor *dDscr)
{
  PacketDescriptor *pDscr = new PacketDescriptor (dDscr);
  pcktDscrs->store (kind, pDscr);
  return pDscr;
}

PacketDescriptor *
Experiment::getPacketDescriptor (int kind)
{
  if (kind < 0 || kind >= pcktDscrs->size ())
    return NULL;
  return pcktDscrs->fetch (kind);
}

void
Experiment::set_clock (int clk)
{
  if (clk > 0)
    {
      if (maxclock < clk)
	{
	  maxclock = clk;
	  clock = maxclock;
	}
      if (minclock == 0 || minclock > clk)
	minclock = clk;
    }
}

bool
JThread::is_system ()
{
  if (group_name == NULL)
    return false;
  return strcmp (group_name, NTXT ("system")) == 0;
}

void
Experiment::dump_stacks (FILE *outfile)
{
  cstack->print (outfile);
}

void
Experiment::dump_map (FILE *outfile)
{
  int index;
  SegMem *s;
  fprintf (outfile, GTXT ("Experiment %s\n"), get_expt_name ());
  fprintf (outfile, GTXT ("Address         Size (hex)              Load time     Unload time    Checksum  Name\n"));
  Vec_loop (SegMem*, seg_items, index, s)
  {
    timestruc_t load;
    timestruc_t unload;
    hr2timestruc (&load, (s->load_time - exp_start_time));
    if (load.tv_nsec < 0)
      {
	load.tv_sec--;
	load.tv_nsec += NANOSEC;
      }
    if (s->unload_time == MAX_TIME)
      {
	unload.tv_sec = 0;
	unload.tv_nsec = 0;
      }
    else
      hr2timestruc (&unload, (s->unload_time - exp_start_time));
    if (load.tv_nsec < 0)
      {
	load.tv_sec--;
	load.tv_nsec += NANOSEC;
      }
    fprintf (outfile,
	     "0x%08llx  %8lld (0x%08llx) %5lld.%09lld %5lld.%09lld  \"%s\"\n",
	     (long long) s->base, (long long) s->size, (long long) s->size,
	     (long long) load.tv_sec, (long long) load.tv_nsec,
	     (long long) unload.tv_sec, (long long) unload.tv_nsec,
	     s->obj->get_name ());
  }
  fprintf (outfile, NTXT ("\n"));
}

/**
 * Copy file to archive
 * @param name
 * @param aname
 * @param hide_msg
 * @return 0 - success, 1 - error
 */
int
Experiment::copy_file_to_archive (const char *name, const char *aname, int hide_msg)
{
  errno = 0;
  int fd_w = ::open64 (aname, O_WRONLY | O_CREAT | O_EXCL, 0644);
  if (fd_w == -1)
    {
      if (errno == EEXIST)
	return 0;
      fprintf (stderr, GTXT ("gp-archive: unable to copy `%s': %s\n"),
	       name, STR (strerror (errno)));
      return 1;
    }

  if (dbe_stat_file (name, NULL) != 0)
    {
      fprintf (stderr, GTXT ("gp-archive: cannot access file `%s': %s\n"),
	       name, STR (strerror (errno)));
      close (fd_w);
      return 1;
    }

  int fd_r = ::open64 (name, O_RDONLY);
  if (fd_r == -1)
    {
      fprintf (stderr, GTXT ("gp-archive: unable to open `%s': %s\n"),
	       name, strerror (errno));
      close (fd_w);
      unlink (aname);
      return 1;
    }

  if (!hide_msg)
    fprintf (stderr, GTXT ("Copying `%s'  to `%s'\n"), name, aname);
  bool do_unlink = false;
  for (;;)
    {
      unsigned char buf[65536];
      int n, n1;
      n = (int) read (fd_r, (void *) buf, sizeof (buf));
      if (n <= 0)
	break;
      n1 = (int) write (fd_w, buf, n);
      if (n != n1)
	{
	  fprintf (stderr, GTXT ("gp-archive: unable to write %d bytes to `%s': %s\n"),
		   n, aname, STR (strerror (errno)));
	  do_unlink = true;
	  break;
	}
    }
  close (fd_w);

  dbe_stat_t s_buf;
  if (fstat64 (fd_r, &s_buf) == 0)
    {
      struct utimbuf u_buf;
      u_buf.actime = s_buf.st_atime;
      u_buf.modtime = s_buf.st_mtime;
      utime (aname, &u_buf);
    }
  close (fd_r);
  if (do_unlink)
    {
      if (!hide_msg)
	fprintf (stderr, GTXT ("gp-archive: remove %s\n"), aname);
      unlink (aname);
      return 1;
    }
  return 0;
}

/**
 * Copy file to common archive
 * Algorithm:
 * Calculate checksum
 * Generate file name to be created in common archive
 * Check if it is not in common archive yet
 * Copy file to the common archive directory if it is not there yet
 * Create symbolic link: "aname" -> "caname", where "caname" is the name in common archive
 * @param name - original file name
 * @param aname - file name in experiment archive
 * @param common_archive - common archive directory
 * @return 0 - success, 1 - error
 */
int
Experiment::copy_file_to_common_archive (const char *name, const char *aname,
					 int hide_msg,
					 const char *common_archive,
					 int relative_path)
{
  if (!name || !aname || !common_archive)
    {
      if (!name)
	fprintf (stderr, GTXT ("gp-archive: Internal error: file name is NULL\n"));
      if (!aname)
	fprintf (stderr, GTXT ("gp-archive: Internal error: file name in archive is NULL\n"));
      if (!common_archive)
	fprintf (stderr, GTXT ("gp-archive: Internal error: path to common archive is NULL\n"));
      return 1;
    }
  // Check if file is already archived
  if (dbe_stat (aname, NULL) == 0)
    return 0; // File is already archived
  // Generate full path to common archive directory
  char *cad = NULL;
  char *abs_aname = NULL;
  if ((common_archive[0] != '/') || (aname[0] != '/'))
    {
      long size = pathconf (NTXT ("."), _PC_PATH_MAX);
      if (size < 0)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: pathconf(\".\", _PC_PATH_MAX) failed\n"));
	  return 1;
	}
      char *buf = (char *) malloc ((size_t) size);
      if (buf == NULL)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: unable to allocate memory\n"));
	  return 1;
	}
      char *ptr = getcwd (buf, (size_t) size);
      if (ptr == NULL)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: cannot determine current directory\n"));
	  free (buf);
	  return 1;
	}
      if (common_archive[0] != '/')
	cad = dbe_sprintf (NTXT ("%s/%s"), ptr, common_archive);
      else
	cad = dbe_strdup (common_archive);
      if (aname[0] != '/')
	abs_aname = dbe_sprintf (NTXT ("%s/%s"), ptr, aname);
      else
	abs_aname = dbe_strdup (aname);
      free (buf);
    }
  else
    {
      cad = dbe_strdup (common_archive);
      abs_aname = dbe_strdup (aname);
    }
  // Calculate checksum
  char * errmsg = NULL;
  uint32_t crcval = get_cksum (name, &errmsg);
  if (0 == crcval)
    { // error
      free (cad);
      free (abs_aname);
      if (NULL != errmsg)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: %s\n"), errmsg);
	  free (errmsg);
	  return 1;
	}
      fprintf (stderr,
	       GTXT ("gp-archive: Fatal error: get_cksum(%s) returned %d\n"),
	       name, crcval);
      return 1;
    }
  // Generate file name to be created in common archive
  char *fname = get_basename (name);
  char *abs_caname = dbe_sprintf (NTXT ("%s/%u_%s"), cad, crcval, fname);
  if (abs_caname == NULL)
    {
      free (cad);
      free (abs_aname);
      fprintf (stderr,
	       GTXT ("gp-archive: Fatal error: unable to allocate memory\n"));
      return 1;
    }
  // Check if full name is not too long
  long len = dbe_sstrlen (abs_caname);
  long max = pathconf (cad, _PC_PATH_MAX);
  if ((max < 0) || (len <= 0))
    { // unknown error
      fprintf (stderr, GTXT ("gp-archive: Fatal error: pathconf(%s, _PC_PATH_MAX) failed\n"),
	       cad);
      free (abs_caname);
      free (cad);
      free (abs_aname);
      return 1;
    }
  if (len >= max)
    {
      // Try to truncate the name
      if ((len - max) <= dbe_sstrlen (fname))
	{
	  // Yes, we can do it
	  abs_caname[max - 1] = 0;
	  if (!hide_msg)
	    fprintf (stderr, GTXT ("gp-gp-archive: file path is too long - truncated:%s\n"),
		     abs_caname);
	}
    }
  // Check if file name is not too long
  char *cafname = get_basename (abs_caname);
  len = dbe_sstrlen (cafname);
  max = pathconf (cad, _PC_NAME_MAX);
  if ((max < 0) || (len <= 0))
    { // unknown error
      fprintf (stderr, GTXT ("gp-archive: Fatal error: pathconf(%s, _PC_NAME_MAX) failed\n"),
	       cad);
      free (abs_caname);
      free (cad);
      free (abs_aname);
      return 1;
    }
  if (len >= max)
    {
      // Try to truncate the name
      if ((len - max) <= dbe_sstrlen (fname))
	{
	  // Yes, we can do it
	  cafname[max - 1] = 0;
	  if (!hide_msg)
	    fprintf (stderr, GTXT ("gp-archive: file name is too long - truncated:%s\n"),
		     abs_caname);
	}
    }
  // Copy file to the common archive directory if it is not there yet
  int res = 0;
  if (dbe_stat_file (abs_caname, NULL) != 0)
    {
      // Use temporary file to avoid synchronization problems
      char *t = dbe_sprintf ("%s/archive_%llx", cad, (unsigned long long) gethrtime());
      free (cad);
      // Copy file to temporary file
      res = copy_file_to_archive (name, t, hide_msg); // hide messages
      if (res != 0)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: cannot copy file %s to temporary file: %s\n"),
		   name, t);
	  unlink (t);
	  free (t);
	  free (abs_caname);
	  free (abs_aname);
	  return 1;
	}
      // Set read-only permissions
      dbe_stat_t statbuf;
      if (0 == dbe_stat_file (name, &statbuf))
	{
	  mode_t mask = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
	  mode_t mode = statbuf.st_mode & mask;
	  chmod (t, mode);
	}
      // Try to rename temporary file "t" to "abs_caname"
      // res = link(t, abs_caname); // link() fails on some f/s - use rename()
      res = rename (t, abs_caname);
      if (res != 0)
	{
	  if (errno != EEXIST)
	    {
	      fprintf (stderr, GTXT ("gp-archive: Fatal error: rename(%s, %s) returned error: %d\n"),
		       t, abs_caname, res);
	      unlink (t);
	      free (t);
	      free (abs_caname);
	      free (abs_aname);
	      return 1;
	    }
	  // File "abs_caname" is already there - continue
	}
      unlink (t);
      free (t);
    }
  else
    free (cad);
  char *lname = NULL;
  if (relative_path)
    {
      if (common_archive[0] != '/' && aname[0] != '/')
	{
	  // compare one relative path to another and find common beginning
	  char *rel_caname = dbe_sprintf ("%s/%s", common_archive, cafname);
	  if (rel_caname == NULL)
	    {
	      fprintf (stderr, GTXT ("gp-archive: Fatal error: unable to allocate memory\n"));
	      return 1;
	    }
	  lname = get_relative_link (rel_caname, aname);
	  free (rel_caname);
	}
      else
	{
	  if (abs_aname == NULL)
	    {
	      fprintf (stderr, GTXT ("gp-archive: Fatal error: unable to allocate memory\n"));
	      return 1;
	    }
	  lname = get_relative_link (abs_caname, abs_aname);
	}
    }
  else  // absolute path
    lname = dbe_strdup (abs_caname);
  free (abs_aname);
  if (lname == NULL)
    {
      fprintf (stderr, GTXT ("gp-archive: Fatal error: unable to allocate memory\n"));
      return 1;
    }
  // Create symbolic link: aname -> lname
  if (dbe_stat_file (abs_caname, NULL) == 0)
    {
      res = symlink (lname, aname);
      if (res != 0)
	{
	  fprintf (stderr, GTXT ("gp-archive: Fatal error: symlink(%s, %s) returned error: %d (errno=%s)\n"),
		   lname, aname, res, strerror (errno));
	  free (abs_caname);
	  free (lname);
	  return 1;
	}
      if (!hide_msg)
	fprintf (stderr, GTXT ("Created symbolic link %s to file in common archive: %s\n"),
		 aname, lname);
    }
  else
    {
      fprintf (stderr, GTXT ("gp-archive: Internal error: file does not exist in common archive: %s\n"),
	       abs_caname);
      res = 1;
    }
  free (abs_caname);
  free (lname);
  return res;
}

/**
 * Copy file to archive
 * @param name
 * @param aname
 * @param hide_msg
 * @param common_archive
 * @return 0 - success
 */
int
Experiment::copy_file (char *name, char *aname, int hide_msg, char *common_archive, int relative_path)
{
  if (common_archive)
    {
      if (0 == copy_file_to_common_archive (name, aname, hide_msg,
					    common_archive, relative_path))
	return 0;
      // Error. For now - fatal error. Message is already printed.
      fprintf (stderr, GTXT ("gp-archive: Fatal error: cannot copy file %s to common archive %s\n"),
	       name, common_archive);
      return 1;
    }
  return (copy_file_to_archive (name, aname, hide_msg));
}

LoadObject *
Experiment::createLoadObject (const char *path, uint64_t chksum)
{
  LoadObject *lo = dbeSession->createLoadObject (path, chksum);
  if (lo->firstExp == NULL)
    lo->firstExp = this;
  return lo;
}

LoadObject *
Experiment::createLoadObject (const char *path, const char *runTimePath)
{
  DbeFile *df = findFileInArchive (path, runTimePath);
  if (df && (df->get_stat () == NULL))
    df = NULL; // No access to file
  LoadObject *lo = dbeSession->createLoadObject (path, runTimePath, df);
  if (df && (lo->dbeFile->get_location (false) == NULL))
    {
      lo->dbeFile->set_location (df->get_location ());
      lo->dbeFile->inArchive = df->inArchive;
      lo->dbeFile->sbuf = df->sbuf;
      lo->dbeFile->experiment = df->experiment;
      lo->firstExp = df->experiment;
    }
  if (lo->firstExp == NULL)
    {
      lo->firstExp = this;
      lo->dbeFile->experiment = this;
    }
  return lo;
}

SourceFile *
Experiment::get_source (const char *path)
{
  if (founder_exp && (founder_exp != this))
    return founder_exp->get_source (path);
  if (sourcesMap == NULL)
    sourcesMap = new StringMap<SourceFile*>(1024, 1024);
  if (strncmp (path, NTXT ("./"), 2) == 0)
    path += 2;
  SourceFile *sf = sourcesMap->get (path);
  if (sf)
    return sf;
  char *fnm = checkFileInArchive (path, false);
  if (fnm)
    {
      sf = new SourceFile (path);
      dbeSession->append (sf);
      DbeFile *df = sf->dbeFile;
      df->set_location (fnm);
      df->inArchive = true;
      df->check_access (fnm); // init 'sbuf'
      df->sbuf.st_mtime = 0; // Don't check timestamps
      free (fnm);
    }
  else
    sf = dbeSession->createSourceFile (path);
  sourcesMap->put (path, sf);
  return sf;
}

Vector<Histable*> *
Experiment::get_comparable_objs ()
{
  update_comparable_objs ();
  if (comparable_objs || dbeSession->expGroups->size () <= 1)
    return comparable_objs;
  comparable_objs = new Vector<Histable*>(dbeSession->expGroups->size ());
  for (long i = 0, sz = dbeSession->expGroups->size (); i < sz; i++)
    {
      ExpGroup *gr = dbeSession->expGroups->get (i);
      if (groupId == gr->groupId)
	{
	  comparable_objs->append (this);
	  continue;
	}
      Histable *h = NULL;
      for (long i1 = 0, sz1 = gr->exps ? gr->exps->size () : 0; i1 < sz1; i1++)
	{
	  Experiment *exp = gr->exps->get (i1);
	  if ((exp->comparable_objs == NULL) && (dbe_strcmp (utargname, exp->utargname) == 0))
	    {
	      exp->phaseCompareIdx = phaseCompareIdx;
	      h = exp;
	      h->comparable_objs = comparable_objs;
	      break;
	    }
	}
      comparable_objs->append (h);
    }
  dump_comparable_objs ();
  return comparable_objs;
}

DbeFile *
Experiment::findFileInArchive (const char *fname)
{
  if (archiveMap)
    {
      char *aname = get_archived_name (fname);
      DbeFile *df = archiveMap->get (aname);
      free (aname);
      return df;
    }
  if (founder_exp)
    return founder_exp->findFileInArchive (fname);
  return NULL;
}

DbeFile *
Experiment::findFileInArchive (const char *className, const char *runTimePath)
{
  DbeFile *df = NULL;
  if (runTimePath)
    {
      const char *fnm = NULL;
      if (strncmp (runTimePath, NTXT ("zip:"), 4) == 0)
	fnm = runTimePath + 4;
      else if (strncmp (runTimePath, NTXT ("jar:file:"), 9) == 0)
	fnm = runTimePath + 9;
      if (fnm)
	{
	  const char *s = strchr (fnm, '!');
	  if (s)
	    {
	      char *s1 = dbe_strndup (fnm, s - fnm);
	      df = findFileInArchive (s1);
	      free (s1);
	    }
	  else
	    df = findFileInArchive (fnm);
	  if (df)
	    df->filetype |= DbeFile::F_JAR_FILE;
	}
      else if (strncmp (runTimePath, NTXT ("file:"), 5) == 0)
	{
	  fnm = runTimePath + 5;
	  df = findFileInArchive (fnm);
	}
      else
	df = findFileInArchive (runTimePath);
    }
  if (df == NULL)
    df = findFileInArchive (className);
  return df;
}
