summaryrefslogtreecommitdiffstats
path: root/soundserver/cpuusage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'soundserver/cpuusage.cpp')
-rw-r--r--soundserver/cpuusage.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/soundserver/cpuusage.cpp b/soundserver/cpuusage.cpp
new file mode 100644
index 0000000..c08baba
--- /dev/null
+++ b/soundserver/cpuusage.cpp
@@ -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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, 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;
+}
+
+}