<commit_before>#include "monitor.h"
#include <ios>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <signal.h>
#include <sys/time.h>

#define pthread(Function, ...) do { if (pthread_ ## Function(__VA_ARGS__)) perror("pthread_" #Function); } while(0)

static 
void* runmonitor(void *arg)
{
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGINT);
    sigaddset(&sigset, SIGQUIT);
    sigaddset(&sigset, SIGHUP);
    sigaddset(&sigset, SIGTERM);
    pthread_sigmask(SIG_BLOCK, &sigset, 0);

    Monitor *m = (Monitor*) arg;
    m->run();
    return 0;
}

Monitor::Monitor(Simulator::MGSystem& sys, bool enabled, const std::string& mdfile, const std::string& outfile, bool quiet)
    : m_sys(sys), 
      m_outputfile(0),
      m_quiet(quiet),
      m_running(false),
      m_enabled(true),
      m_sampler(0)
{
    if (!enabled)
    {
        if (!m_quiet)
            std::clog << "# monitoring disabled." << std::endl;
        return ;
    }

    std::ofstream metadatafile(mdfile.c_str(), std::ios_base::out|std::ios_base::trunc);
    if (!metadatafile.good())
    {
        std::clog << "# warning: cannot write to file " << mdfile << ". Monitoring disabled." << std::endl;
        return ;
    }

    if (outfile.empty())
        /* only metadata was requested */
        return ;

    m_outputfile = new std::ofstream(outfile.c_str(), std::ios_base::binary|std::ios_base::out|std::ios_base::trunc);
    if (!m_outputfile->good()) 
    {
        std::clog << "# warning: cannot write to file " << outfile << ". Monitoring disabled." << std::endl;
        delete m_outputfile;
        m_outputfile = 0;
        return ;
    }


    std::vector<std::string> pats = sys.GetConfig().getIntegerList<std::string>("MonitorSampleVariables");
    pats.insert(pats.begin(), "kernel.cycle");
    pats.push_back("kernel.cycle");
    m_sampler = new BinarySampler(metadatafile, sys, pats);
    metadatafile << "# tv_sizes: " << sizeof(((struct timeval*)(void*)0)->tv_sec) 
                 << ' ' << sizeof(((struct timeval*)(void*)0)->tv_usec)
                 << ' ' << sizeof(struct timeval) << std::endl;
    metadatafile.close();

    float msd = sys.GetConfig().getInteger<float>("MonitorSampleDelay", 0.001);
    msd = fabs(msd);
    m_tsdelay.tv_sec = msd;
    m_tsdelay.tv_nsec = (msd - (float)m_tsdelay.tv_sec) * 1000000000.;
   
    if (!m_quiet)
        std::clog << "# monitoring enabled, sampling "
                  << m_sampler->GetBufferSize()
                  << " bytes every "
                  << m_tsdelay.tv_sec << '.'
                  << std::setfill('0') << std::setw(9) << m_tsdelay.tv_nsec 
                  << "s to file " << outfile << std::endl
                  << "# metadata output to file " << mdfile << std::endl;

    pthread(mutex_init, &m_runlock, 0);
    pthread(mutex_lock, &m_runlock);

    pthread(create, &m_monitorthread, 0, runmonitor, this);
}

Monitor::~Monitor()
{<commit_msg>[mgsim] monitor: emit metadata before opening trace file<commit_after>#include "monitor.h"
#include <ios>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <signal.h>
#include <sys/time.h>

#define pthread(Function, ...) do { if (pthread_ ## Function(__VA_ARGS__)) perror("pthread_" #Function); } while(0)

static 
void* runmonitor(void *arg)
{
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGINT);
    sigaddset(&sigset, SIGQUIT);
    sigaddset(&sigset, SIGHUP);
    sigaddset(&sigset, SIGTERM);
    pthread_sigmask(SIG_BLOCK, &sigset, 0);

    Monitor *m = (Monitor*) arg;
    m->run();
    return 0;
}

Monitor::Monitor(Simulator::MGSystem& sys, bool enabled, const std::string& mdfile, const std::string& outfile, bool quiet)
    : m_sys(sys), 
      m_outputfile(0),
      m_quiet(quiet),
      m_running(false),
      m_enabled(true),
      m_sampler(0)
{
    if (!enabled)
    {
        if (!m_quiet)
            std::clog << "# monitoring disabled." << std::endl;
        return ;
    }

    std::ofstream metadatafile(mdfile.c_str(), std::ios_base::out|std::ios_base::trunc);
    if (!metadatafile.good())
    {
        std::clog << "# warning: cannot write to file " << mdfile << ". Monitoring disabled." << std::endl;
        return ;
    }

    std::vector<std::string> pats = sys.GetConfig().getIntegerList<std::string>("MonitorSampleVariables");
    pats.insert(pats.begin(), "kernel.cycle");
    pats.push_back("kernel.cycle");
    m_sampler = new BinarySampler(metadatafile, sys, pats);
    metadatafile << "# tv_sizes: " << sizeof(((struct timeval*)(void*)0)->tv_sec) 
                 << ' ' << sizeof(((struct timeval*)(void*)0)->tv_usec)
                 << ' ' << sizeof(struct timeval) << std::endl;
    metadatafile.close();

    if (outfile.empty())
        /* only metadata was requested */
        return ;

    m_outputfile = new std::ofstream(outfile.c_str(), std::ios_base::binary|std::ios_base::out|std::ios_base::trunc);
    if (!m_outputfile->good()) 
    {
        std::clog << "# warning: cannot write to file " << outfile << ". Monitoring disabled." << std::endl;
        delete m_outputfile;
        m_outputfile = 0;
        return ;
    }

    float msd = sys.GetConfig().getInteger<float>("MonitorSampleDelay", 0.001);
    msd = fabs(msd);
    m_tsdelay.tv_sec = msd;
    m_tsdelay.tv_nsec = (msd - (float)m_tsdelay.tv_sec) * 1000000000.;
   
    if (!m_quiet)
        std::clog << "# monitoring enabled, sampling "
                  << m_sampler->GetBufferSize()
                  << " bytes every "
                  << m_tsdelay.tv_sec << '.'
                  << std::setfill('0') << std::setw(9) << m_tsdelay.tv_nsec 
                  << "s to file " << outfile << std::endl
                  << "# metadata output to file " << mdfile << std::endl;

    pthread(mutex_init, &m_runlock, 0);
    pthread(mutex_lock, &m_runlock);

    pthread(create, &m_monitorthread, 0, runmonitor, this);
}

Monitor::~Monitor()
{
{'fraction_non_alphanumeric': 0.1681135225375626, 'fraction_numerical': 0.008681135225375626, 'mean_word_length': 2.9388560157790926, 'pattern_counts': {'":': 0, '<': 147, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5347108', 'n_tokens_mistral': 2078, 'n_tokens_neox': 1986, 'n_words': 389}