using namespace icinga;
ThreadPool::ThreadPool(void)
- : m_ThreadDeaths(0), m_WaitTime(0), m_ServiceTime(0),
+ : m_WaitTime(0), m_ServiceTime(0),
m_TaskCount(0), m_Stopped(false)
{
for (int i = 0; i < 2; i++)
UpdateThreadUtilization(tid, ThreadIdle);
- while (m_WorkItems.empty() && !m_Stopped && m_ThreadDeaths == 0)
+ while (m_WorkItems.empty() && !m_Stopped && !m_ThreadStats[tid].Zombie)
m_WorkCV.wait(lock);
- if (m_ThreadDeaths > 0) {
- m_ThreadDeaths--;
+ if (m_ThreadStats[tid].Zombie)
break;
- }
if (m_WorkItems.empty() && m_Stopped)
break;
}
UpdateThreadUtilization(tid, ThreadDead);
+ m_ThreadStats[tid].Zombie = false;
}
/**
alive = 0;
for (size_t i = 0; i < sizeof(m_ThreadStats) / sizeof(m_ThreadStats[0]); i++) {
- if (m_ThreadStats[i].State != ThreadDead) {
+ if (m_ThreadStats[i].State != ThreadDead && !m_ThreadStats[i].Zombie) {
alive++;
utilization += m_ThreadStats[i].Utilization * 100;
}
avg_latency = 0;
if (utilization < 60 || utilization > 80 || alive < 2) {
- int tthreads = ceil((utilization * alive) / 80.0) - alive;
+ double wthreads = ceil((utilization * alive) / 80.0);
+
+ if (!finite(wthreads))
+ wthreads = 0;
+
+ int tthreads = wthreads - alive;
/* Don't ever kill the last 2 threads. */
if (alive + tthreads < 2)
if (tthreads > 0 && pending > 0)
tthreads = 8;
+ std::ostringstream msgbuf;
+ msgbuf << "Thread pool; current: " << alive << "; adjustment: " << tthreads;
+ Log(LogDebug, "base", msgbuf.str());
+
for (int i = 0; i < -tthreads; i++)
KillWorker();
*/
void ThreadPool::KillWorker(void)
{
- Log(LogDebug, "base", "Killing worker thread.");
+ for (size_t i = 0; i < sizeof(m_ThreadStats) / sizeof(m_ThreadStats[0]); i++) {
+ if (m_ThreadStats[i].State == ThreadIdle && !m_ThreadStats[i].Zombie) {
+ Log(LogDebug, "base", "Killing worker thread.");
- m_ThreadDeaths++;
+ m_ThreadStats[i].Zombie = true;
+ m_WorkCV.notify_all();
+
+ break;
+ }
+ }
}
void ThreadPool::StatsThreadProc(void)
struct ThreadStats
{
ThreadState State;
+ bool Zombie;
double Utilization;
double LastUpdate;
ThreadStats(ThreadState state = ThreadDead)
- : State(state), Utilization(0), LastUpdate(0)
+ : State(state), Zombie(false), Utilization(0), LastUpdate(0)
{ }
};
ThreadStats m_ThreadStats[512];
- int m_ThreadDeaths;
boost::thread m_ManagerThread;
boost::thread m_StatsThread;