/* Copyright (C) 2014 InfiniDB, Inc. 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; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /******************************************************************************* * $Id: we_stats.cpp 4450 2013-01-21 14:13:24Z rdempsey $ * *******************************************************************************/ /** @file */ #include using namespace std; namespace WriteEngine { #ifdef PROFILE /* static */ bool Stats::fProfiling = false; /* static */ boost::mutex Stats::fRegisterReaderMutex; /* static */ boost::mutex Stats::fRegisterParseMutex; /* static */ std::vector Stats::fReadProfThreads; /* static */ std::vector Stats::fParseProfThreads; /* static */ std::vector Stats::fReadStopWatch; /* static */ std::vector Stats::fParseStopWatch; #endif struct IoStats Stats::m_ioStats = {0, 0}; bool Stats::m_bUseStats = false; /*********************************************************** * DESCRIPTION: * Increase the counter for block read * PARAMETERS: * blockNum - the number of blocks * RETURN: * none ***********************************************************/ void Stats::incIoBlockRead(const int blockNum) { if (!m_bUseStats) return; m_ioStats.blockRead += blockNum; } /*********************************************************** * DESCRIPTION: * Increase the counter for block write * PARAMETERS: * blockNum - the number of blocks * RETURN: * none ***********************************************************/ void Stats::incIoBlockWrite(const int blockNum) { if (!m_bUseStats) return; m_ioStats.blockWrite += blockNum; } #ifdef PROFILE //------------------------------------------------------------------------------- // Functions that follow are used for profiling using the StopWatch class //------------------------------------------------------------------------------- /*********************************************************** * DESCRIPTION: * Enable/Initialize the profiling functions * PARAMETERS: * nReadThreads - number of read threads to be profiled * nParseThreads - number of parse threads to be profiled * RETURN: * none ***********************************************************/ void Stats::enableProfiling(int nReadThreads, int nParseThreads) { fProfiling = true; // @bug 2625: pre-reserve space for our vectors; else we could have a race // condition whereby one parsing thread is adding itself to the vectors // and thus "growing" the vector (in registerParseProfThread), at the // same time that another parsing thread is reading the vector in parse- // Event(). By pre-reserving the space, the vectors won't be growing, // thus eliminating the problem with this race condition. fReadProfThreads.reserve(nReadThreads); fReadStopWatch.reserve(nReadThreads); fParseProfThreads.reserve(nParseThreads); fParseStopWatch.reserve(nParseThreads); } /*********************************************************** * DESCRIPTION: * Register the current thread as a Read thread to be profiled * PARAMETERS: * none * RETURN: * none ***********************************************************/ void Stats::registerReadProfThread() { boost::mutex::scoped_lock lk(fRegisterReaderMutex); fReadProfThreads.push_back(pthread_self()); logging::StopWatch readStopWatch; fReadStopWatch.push_back(readStopWatch); } /*********************************************************** * DESCRIPTION: * Register the current thread as a Parse thread to be profiled * PARAMETERS: * none * RETURN: * none ***********************************************************/ void Stats::registerParseProfThread() { boost::mutex::scoped_lock lk(fRegisterParseMutex); fParseProfThreads.push_back(pthread_self()); logging::StopWatch parseStopWatch; fParseStopWatch.push_back(parseStopWatch); } /*********************************************************** * DESCRIPTION: * Track the specified Read event in the current Read thread. * PARAMETERS: * eventString - string that identifies the event. * start - boolean indicating whether the is the start or the * end of the event. TRUE=>start FALSE=>end * RETURN: * none ***********************************************************/ void Stats::readEvent(const std::string& eventString, bool start) { if (fProfiling) { pthread_t thread = pthread_self(); for (unsigned i = 0; i < fReadProfThreads.size(); i++) { if (fReadProfThreads[i] == thread) { if (start) fReadStopWatch[i].start(eventString); else fReadStopWatch[i].stop(eventString); break; } } } } /*********************************************************** * DESCRIPTION: * Track the specified Parse event in the current Parse thread. * PARAMETERS: * eventString - string that identifies the event. * start - boolean indicating whether the is the start or the * end of the event. TRUE=>start FALSE=>end * RETURN: * none ***********************************************************/ void Stats::parseEvent(const std::string& eventString, bool start) { if (fProfiling) { pthread_t thread = pthread_self(); for (unsigned i = 0; i < fParseProfThreads.size(); i++) { if (fParseProfThreads[i] == thread) { if (start) fParseStopWatch[i].start(eventString); else fParseStopWatch[i].stop(eventString); break; } } } } /*********************************************************** * DESCRIPTION: * Print profiling results. * PARAMETERS: * none * RETURN: * none ***********************************************************/ void Stats::printProfilingResults() { if (fProfiling) { std::cout << endl; for (unsigned j = 0; j < fReadStopWatch.size(); j++) { std::cout << "Execution Stats for Read Thread " << j << " (" << fReadProfThreads[j] << ")" << std::endl << "-------------------------------" << std::endl; fReadStopWatch[j].finish(); std::cout << std::endl; } for (unsigned j = 0; j < fParseStopWatch.size(); j++) { std::cout << "Execution Stats for Parse Thread " << j << " (" << fParseProfThreads[j] << ")" << std::endl << "--------------------------------" << std::endl; fParseStopWatch[j].finish(); std::cout << std::endl; } } } #endif } // namespace WriteEngine