2010-02-13 21:14:44 +01:00
|
|
|
/*
|
2010-02-28 01:08:10 +01:00
|
|
|
* This file is a part of Winix
|
2014-10-04 20:04:03 +02:00
|
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2018-11-21 12:03:53 +01:00
|
|
|
* Copyright (c) 2008-2018, Tomasz Sowa
|
2010-02-13 21:14:44 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2014-10-04 20:04:03 +02:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
2010-02-13 21:14:44 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "loadavg.h"
|
2018-11-23 18:53:43 +01:00
|
|
|
#include "misc.h"
|
2018-11-21 12:03:53 +01:00
|
|
|
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
|
2014-02-12 17:30:49 +01:00
|
|
|
namespace Winix
|
|
|
|
{
|
|
|
|
|
|
|
|
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2021-06-24 15:33:44 +02:00
|
|
|
timespec_old_req_stop.tv_sec = 0;
|
|
|
|
timespec_old_req_stop.tv_nsec = 0;
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2021-06-24 15:33:44 +02:00
|
|
|
timespec_old_req_stop.tv_sec = l.timespec_old_req_stop.tv_sec;
|
|
|
|
timespec_old_req_stop.tv_nsec = l.timespec_old_req_stop.tv_nsec;
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-06-24 15:33:44 +02:00
|
|
|
void LoadAvg::StartRequest(Request * req)
|
2010-02-13 21:14:44 +01:00
|
|
|
{
|
2021-06-24 15:33:44 +02:00
|
|
|
if( timespec_old_req_stop.tv_sec != 0 )
|
2010-02-13 21:14:44 +01:00
|
|
|
{
|
2021-06-24 15:33:44 +02:00
|
|
|
// we got at least one request in the past
|
|
|
|
timespec diff;
|
|
|
|
calculate_timespec_diff(timespec_old_req_stop, req->timespec_req_start, diff);
|
|
|
|
double dp = timespec_to_double(diff);
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
current1.dp += dp;
|
|
|
|
current5.dp += dp;
|
|
|
|
current15.dp += dp;
|
|
|
|
|
|
|
|
CheckTimers();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-11-22 16:30:56 +01:00
|
|
|
|
|
|
|
|
2021-06-24 15:33:44 +02:00
|
|
|
void LoadAvg::StopRequest(Request * req)
|
2010-02-13 21:14:44 +01:00
|
|
|
{
|
2021-06-24 15:33:44 +02:00
|
|
|
double dr = timespec_to_double(req->timespec_req_diff);
|
2010-02-13 21:14:44 +01:00
|
|
|
|
|
|
|
current1.dr += dr;
|
|
|
|
current5.dr += dr;
|
|
|
|
current15.dr += dr;
|
|
|
|
|
|
|
|
current1.req += 1;
|
|
|
|
current5.req += 1;
|
|
|
|
current15.req += 1;
|
|
|
|
|
2021-06-24 15:33:44 +02:00
|
|
|
timespec_old_req_stop = req->timespec_req_stop;
|
2010-02-13 21:14:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2014-02-12 17:30:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace Winix
|
|
|
|
|