1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-30 19:23:07 +03:00

Merge pull request #1863 from mariadb-corporation/pmp-develop

A plugable PoorManProfiler singleton
This commit is contained in:
Roman Nozdrin
2021-04-16 13:51:01 +03:00
committed by GitHub
5 changed files with 151 additions and 131 deletions

View File

@ -70,6 +70,11 @@ using namespace joblist;
namespace primitiveprocessor
{
#ifdef PRIMPROC_STOPWATCH
#include "poormanprofiler.inc"
#endif
// these are config parms defined in primitiveserver.cpp, initialized by PrimProc main().
extern uint32_t blocksReadAhead;
extern uint32_t dictBufferSize;
@ -2157,42 +2162,14 @@ int BatchPrimitiveProcessor::operator()()
utils::setThreadName("PPBatchPrimProc");
#ifdef PRIMPROC_STOPWATCH
const static std::string msg{"BatchPrimitiveProcessor::operator()"};
logging::StopWatch* stopwatch = nullptr;
logging::StopWatch* stopwatch = profiler.getTimer();
#endif
if (currentBlockOffset == 0)
{
#ifdef PRIMPROC_STOPWATCH
auto stopwatchMapIter = stopwatchMap.find(pthread_self());
if (stopwatchMapIter != stopwatchMap.end())
{
stopwatch = stopwatchMapIter->second;
}
else
{
pthread_mutex_lock(&stopwatchMapMutex);
stopwatch = new logging::StopWatch(stopwatchMap.size());
stopwatchMap.insert({pthread_self(), stopwatch});
// Create the thread that will show timing results after five seconds of idle time.
if (!stopwatchThreadCreated)
{
pthread_t timerThread;
int err = pthread_create(&timerThread, NULL, autoFinishStopwatchThread, NULL);
if (err)
cout << "Error creating thread to complete Stopwatches." << endl;
stopwatchThreadCreated = true;
}
pthread_mutex_unlock(&stopwatchMapMutex);
}
stopwatch->start(msg);
#endif
idbassert(count > 0);
}
@ -2272,7 +2249,6 @@ int BatchPrimitiveProcessor::operator()()
<< " blockNum=" << blockNum << endl;
*/
}
vssCache.clear();
#ifndef __FreeBSD__
pthread_mutex_unlock(&objLock);

View File

@ -54,6 +54,11 @@
#include "bppsendthread.h"
#include "columnwidth.h"
//#define PRIMPROC_STOPWATCH
#ifdef PRIMPROC_STOPWATCH
#include "stopwatch.h"
#endif
namespace primitiveprocessor
{
typedef std::tr1::unordered_map<int64_t, BRM::VSSData> VSSCache;

View File

@ -2627,93 +2627,6 @@ bool BPPV::aborted()
return sendThread->aborted();
}
#ifdef PRIMPROC_STOPWATCH
std::unordered_map<pthread_t, logging::StopWatch*> stopwatchMap;
pthread_mutex_t stopwatchMapMutex;
bool stopwatchThreadCreated = false;
//------------------------------------------------------------------------------
// Stays in "sleep" state for specified until passed seconds have elapsed.
//------------------------------------------------------------------------------
void pause_(int seconds )
{
struct timespec req;
struct timespec rem;
req.tv_sec = seconds;
req.tv_nsec = 0;
rem.tv_sec = 0;
rem.tv_nsec = 0;
while (1)
{
if (nanosleep(&req, &rem) != 0)
{
if (rem.tv_sec > 0 || rem.tv_nsec > 0)
{
req = rem;
continue;
}
}
break;
}
}
void* autoFinishStopwatchThread(void* arg)
{
struct timeval tvCurrent;
int count = 0;
for (;;)
{
// Pause two seconds.
pause_(2);
count++;
// Iterate through the stopwatch map and see how long it's been since last activity.
auto stopwatchMapIter = stopwatchMap.begin();
logging::StopWatch* stopwatch;
gettimeofday(&tvCurrent, 0);
bool primProcIdle = true;
while (stopwatchMapIter != stopwatchMap.end())
{
stopwatch = stopwatchMapIter->second;
// If any threads have been active in the last 5 seconds, kick out.
if (((tvCurrent.tv_sec - stopwatch->fTvLast.tv_sec) < 5) || stopwatch->isActive())
{
primProcIdle = false;
break;
}
stopwatchMapIter++;
}
// No activity in last five seconds, display timing results.
// if(primProcIdle || (count%15 == 0))
if (primProcIdle)
{
pthread_mutex_lock(&stopwatchMapMutex);
stopwatchMapIter = stopwatchMap.begin();
while (stopwatchMapIter != stopwatchMap.end())
{
stopwatch = stopwatchMapIter->second;
stopwatch->finish();
stopwatchMapIter++;
delete stopwatch;
}
stopwatchMap.clear();
pthread_mutex_unlock(&stopwatchMapMutex);
}
}
return 0;
};
#endif // PRIMPROC_STOPWATCH
// end workaround
} // namespace primitiveprocessor

View File

@ -44,11 +44,6 @@
#include "service.h"
//#define PRIMPROC_STOPWATCH
#ifdef PRIMPROC_STOPWATCH
#include "stopwatch.h"
#endif
#include "oamcache.h"
extern oam::OamCache* oamCache;
@ -60,15 +55,6 @@ extern BRM::DBRM* brm;
extern boost::mutex bppLock;
extern uint32_t highPriorityThreads, medPriorityThreads, lowPriorityThreads;
#ifdef PRIMPROC_STOPWATCH
extern std::unordered_map<pthread_t, logging::StopWatch*> stopwatchMap;
extern pthread_mutex_t stopwatchMapMutex;
extern bool stopwatchThreadCreated;
extern void pause_(int seconds);
extern void* autoFinishStopwatchThread(void* arg);
#endif
class BPPV
{
public:

View File

@ -0,0 +1,140 @@
#ifndef POORMANPROFILER_H
#define POORMANPROFILER_H
#include "stopwatch.h"
#include <unordered_map>
using StopWatchMapType = std::unordered_map<pthread_t, logging::StopWatch*>;
void pause_(int seconds )
{
struct timespec req;
struct timespec rem;
req.tv_sec = seconds;
req.tv_nsec = 0;
rem.tv_sec = 0;
rem.tv_nsec = 0;
while (1)
{
if (nanosleep(&req, &rem) != 0)
{
if (rem.tv_sec > 0 || rem.tv_nsec > 0)
{
req = rem;
continue;
}
}
break;
}
}
class PoorManProfiler
{
public:
PoorManProfiler() {};
StopWatchMapType stopwatchMap;
pthread_mutex_t stopwatchMapMutex;
pthread_t timerThread;
bool stopwatchThreadCreated = false;
inline logging::StopWatch* start();
inline logging::StopWatch* getTimer();
inline void spawnAutoFinishThread();
};
void* autoFinishStopwatchThread(void* arg)
{
struct timeval tvCurrent;
PoorManProfiler* profiler = reinterpret_cast<PoorManProfiler*>(arg);
StopWatchMapType& stopwatchMap = profiler->stopwatchMap;
for (;;)
{
// Pause n seconds.
pause_(10);
// Iterate through the stopwatch map and see how long it's been since last activity.
pthread_mutex_lock(&profiler->stopwatchMapMutex);
auto stopwatchMapIter = stopwatchMap.begin();
logging::StopWatch* stopwatch;
gettimeofday(&tvCurrent, 0);
bool procIsIdle = true;
while (stopwatchMapIter != stopwatchMap.end())
{
stopwatch = stopwatchMapIter->second;
// If any threads have been active in the last 5 seconds, kick out.
if (((tvCurrent.tv_sec - stopwatch->fTvLast.tv_sec) < 5) || stopwatch->isActive())
{
procIsIdle = false;
break;
}
stopwatchMapIter++;
}
// No activity in last five seconds, display timing results.
if (procIsIdle)
{
stopwatchMapIter = stopwatchMap.begin();
while (stopwatchMapIter != stopwatchMap.end())
{
stopwatch = stopwatchMapIter->second;
stopwatch->finish();
stopwatchMapIter++;
delete stopwatch;
}
stopwatchMap.clear();
profiler->stopwatchThreadCreated = false;
}
pthread_mutex_unlock(&profiler->stopwatchMapMutex);
}
return 0;
};
inline void PoorManProfiler::spawnAutoFinishThread()
{
// Create the thread that will show timing results after five seconds of idle time.
if (!stopwatchThreadCreated)
{
pthread_t timerThread;
int err = pthread_create(&timerThread, nullptr, autoFinishStopwatchThread, this);
if (err)
std::cerr << "Error creating thread to complete Stopwatches." << endl;
stopwatchThreadCreated = true;
}
}
inline logging::StopWatch* PoorManProfiler::start()
{
pthread_mutex_lock(&stopwatchMapMutex);
auto stopwatchMapIter = stopwatchMap.find(pthread_self());
if (stopwatchMapIter != stopwatchMap.end())
{
pthread_mutex_unlock(&stopwatchMapMutex);
return stopwatchMapIter->second;
}
logging::StopWatch* stopwatch = new logging::StopWatch(stopwatchMap.size());
stopwatchMap.insert({pthread_self(), stopwatch});
spawnAutoFinishThread();
pthread_mutex_unlock(&stopwatchMapMutex);
return stopwatch;
}
inline logging::StopWatch* PoorManProfiler::getTimer()
{
return start();
}
static PoorManProfiler profiler;
#endif