diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
commit | 42995d7bf396933ee60c5f89c354ea89cf13df0d (patch) | |
tree | cfdcea0ac57420e7baf570bfe435e107bb842541 /soundserver/cpuusage.cc | |
download | arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.tar.gz arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.zip |
Copy of aRts for Trinity modifications
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'soundserver/cpuusage.cc')
-rw-r--r-- | soundserver/cpuusage.cc | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/soundserver/cpuusage.cc b/soundserver/cpuusage.cc new file mode 100644 index 0000000..6c5dd47 --- /dev/null +++ b/soundserver/cpuusage.cc @@ -0,0 +1,137 @@ + /* + + Copyright (C) 2000-2002 Stefan Westerfeld + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#include "cpuusage.h" +#include "dispatcher.h" +#include "debug.h" + +#include <time.h> +#include <unistd.h> +#include <sys/time.h> +#include <signal.h> + +#include <iostream> + +using namespace std; + +namespace Arts { + +class Benchmark +{ +private: + struct timeval _start,_stop; +public: + void start() + { + gettimeofday(&_start,NULL); + } + float stop() + { + gettimeofday(&_stop,NULL); + + float diff = _stop.tv_sec-_start.tv_sec; + diff += (float)(_stop.tv_usec-_start.tv_usec)/1000000; + return diff; + } +}; + +class CPUUsagePrivate +{ +public: + clock_t oldclock; + int stalled; + float usage; + Benchmark b; +}; + +/** signal handlers **/ + +static CPUUsage *cpuUsage = 0; + +extern "C" void cpuUsageCheck(int) +{ + if(cpuUsage != 0) + cpuUsage->check(); + + signal(SIGALRM, cpuUsageCheck); +} + +/** main stuff **/ + +CPUUsage::CPUUsage() : d(new CPUUsagePrivate()) +{ + d->oldclock = clock(); + d->usage = 0; + d->stalled = 0; + d->b.start(); + cpuUsage = this; + + /* setup signal handler & timer */ + + struct itimerval oldvalue; + struct itimerval newvalue = {{ 1, 0 }, {1, 0}}; // 1 second + + setitimer(ITIMER_REAL, &newvalue, &oldvalue); + signal(SIGALRM, cpuUsageCheck); +} + +CPUUsage::~CPUUsage() +{ + delete d; + cpuUsage = 0; +} + +float CPUUsage::usage() +{ + return d->usage; +} + +void CPUUsage::check() +{ + float cpu_time = (clock()-d->oldclock)/(float)CLOCKS_PER_SEC; + float real_time = d->b.stop(); + + if(cpu_time > 0 && real_time > 0) // there may be wraparounds + { + d->usage = cpu_time / real_time; + + if(d->usage > 0.95) // more than 95% -> not good! (probably freeze) + d->stalled++; + else + d->stalled=0; + + // ok, cancel synthesis due to cpu overload! brutal method + if(d->stalled > 15) + arts_fatal("cpu overload, aborting"); + } + + // prepare for next checkpoint + d->oldclock = clock(); + d->b.start(); +} + +CPUUsage *CPUUsage::the() +{ + return cpuUsage; +} + +} |