From 4aae12fc63073d3e6b429fa5f1d1f1ee143b37a0 Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Sat, 13 Feb 2010 20:14:44 +0000 Subject: [PATCH] I forgot to commit loadavg.h and loadavg.cpp git-svn-id: svn://ttmath.org/publicrep/winix/trunk@579 e52654a7-88a9-db11-a3e9-0013d4bc506e --- core/loadavg.cpp | 372 +++++++++++++++++++++++++++++++++++++++++++++++ core/loadavg.h | 114 +++++++++++++++ 2 files changed, 486 insertions(+) create mode 100755 core/loadavg.cpp create mode 100755 core/loadavg.h diff --git a/core/loadavg.cpp b/core/loadavg.cpp new file mode 100755 index 0000000..9a10fc6 --- /dev/null +++ b/core/loadavg.cpp @@ -0,0 +1,372 @@ +/* + * This file is a part of CMSLU -- Content Management System like Unix + * 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 1 ) + { + for(size_t i=0 ; i (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; +} diff --git a/core/loadavg.h b/core/loadavg.h new file mode 100755 index 0000000..09eb339 --- /dev/null +++ b/core/loadavg.h @@ -0,0 +1,114 @@ +/* + * This file is a part of CMSLU -- Content Management System like Unix + * and is not publicly distributed + * + * Copyright (c) 2008-2010, Tomasz Sowa + * All rights reserved. + * + */ + +#ifndef headerfilecmslucoreloadavg +#define headerfilecmslucoreloadavg + +#include + + + + +// in seconds +#define WINIX_LOADAVG_GRANULARITY1 2 +#define WINIX_LOADAVG_GRANULARITY5 15 +#define WINIX_LOADAVG_GRANULARITY15 45 + + + +class LoadAvg +{ +public: + LoadAvg(); + ~LoadAvg(); + LoadAvg & operator=(const LoadAvg & l); + LoadAvg(const LoadAvg & l); + + void StartRequest(); + void StopRequest(); + + double LoadAvgNow(); // load average withing last WINIX_LOADAVG_GRANULARITY1 seconds + double LoadAvg1(); + double LoadAvg5(); + double LoadAvg15(); + + double ReqPerSecNow(); + double ReqPerSec1(); + double ReqPerSec5(); + double ReqPerSec15(); + +private: + + struct Times + { + double dr; // time for the request (in seconds) + double dp; // time for the pause between requestes (in seconds) + long req; // how many requests + + void Clear() + { + dr = 0.0; + dp = 0.0; + req = 0; + } + + Times & operator=(const Times & t) + { + dr = t.dr; + dp = t.dp; + req = t.req; + + return *this; + } + }; + + void CheckTimers(); + void UpdateTimer1(); + void UpdateTimer5(); + void UpdateTimer15(); + + Times current1; + Times current5; + Times current15; + + void CreateTable(size_t seconds, size_t granulatiry, Times* & tab, size_t & len); + void CreateTable(); + + void MoveTab(Times * tab, size_t len); + void SumTab(Times * tab, size_t len, double expected, Times & t); + + void Calculate1(); + void Calculate5(); + void Calculate15(); + + bool was_stop_request; + timespec start_req, stop_req; + + Times * tab1; + size_t len1; + + Times * tab5; + size_t len5; + + Times * tab15; + size_t len15; + + double cache_load1; + double cache_load5; + double cache_load15; + + double cache_req_per_sec1; + double cache_req_per_sec5; + double cache_req_per_sec15; +}; + + + + +#endif