373 lines
5.7 KiB
C++
Executable File
373 lines
5.7 KiB
C++
Executable File
/*
|
|
* This file is a part of Winix
|
|
* and is not publicly distributed
|
|
*
|
|
* Copyright (c) 2008-2010, Tomasz Sowa
|
|
* All rights reserved.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "loadavg.h"
|
|
#include "log.h"
|
|
|
|
|
|
|
|
LoadAvg::LoadAvg()
|
|
{
|
|
current1.Clear();
|
|
current5.Clear();
|
|
current15.Clear();
|
|
|
|
cache_load1 = 0.0;
|
|
cache_load5 = 0.0;
|
|
cache_load15 = 0.0;
|
|
|
|
cache_req_per_sec1 = 0.0;
|
|
cache_req_per_sec5 = 0.0;
|
|
cache_req_per_sec15 = 0.0;
|
|
|
|
was_stop_request = false;
|
|
|
|
CreateTable();
|
|
}
|
|
|
|
|
|
LoadAvg & LoadAvg::operator=(const LoadAvg & l)
|
|
{
|
|
current1 = l.current1;
|
|
current5 = l.current5;
|
|
current15 = l.current15;
|
|
|
|
cache_load1 = l.cache_load1;
|
|
cache_load5 = l.cache_load5;
|
|
cache_load15 = l.cache_load15;
|
|
|
|
cache_req_per_sec1 = l.cache_req_per_sec1;
|
|
cache_req_per_sec5 = l.cache_req_per_sec5;
|
|
cache_req_per_sec15 = l.cache_req_per_sec15;
|
|
|
|
was_stop_request = l.was_stop_request;
|
|
|
|
CreateTable();
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
LoadAvg::LoadAvg(const LoadAvg & l)
|
|
{
|
|
operator=(l);
|
|
}
|
|
|
|
|
|
LoadAvg::~LoadAvg()
|
|
{
|
|
delete [] tab1;
|
|
delete [] tab5;
|
|
delete [] tab15;
|
|
}
|
|
|
|
|
|
|
|
void LoadAvg::CreateTable(size_t seconds, size_t granularity, Times* & tab, size_t & len)
|
|
{
|
|
len = (seconds / granularity) + 1; // rounding up (len mininum is 1)
|
|
tab = new Times[len];
|
|
|
|
for(size_t i=0 ; i<len ; ++i)
|
|
{
|
|
tab[i].Clear();
|
|
tab[i].dp = granularity; // at the beginning we assume the pause for all items
|
|
}
|
|
}
|
|
|
|
|
|
void LoadAvg::CreateTable()
|
|
{
|
|
CreateTable(60, WINIX_LOADAVG_GRANULARITY1, tab1, len1);
|
|
CreateTable(60 * 5, WINIX_LOADAVG_GRANULARITY5, tab5, len5);
|
|
CreateTable(60 * 15, WINIX_LOADAVG_GRANULARITY15, tab15, len15);
|
|
}
|
|
|
|
|
|
|
|
void LoadAvg::MoveTab(Times * tab, size_t len)
|
|
{
|
|
if( len > 1 )
|
|
{
|
|
for(size_t i=0 ; i<len-1 ; ++i)
|
|
tab[i] = tab[i+1];
|
|
}
|
|
|
|
tab[len-1].Clear();
|
|
}
|
|
|
|
|
|
void LoadAvg::UpdateTimer1()
|
|
{
|
|
MoveTab(tab1, len1);
|
|
|
|
tab1[len1-1] = current1;
|
|
current1.Clear();
|
|
cache_load1 = 0.0;
|
|
cache_req_per_sec1 = 0.0;
|
|
}
|
|
|
|
|
|
void LoadAvg::UpdateTimer5()
|
|
{
|
|
MoveTab(tab5, len5);
|
|
|
|
tab5[len5-1] = current5;
|
|
current5.Clear();
|
|
cache_load5 = 0.0;
|
|
cache_req_per_sec5 = 0.0;
|
|
}
|
|
|
|
|
|
|
|
void LoadAvg::UpdateTimer15()
|
|
{
|
|
MoveTab(tab15, len15);
|
|
|
|
tab15[len15-1] = current15;
|
|
current15.Clear();
|
|
cache_load15 = 0.0;
|
|
cache_req_per_sec15 = 0.0;
|
|
}
|
|
|
|
|
|
void LoadAvg::CheckTimers()
|
|
{
|
|
if( current1.dr + current1.dp > (double)WINIX_LOADAVG_GRANULARITY1 )
|
|
UpdateTimer1();
|
|
|
|
if( current5.dr + current5.dp > (double)WINIX_LOADAVG_GRANULARITY5 )
|
|
UpdateTimer5();
|
|
|
|
if( current15.dr + current15.dp > (double)WINIX_LOADAVG_GRANULARITY15 )
|
|
UpdateTimer15();
|
|
}
|
|
|
|
|
|
|
|
|
|
void LoadAvg::StartRequest()
|
|
{
|
|
clock_gettime(CLOCK_REALTIME, &start_req);
|
|
|
|
if( was_stop_request )
|
|
{
|
|
double dp = (start_req.tv_sec - stop_req.tv_sec);
|
|
dp += double(start_req.tv_nsec - stop_req.tv_nsec) / 1000000000.0; // make sure that tv_nsec has signed type
|
|
|
|
current1.dp += dp;
|
|
current5.dp += dp;
|
|
current15.dp += dp;
|
|
|
|
CheckTimers();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void LoadAvg::StopRequest()
|
|
{
|
|
clock_gettime(CLOCK_REALTIME, &stop_req);
|
|
|
|
double dr = (stop_req.tv_sec - start_req.tv_sec);
|
|
dr += double(stop_req.tv_nsec - start_req.tv_nsec) / 1000000000.0; // make sure that tv_nsec has signed type
|
|
|
|
current1.dr += dr;
|
|
current5.dr += dr;
|
|
current15.dr += dr;
|
|
|
|
current1.req += 1;
|
|
current5.req += 1;
|
|
current15.req += 1;
|
|
|
|
log << log2 << "LA: request took: " << dr << "s" << logend;
|
|
was_stop_request = true;
|
|
}
|
|
|
|
|
|
void LoadAvg::SumTab(Times * tab, size_t len, double expected, Times & t)
|
|
{
|
|
size_t i = len;
|
|
|
|
while( i-- > 0 && t.dr+t.dp < expected )
|
|
{
|
|
t.dr += tab[i].dr;
|
|
t.dp += tab[i].dp;
|
|
t.req += tab[i].req;
|
|
}
|
|
}
|
|
|
|
|
|
void LoadAvg::Calculate1()
|
|
{
|
|
Times t = current1;
|
|
|
|
SumTab(tab1, len1, 60.0, t);
|
|
|
|
if( t.dr+t.dp == 0.0 )
|
|
{
|
|
cache_load1 = 0.0;
|
|
cache_req_per_sec1 = 0.0;
|
|
}
|
|
else
|
|
{
|
|
cache_load1 = t.dr / (t.dr+t.dp);
|
|
cache_req_per_sec1 = t.req / (t.dr+t.dp);
|
|
}
|
|
}
|
|
|
|
|
|
void LoadAvg::Calculate5()
|
|
{
|
|
Times t = current5;
|
|
|
|
SumTab(tab5, len5, 60.0 * 5, t);
|
|
|
|
if( t.dr+t.dp == 0.0 )
|
|
{
|
|
cache_load5 = 0.0;
|
|
cache_req_per_sec5 = 0.0;
|
|
}
|
|
else
|
|
{
|
|
cache_load5 = t.dr / (t.dr+t.dp);
|
|
cache_req_per_sec5 = t.req / (t.dr+t.dp);
|
|
}
|
|
}
|
|
|
|
|
|
void LoadAvg::Calculate15()
|
|
{
|
|
Times t = current15;
|
|
|
|
SumTab(tab15, len15, 60.0 * 15, t);
|
|
|
|
if( t.dr+t.dp == 0.0 )
|
|
{
|
|
cache_load15 = 0.0;
|
|
cache_req_per_sec15 = 0.0;
|
|
}
|
|
else
|
|
{
|
|
cache_load15 = t.dr / (t.dr+t.dp);
|
|
cache_req_per_sec15 = t.req / (t.dr+t.dp);
|
|
}
|
|
}
|
|
|
|
|
|
double LoadAvg::LoadAvgNow()
|
|
{
|
|
double load = 0.0;
|
|
|
|
double dr = current1.dr;
|
|
double dp = current1.dp;
|
|
|
|
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
|
|
{
|
|
dr += tab1[len1-1].dr;
|
|
dp += tab1[len1-1].dp;
|
|
}
|
|
|
|
if( dr + dp != 0.0 )
|
|
load = dr / (dr + dp);
|
|
|
|
return load;
|
|
}
|
|
|
|
|
|
|
|
double LoadAvg::LoadAvg1()
|
|
{
|
|
if( cache_load1 != 0.0 )
|
|
return cache_load1;
|
|
|
|
Calculate1();
|
|
|
|
return cache_load1;
|
|
}
|
|
|
|
|
|
double LoadAvg::LoadAvg5()
|
|
{
|
|
if( cache_load5 != 0.0 )
|
|
return cache_load5;
|
|
|
|
Calculate5();
|
|
|
|
return cache_load5;
|
|
}
|
|
|
|
|
|
double LoadAvg::LoadAvg15()
|
|
{
|
|
if( cache_load15 != 0.0 )
|
|
return cache_load15;
|
|
|
|
Calculate15();
|
|
|
|
return cache_load15;
|
|
}
|
|
|
|
|
|
|
|
double LoadAvg::ReqPerSecNow()
|
|
{
|
|
double req_per_sec = 0.0;
|
|
|
|
double dr = current1.dr;
|
|
double dp = current1.dp;
|
|
double req = current1.req;
|
|
|
|
if( tab1[len1-1].dr + tab1[len1-1].dp < WINIX_LOADAVG_GRANULARITY1 * 2 )
|
|
{
|
|
dr += tab1[len1-1].dr;
|
|
dp += tab1[len1-1].dp;
|
|
req += tab1[len1-1].req;
|
|
}
|
|
|
|
if( dr + dp != 0.0 )
|
|
req_per_sec = req / (dr + dp);
|
|
|
|
return req_per_sec;
|
|
}
|
|
|
|
|
|
double LoadAvg::ReqPerSec1()
|
|
{
|
|
if( cache_req_per_sec1 != 0.0 )
|
|
return cache_req_per_sec1;
|
|
|
|
Calculate1();
|
|
|
|
return cache_req_per_sec1;
|
|
}
|
|
|
|
|
|
double LoadAvg::ReqPerSec5()
|
|
{
|
|
if( cache_req_per_sec5 != 0.0 )
|
|
return cache_req_per_sec5;
|
|
|
|
Calculate5();
|
|
|
|
return cache_req_per_sec5;
|
|
}
|
|
|
|
|
|
double LoadAvg::ReqPerSec15()
|
|
{
|
|
if( cache_req_per_sec15 != 0.0 )
|
|
return cache_req_per_sec15;
|
|
|
|
Calculate15();
|
|
|
|
return cache_req_per_sec15;
|
|
}
|