src/qvcore/qvworker.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024  
00025 #include <iostream>
00026 
00027 #include <QDebug>
00028 #include <QMutex>
00029 #include <QWaitCondition>
00030 #include <QApplication>
00031 
00032 #include <QVWorker>
00033 
00034 QVWorker::QVWorker(const QString name):QVPropertyContainer(name),numIterations(0), status(Running), triggerList(), minms(0)
00035         {
00036         qDebug() << "QVWorker::QVWorker(" << name << ")";
00037         Q_ASSERT_X(qvApp != NULL, "QVWorker::QVWorker()", "QVApplication doesn't exists");
00038         if (qvApp == NULL)
00039                 {
00040                 QString str = "QVWorker::QVWorker(): the QVWorker cannot be created before the QVApplication instance. Aborting now.";
00041                 std::cerr << qPrintable(str) << std::endl;
00042                 exit(1);
00043                 }
00044 
00045         addProperty<int>("max worker iterations", inputFlag | guiInvisible | internalProp, -1, "Stablishes maximal number of iterations to execute worker");
00046         maxIterations = getPropertyValue<int>("max worker iterations");
00047 
00048         addProperty<bool>("stats enabled", inputFlag | guiInvisible | internalProp, TRUE, "Stablishes if the worker's cpu stats will be enabled");
00049         statsEnabled = getPropertyValue<bool>("stats enabled");
00050         if (statsEnabled) cpuStatControler = new QVStatControler();
00051         if (statsEnabled)       addProperty<QVStat>("cpu stats", outputFlag | internalProp, cpuStatControler->value(), "CPU stats's Statistics");
00052         else                            addProperty<QVStat>("cpu stats", outputFlag | internalProp, QVStat(), "CPU stats's Statistics");
00053 
00054         qDebug() << "QVWorker::QVWorker(" << name << ") <- return";
00055         };
00056 
00057 QVWorker::~QVWorker()
00058         {
00059         if (statsEnabled)
00060                 delete cpuStatControler;
00061         }
00062 /*
00063 void QVWorker::unlink()
00064         {
00065         if(status == Finished)
00066                 QVPropertyContainer::unlink();
00067         else
00068                 std::cerr << "WARNING: A worker only can be unlinked if the worker's status is Finished." << std::endl;
00069         }
00070 */
00071 void QVWorker::run()
00072         {
00073         qDebug() << "QVWorker::run()";
00074 
00075         while(status != Finished)
00076                 {
00077                 // First, we check if there are any pending signals, and if so, we
00078                 // execute their associated slots:
00079                 qApp->processEvents();
00080 
00081                 qDebug() << "QVWorker::iterate()";
00082                 qDebug() << "QVWorker::iterate(): iteration" << numIterations;
00083         
00084                 // Avoids "apparent hanging" (greedy ocupation of CPU by extremely fast
00085                 // workers, such as paused ones). It is just 0.5 milliseconds, so
00086                 // it should not be appreciable in any practical situation.
00087                 usleep(500);
00088 
00089                 switch (status)
00090                         {
00091                         case RunningOneStep:
00092                                 qDebug() << "QVWorker::iterate(): RunningOneStep";
00093                                 status = Paused;
00094         
00095                         case Running:
00096                                 iterationTime.start();
00097                                 emit startIteration();
00098                                 if (statsEnabled) cpuStatControler->step();
00099                                 readInputProperties();
00100                                 timeFlag("System");
00101                                 iterate();
00102                                 if (statsEnabled) setPropertyValue<QVStat>("cpu stats", cpuStatControler->value());
00103                                 writeOutputProperties();
00104                                 numIterations++;
00105                                 emit endIteration();
00106                                 emit endIteration(getId(), getIteration());
00107                                 curms = iterationTime.elapsed();
00108                                 if(minms > curms)
00109                                         usleep(1000*(minms-curms));
00110                                 /*if(numIterations!=1) // First iteration time is too noisy:
00111                                         acumms = (acumms*(numIterations-2) + curms) / (numIterations-1);
00112                                 std::cout << "-----> curms=" << curms << " acumms=" << acumms << "\n";*/
00113                                 break;
00114         
00115                         case Paused:
00116                                 qDebug() << "QVWorker::iterate(): Paused";
00117                                 usleep(100); // This avoids spurious CPU consuming when paused.
00118                                 break;
00119                                                 
00120                         case Finished:
00121                                 qDebug() << "QVWorker::iterate(): Finished";
00122                                 break;
00123                         }
00124 
00125                 if (maxIterations != -1 && numIterations >= maxIterations)
00126                         finish();
00127 
00128                 qDebug() << "QVWorker::iterate() <- return";
00129                 }
00130 
00131 //      unlink();
00132         qDebug() << "QVWorker::run() <- return";
00133         }