/** @file kmp_stats.cpp
 * Statistics gathering and processing.
 */

//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//

#include "kmp.h"
#include "kmp_lock.h"
#include "kmp_stats.h"
#include "kmp_str.h"

#include <algorithm>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <stdlib.h> // for atexit

#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)

#define expandName(name, flags, ignore) {STRINGIZE(name), flags},
statInfo timeStat::timerInfo[] = {
    KMP_FOREACH_TIMER(expandName, 0){"TIMER_LAST", 0}};
const statInfo counter::counterInfo[] = {
    KMP_FOREACH_COUNTER(expandName, 0){"COUNTER_LAST", 0}};
#undef expandName

#define expandName(ignore1, ignore2, ignore3) {0.0, 0.0, 0.0},
kmp_stats_output_module::rgb_color kmp_stats_output_module::timerColorInfo[] = {
    KMP_FOREACH_TIMER(expandName, 0){0.0, 0.0, 0.0}};
#undef expandName

const kmp_stats_output_module::rgb_color
    kmp_stats_output_module::globalColorArray[] = {
        {1.0, 0.0, 0.0}, // red
        {1.0, 0.6, 0.0}, // orange
        {1.0, 1.0, 0.0}, // yellow
        {0.0, 1.0, 0.0}, // green
        {0.0, 0.0, 1.0}, // blue
        {0.6, 0.2, 0.8}, // purple
        {1.0, 0.0, 1.0}, // magenta
        {0.0, 0.4, 0.2}, // dark green
        {1.0, 1.0, 0.6}, // light yellow
        {0.6, 0.4, 0.6}, // dirty purple
        {0.0, 1.0, 1.0}, // cyan
        {1.0, 0.4, 0.8}, // pink
        {0.5, 0.5, 0.5}, // grey
        {0.8, 0.7, 0.5}, // brown
        {0.6, 0.6, 1.0}, // light blue
        {1.0, 0.7, 0.5}, // peach
        {0.8, 0.5, 1.0}, // lavender
        {0.6, 0.0, 0.0}, // dark red
        {0.7, 0.6, 0.0}, // gold
        {0.0, 0.0, 0.0} // black
};

// Ensure that the atexit handler only runs once.
static uint32_t statsPrinted = 0;

// output interface
static kmp_stats_output_module *__kmp_stats_global_output = NULL;

/* ************* statistic member functions ************* */

void statistic::addSample(double sample) {
  double delta = sample - meanVal;

  sampleCount = sampleCount + 1;
  meanVal = meanVal + delta / sampleCount;
  m2 = m2 + delta * (sample - meanVal);

  minVal = std::min(minVal, sample);
  maxVal = std::max(maxVal, sample);
}

statistic &statistic::operator+=(const statistic &other) {
  if (sampleCount == 0) {
    *this = other;
    return *this;
  }

  uint64_t newSampleCount = sampleCount + other.sampleCount;
  double dnsc = double(newSampleCount);
  double dsc = double(sampleCount);
  double dscBydnsc = dsc / dnsc;
  double dosc = double(other.sampleCount);
  double delta = other.meanVal - meanVal;

  // Try to order these calculations to avoid overflows. If this were Fortran,
  // then the compiler would not be able to re-order over brackets. In C++ it
  // may be legal to do that (we certainly hope it doesn't, and CC+ Programming
  // Language 2nd edition suggests it shouldn't, since it says that exploitation
  // of associativity can only be made if the operation really is associative
  // (which floating addition isn't...)).
  meanVal = meanVal * dscBydnsc + other.meanVal * (1 - dscBydnsc);
  m2 = m2 + other.m2 + dscBydnsc * dosc * delta * delta;
  minVal = std::min(minVal, other.minVal);
  maxVal = std::max(maxVal, other.maxVal);
  sampleCount = newSampleCount;

  return *this;
}

void statistic::scale(double factor) {
  minVal = minVal * factor;
  maxVal = maxVal * factor;
  meanVal = meanVal * factor;
  m2 = m2 * factor * factor;
  return;
}

std::string statistic::format(char unit, bool total) const {
  std::string result = formatSI(sampleCount, 9, ' ');

  if (sampleCount == 0) {
    result = result + std::string(", ") + formatSI(0.0, 9, unit);
    result = result + std::string(", ") + formatSI(0.0, 9, unit);
    result = result + std::string(", ") + formatSI(0.0, 9, unit);
    if (total)
      result = result + std::string(", ") + formatSI(0.0, 9, unit);
    result = result + std::string(", ") + formatSI(0.0, 9, unit);
  } else {
    result = result + std::string(", ") + formatSI(minVal, 9, unit);
    result = result + std::string(", ") + formatSI(meanVal, 9, unit);
    result = result + std::string(", ") + formatSI(maxVal, 9, unit);
    if (total)
      result =
          result + std::string(", ") + formatSI(meanVal * sampleCount, 9, unit);
    result = result + std::string(", ") + formatSI(getSD(), 9, unit);
  }
  return result;
}

/* ************* explicitTimer member functions ************* */

void explicitTimer::start(timer_e timerEnumValue) {
  startTime = tsc_tick_count::now();
  totalPauseTime = 0;
  if (timeStat::logEvent(timerEnumValue)) {
    __kmp_stats_thread_ptr->incrementNestValue();
  }
  return;
}

void explicitTimer::stop(timer_e timerEnumValue,
                         kmp_stats_list *stats_ptr /* = nullptr */) {
  if (startTime.getValue() == 0)
    return;

  tsc_tick_count finishTime = tsc_tick_count::now();

  // stat->addSample ((tsc_tick_count::now() - startTime).ticks());
  stat->addSample(((finishTime - startTime) - totalPauseTime).ticks());

  if (timeStat::logEvent(timerEnumValue)) {
    if (!stats_ptr)
      stats_ptr = __kmp_stats_thread_ptr;
    stats_ptr->push_event(
        startTime.getValue() - __kmp_stats_start_time.getValue(),
        finishTime.getValue() - __kmp_stats_start_time.getValue(),
        __kmp_stats_thread_ptr->getNestValue(), timerEnumValue);
    stats_ptr->decrementNestValue();
  }

  /* We accept the risk that we drop a sample because it really did start at
     t==0. */
  startTime = 0;
  return;
}

/* ************* partitionedTimers member functions ************* */
partitionedTimers::partitionedTimers() { timer_stack.reserve(8); }

// add a timer to this collection of partitioned timers.
void partitionedTimers::add_timer(explicit_timer_e timer_index,
                                  explicitTimer *timer_pointer) {
  KMP_DEBUG_ASSERT((int)timer_index < (int)EXPLICIT_TIMER_LAST + 1);
  timers[timer_index] = timer_pointer;
}

// initialize the paritioned timers to an initial timer
void partitionedTimers::init(timerPair init_timer_pair) {
  KMP_DEBUG_ASSERT(this->timer_stack.size() == 0);
  timer_stack.push_back(init_timer_pair);
  timers[init_timer_pair.get_index()]->start(init_timer_pair.get_timer());
}

// stop/save the current timer, and start the new timer (timer_pair)
// There is a special condition where if the current timer is equal to
// the one you are trying to push, then it only manipulates the stack,
// and it won't stop/start the currently running timer.
void partitionedTimers::push(timerPair timer_pair) {
  // get the current timer
  // stop current timer
  // push new timer
  // start the new timer
  KMP_DEBUG_ASSERT(this->timer_stack.size() > 0);
  timerPair current_timer = timer_stack.back();
  timer_stack.push_back(timer_pair);
  if (current_timer != timer_pair) {
    timers[current_timer.get_index()]->pause();
    timers[timer_pair.get_index()]->start(timer_pair.get_timer());
  }
}

// stop/discard the current timer, and start the previously saved timer
void partitionedTimers::pop() {
  // get the current timer
  // stop current timer
  // pop current timer
  // get the new current timer and start it back up
  KMP_DEBUG_ASSERT(this->timer_stack.size() > 1);
  timerPair current_timer = timer_stack.back();
  timer_stack.pop_back();
  timerPair new_timer = timer_stack.back();
  if (current_timer != new_timer) {
    timers[current_timer.get_index()]->stop(current_timer.get_timer());
    timers[new_timer.get_index()]->resume();
  }
}

// Wind up all the currently running timers.
// This pops off all the timers from the stack and clears the stack
// After this is called, init() must be run again to initialize the
// stack of timers
void partitionedTimers::windup() {
  while (timer_stack.size() > 1) {
    this->pop();
  }
  if (timer_stack.size() > 0) {
    timerPair last_timer = timer_stack.back();
    timer_stack.pop_back();
    timers[last_timer.get_index()]->stop(last_timer.get_timer());
  }
}

/* ************* kmp_stats_event_vector member functions ************* */

void kmp_stats_event_vector::deallocate() {
  __kmp_free(events);
  internal_size = 0;
  allocated_size = 0;
  events = NULL;
}

// This function is for qsort() which requires the compare function to return
// either a negative number if event1 < event2, a positive number if event1 >
// event2 or zero if event1 == event2. This sorts by start time (lowest to
// highest).
int compare_two_events(const void *event1, const void *event2) {
  kmp_stats_event *ev1 = (kmp_stats_event *)event1;
  kmp_stats_event *ev2 = (kmp_stats_event *)event2;

  if (ev1->getStart() < ev2->getStart())
    return -1;
  else if (ev1->getStart() > ev2->getStart())
    return 1;
  else
    return 0;
}

void kmp_stats_event_vector::sort() {
  qsort(events, internal_size, sizeof(kmp_stats_event), compare_two_events);
}

/* ************* kmp_stats_list member functions ************* */

// returns a pointer to newly created stats node
kmp_stats_list *kmp_stats_list::push_back(int gtid) {
  kmp_stats_list *newnode =
      (kmp_stats_list *)__kmp_allocate(sizeof(kmp_stats_list));
  // placement new, only requires space and pointer and initializes (so
  // __kmp_allocate instead of C++ new[] is used)
  new (newnode) kmp_stats_list();
  newnode->setGtid(gtid);
  newnode->prev = this->prev;
  newnode->next = this;
  newnode->prev->next = newnode;
  newnode->next->prev = newnode;
  return newnode;
}
void kmp_stats_list::deallocate() {
  kmp_stats_list *ptr = this->next;
  kmp_stats_list *delptr = this->next;
  while (ptr != this) {
    delptr = ptr;
    ptr = ptr->next;
    // placement new means we have to explicitly call destructor.
    delptr->_event_vector.deallocate();
    delptr->~kmp_stats_list();
    __kmp_free(delptr);
  }
}
kmp_stats_list::iterator kmp_stats_list::begin() {
  kmp_stats_list::iterator it;
  it.ptr = this->next;
  return it;
}
kmp_stats_list::iterator kmp_stats_list::end() {
  kmp_stats_list::iterator it;
  it.ptr = this;
  return it;
}
int kmp_stats_list::size() {
  int retval;
  kmp_stats_list::iterator it;
  for (retval = 0, it = begin(); it != end(); it++, retval++) {
  }
  return retval;
}

/* ************* kmp_stats_list::iterator member functions ************* */

kmp_stats_list::iterator::iterator() : ptr(NULL) {}
kmp_stats_list::iterator::~iterator() {}
kmp_stats_list::iterator kmp_stats_list::iterator::operator++() {
  this->ptr = this->ptr->next;
  return *this;
}
kmp_stats_list::iterator kmp_stats_list::iterator::operator++(int dummy) {
  this->ptr = this->ptr->next;
  return *this;
}
kmp_stats_list::iterator kmp_stats_list::iterator::operator--() {
  this->ptr = this->ptr->prev;
  return *this;
}
kmp_stats_list::iterator kmp_stats_list::iterator::operator--(int dummy) {
  this->ptr = this->ptr->prev;
  return *this;
}
bool kmp_stats_list::iterator::operator!=(const kmp_stats_list::iterator &rhs) {
  return this->ptr != rhs.ptr;
}
bool kmp_stats_list::iterator::operator==(const kmp_stats_list::iterator &rhs) {
  return this->ptr == rhs.ptr;
}
kmp_stats_list *kmp_stats_list::iterator::operator*() const {
  return this->ptr;
}

/* *************  kmp_stats_output_module functions ************** */

const char *kmp_stats_output_module::eventsFileName = NULL;
const char *kmp_stats_output_module::plotFileName = NULL;
int kmp_stats_output_module::printPerThreadFlag = 0;
int kmp_stats_output_module::printPerThreadEventsFlag = 0;

// init() is called very near the beginning of execution time in the constructor
// of __kmp_stats_global_output
void kmp_stats_output_module::init() {
  char *statsFileName = getenv("KMP_STATS_FILE");
  eventsFileName = getenv("KMP_STATS_EVENTS_FILE");
  plotFileName = getenv("KMP_STATS_PLOT_FILE");
  char *threadStats = getenv("KMP_STATS_THREADS");
  char *threadEvents = getenv("KMP_STATS_EVENTS");

  // set the stats output filenames based on environment variables and defaults
  if (statsFileName) {
    // append the process id to the output filename
    // events.csv --> events-pid.csv
    size_t index;
    std::string baseFileName, pid, suffix;
    std::stringstream ss;
    outputFileName = std::string(statsFileName);
    index = outputFileName.find_last_of('.');
    if (index == std::string::npos) {
      baseFileName = outputFileName;
    } else {
      baseFileName = outputFileName.substr(0, index);
      suffix = outputFileName.substr(index);
    }
    ss << getpid();
    pid = ss.str();
    outputFileName = baseFileName + "-" + pid + suffix;
  }
  eventsFileName = eventsFileName ? eventsFileName : "events.dat";
  plotFileName = plotFileName ? plotFileName : "events.plt";

  // set the flags based on environment variables matching: true, on, 1, .true.
  // , .t. , yes
  printPerThreadFlag = __kmp_str_match_true(threadStats);
  printPerThreadEventsFlag = __kmp_str_match_true(threadEvents);

  if (printPerThreadEventsFlag) {
    // assigns a color to each timer for printing
    setupEventColors();
  } else {
    // will clear flag so that no event will be logged
    timeStat::clearEventFlags();
  }

  return;
}

void kmp_stats_output_module::setupEventColors() {
  int i;
  int globalColorIndex = 0;
  int numGlobalColors = sizeof(globalColorArray) / sizeof(rgb_color);
  for (i = 0; i < TIMER_LAST; i++) {
    if (timeStat::logEvent((timer_e)i)) {
      timerColorInfo[i] = globalColorArray[globalColorIndex];
      globalColorIndex = (globalColorIndex + 1) % numGlobalColors;
    }
  }
  return;
}

void kmp_stats_output_module::printTimerStats(FILE *statsOut,
                                              statistic const *theStats,
                                              statistic const *totalStats) {
  fprintf(statsOut, "Timer,                      SampleCount,    Min,      "
                    "Mean,       Max,     Total,        SD\n");
  for (timer_e s = timer_e(0); s < TIMER_LAST; s = timer_e(s + 1)) {
    statistic const *stat = &theStats[s];
    char tag = timeStat::noUnits(s) ? ' ' : 'T';

    fprintf(statsOut, "%-28s, %s\n", timeStat::name(s),
            stat->format(tag, true).c_str());
  }
  // Also print the Total_ versions of times.
  for (timer_e s = timer_e(0); s < TIMER_LAST; s = timer_e(s + 1)) {
    char tag = timeStat::noUnits(s) ? ' ' : 'T';
    if (totalStats && !timeStat::noTotal(s))
      fprintf(statsOut, "Total_%-22s, %s\n", timeStat::name(s),
              totalStats[s].format(tag, true).c_str());
  }
}

void kmp_stats_output_module::printCounterStats(FILE *statsOut,
                                                statistic const *theStats) {
  fprintf(statsOut, "Counter,                 ThreadCount,    Min,      Mean,  "
                    "     Max,     Total,        SD\n");
  for (int s = 0; s < COUNTER_LAST; s++) {
    statistic const *stat = &theStats[s];
    fprintf(statsOut, "%-25s, %s\n", counter::name(counter_e(s)),
            stat->format(' ', true).c_str());
  }
}

void kmp_stats_output_module::printCounters(FILE *statsOut,
                                            counter const *theCounters) {
  // We print all the counters even if they are zero.
  // That makes it easier to slice them into a spreadsheet if you need to.
  fprintf(statsOut, "\nCounter,                    Count\n");
  for (int c = 0; c < COUNTER_LAST; c++) {
    counter const *stat = &theCounters[c];
    fprintf(statsOut, "%-25s, %s\n", counter::name(counter_e(c)),
            formatSI(stat->getValue(), 9, ' ').c_str());
  }
}

void kmp_stats_output_module::printEvents(FILE *eventsOut,
                                          kmp_stats_event_vector *theEvents,
                                          int gtid) {
  // sort by start time before printing
  theEvents->sort();
  for (int i = 0; i < theEvents->size(); i++) {
    kmp_stats_event ev = theEvents->at(i);
    rgb_color color = getEventColor(ev.getTimerName());
    fprintf(eventsOut, "%d %lu %lu %1.1f rgb(%1.1f,%1.1f,%1.1f) %s\n", gtid,
            ev.getStart(), ev.getStop(), 1.2 - (ev.getNestLevel() * 0.2),
            color.r, color.g, color.b, timeStat::name(ev.getTimerName()));
  }
  return;
}

void kmp_stats_output_module::windupExplicitTimers() {
  // Wind up any explicit timers. We assume that it's fair at this point to just
  // walk all the explcit timers in all threads and say "it's over".
  // If the timer wasn't running, this won't record anything anyway.
  kmp_stats_list::iterator it;
  for (it = __kmp_stats_list->begin(); it != __kmp_stats_list->end(); it++) {
    kmp_stats_list *ptr = *it;
    ptr->getPartitionedTimers()->windup();
    for (int timer = 0; timer < EXPLICIT_TIMER_LAST; timer++) {
      ptr->getExplicitTimer(explicit_timer_e(timer))->stop((timer_e)timer, ptr);
    }
  }
}

void kmp_stats_output_module::printPloticusFile() {
  int i;
  int size = __kmp_stats_list->size();
  FILE *plotOut = fopen(plotFileName, "w+");

  fprintf(plotOut, "#proc page\n"
                   "   pagesize: 15 10\n"
                   "   scale: 1.0\n\n");

  fprintf(plotOut, "#proc getdata\n"
                   "   file: %s\n\n",
          eventsFileName);

  fprintf(plotOut, "#proc areadef\n"
                   "   title: OpenMP Sampling Timeline\n"
                   "   titledetails: align=center size=16\n"
                   "   rectangle: 1 1 13 9\n"
                   "   xautorange: datafield=2,3\n"
                   "   yautorange: -1 %d\n\n",
          size);

  fprintf(plotOut, "#proc xaxis\n"
                   "   stubs: inc\n"
                   "   stubdetails: size=12\n"
                   "   label: Time (ticks)\n"
                   "   labeldetails: size=14\n\n");

  fprintf(plotOut, "#proc yaxis\n"
                   "   stubs: inc 1\n"
                   "   stubrange: 0 %d\n"
                   "   stubdetails: size=12\n"
                   "   label: Thread #\n"
                   "   labeldetails: size=14\n\n",
          size - 1);

  fprintf(plotOut, "#proc bars\n"
                   "   exactcolorfield: 5\n"
                   "   axis: x\n"
                   "   locfield: 1\n"
                   "   segmentfields: 2 3\n"
                   "   barwidthfield: 4\n\n");

  // create legend entries corresponding to the timer color
  for (i = 0; i < TIMER_LAST; i++) {
    if (timeStat::logEvent((timer_e)i)) {
      rgb_color c = getEventColor((timer_e)i);
      fprintf(plotOut, "#proc legendentry\n"
                       "   sampletype: color\n"
                       "   label: %s\n"
                       "   details: rgb(%1.1f,%1.1f,%1.1f)\n\n",
              timeStat::name((timer_e)i), c.r, c.g, c.b);
    }
  }

  fprintf(plotOut, "#proc legend\n"
                   "   format: down\n"
                   "   location: max max\n\n");
  fclose(plotOut);
  return;
}

/* Print some useful information about
   * the date and time this experiment ran.
   * the machine on which it ran.
   We output all of this as stylised comments, though we may decide to parse
   some of it. */
void kmp_stats_output_module::printHeaderInfo(FILE *statsOut) {
  std::time_t now = std::time(0);
  char buffer[40];
  char hostName[80];

  std::strftime(&buffer[0], sizeof(buffer), "%c", std::localtime(&now));
  fprintf(statsOut, "# Time of run: %s\n", &buffer[0]);
  if (gethostname(&hostName[0], sizeof(hostName)) == 0)
    fprintf(statsOut, "# Hostname: %s\n", &hostName[0]);
#if KMP_ARCH_X86 || KMP_ARCH_X86_64
  fprintf(statsOut, "# CPU:  %s\n", &__kmp_cpuinfo.name[0]);
  fprintf(statsOut, "# Family: %d, Model: %d, Stepping: %d\n",
          __kmp_cpuinfo.family, __kmp_cpuinfo.model, __kmp_cpuinfo.stepping);
  if (__kmp_cpuinfo.frequency == 0)
    fprintf(statsOut, "# Nominal frequency: Unknown\n");
  else
    fprintf(statsOut, "# Nominal frequency: %sz\n",
            formatSI(double(__kmp_cpuinfo.frequency), 9, 'H').c_str());
#endif
}

void kmp_stats_output_module::outputStats(const char *heading) {
  // Stop all the explicit timers in all threads
  // Do this before declaring the local statistics because thay have
  // constructors so will take time to create.
  windupExplicitTimers();

  statistic allStats[TIMER_LAST];
  statistic totalStats[TIMER_LAST]; /* Synthesized, cross threads versions of
                                       normal timer stats */
  statistic allCounters[COUNTER_LAST];

  FILE *statsOut =
      !outputFileName.empty() ? fopen(outputFileName.c_str(), "a+") : stderr;
  if (!statsOut)
    statsOut = stderr;

  FILE *eventsOut;
  if (eventPrintingEnabled()) {
    eventsOut = fopen(eventsFileName, "w+");
  }

  printHeaderInfo(statsOut);
  fprintf(statsOut, "%s\n", heading);
  // Accumulate across threads.
  kmp_stats_list::iterator it;
  for (it = __kmp_stats_list->begin(); it != __kmp_stats_list->end(); it++) {
    int t = (*it)->getGtid();
    // Output per thread stats if requested.
    if (printPerThreadFlag) {
      fprintf(statsOut, "Thread %d\n", t);
      printTimerStats(statsOut, (*it)->getTimers(), 0);
      printCounters(statsOut, (*it)->getCounters());
      fprintf(statsOut, "\n");
    }
    // Output per thread events if requested.
    if (eventPrintingEnabled()) {
      kmp_stats_event_vector events = (*it)->getEventVector();
      printEvents(eventsOut, &events, t);
    }

    // Accumulate timers.
    for (timer_e s = timer_e(0); s < TIMER_LAST; s = timer_e(s + 1)) {
      // See if we should ignore this timer when aggregating
      if ((timeStat::masterOnly(s) && (t != 0)) || // Timer only valid on master
          // and this thread is worker
          (timeStat::workerOnly(s) && (t == 0)) // Timer only valid on worker
          // and this thread is the master
          ) {
        continue;
      }

      statistic *threadStat = (*it)->getTimer(s);
      allStats[s] += *threadStat;

      // Add Total stats for timers that are valid in more than one thread
      if (!timeStat::noTotal(s))
        totalStats[s].addSample(threadStat->getTotal());
    }

    // Accumulate counters.
    for (counter_e c = counter_e(0); c < COUNTER_LAST; c = counter_e(c + 1)) {
      if (counter::masterOnly(c) && t != 0)
        continue;
      allCounters[c].addSample((*it)->getCounter(c)->getValue());
    }
  }

  if (eventPrintingEnabled()) {
    printPloticusFile();
    fclose(eventsOut);
  }

  fprintf(statsOut, "Aggregate for all threads\n");
  printTimerStats(statsOut, &allStats[0], &totalStats[0]);
  fprintf(statsOut, "\n");
  printCounterStats(statsOut, &allCounters[0]);

  if (statsOut != stderr)
    fclose(statsOut);
}

/* *************  exported C functions ************** */

// no name mangling for these functions, we want the c files to be able to get
// at these functions
extern "C" {

void __kmp_reset_stats() {
  kmp_stats_list::iterator it;
  for (it = __kmp_stats_list->begin(); it != __kmp_stats_list->end(); it++) {
    timeStat *timers = (*it)->getTimers();
    counter *counters = (*it)->getCounters();
    explicitTimer *eTimers = (*it)->getExplicitTimers();

    for (int t = 0; t < TIMER_LAST; t++)
      timers[t].reset();

    for (int c = 0; c < COUNTER_LAST; c++)
      counters[c].reset();

    for (int t = 0; t < EXPLICIT_TIMER_LAST; t++)
      eTimers[t].reset();

    // reset the event vector so all previous events are "erased"
    (*it)->resetEventVector();
  }
}

// This function will reset all stats and stop all threads' explicit timers if
// they haven't been stopped already.
void __kmp_output_stats(const char *heading) {
  __kmp_stats_global_output->outputStats(heading);
  __kmp_reset_stats();
}

void __kmp_accumulate_stats_at_exit(void) {
  // Only do this once.
  if (KMP_XCHG_FIXED32(&statsPrinted, 1) != 0)
    return;

  __kmp_output_stats("Statistics on exit");
}

void __kmp_stats_init(void) {
  __kmp_init_tas_lock(&__kmp_stats_lock);
  __kmp_stats_start_time = tsc_tick_count::now();
  __kmp_stats_global_output = new kmp_stats_output_module();
  __kmp_stats_list = new kmp_stats_list();
}

void __kmp_stats_fini(void) {
  __kmp_accumulate_stats_at_exit();
  __kmp_stats_list->deallocate();
  delete __kmp_stats_global_output;
  delete __kmp_stats_list;
}

} // extern "C"
