diff --git a/CMakeLists.txt b/CMakeLists.txt index 05203f365..b39c72ef7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -214,6 +214,7 @@ endif() add_subdirectory(sdrbase) add_subdirectory(sdrgui) add_subdirectory(sdrsrv) +add_subdirectory(sdrbench) add_subdirectory(httpserver) add_subdirectory(logging) add_subdirectory(qrtplib) @@ -293,6 +294,29 @@ target_link_libraries(sdrangelsrv qt5_use_modules(sdrangelsrv Multimedia) +############################################################################## +# main benchmark application + +set(sdrangelbench_SOURCES + appbench/main.cpp +) + +add_executable(sdrangelbench + ${sdrangelbench_SOURCES} +) + +target_include_directories(sdrangelbench + PUBLIC ${CMAKE_SOURCE_DIR}/sdrbench +) + +target_link_libraries(sdrangelbench + sdrbench + logging + ${QT_LIBRARIES} +) + +qt5_use_modules(sdrangelbench Multimedia) + ############################################################################## if (BUILD_DEBIAN) @@ -325,6 +349,7 @@ endif(LIBUSB_FOUND AND UNIX) #install targets install(TARGETS sdrangel DESTINATION bin) install(TARGETS sdrangelsrv DESTINATION bin) +install(TARGETS sdrangelbench DESTINATION bin) #install(TARGETS sdrbase DESTINATION lib) #install files and directories diff --git a/appbench/main.cpp b/appbench/main.cpp new file mode 100644 index 000000000..74adea9bc --- /dev/null +++ b/appbench/main.cpp @@ -0,0 +1,110 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include +#include +#include + +#include "loggerwithfile.h" +#include "mainbench.h" +#include "dsp/dsptypes.h" + +void handler(int sig) { + fprintf(stderr, "quit the application by signal(%d).\n", sig); + QCoreApplication::quit(); +} + +void catchUnixSignals(const std::vector& quitSignals) { + sigset_t blocking_mask; + sigemptyset(&blocking_mask); + + for (std::vector::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) { + sigaddset(&blocking_mask, *it); + } + + struct sigaction sa; + sa.sa_handler = handler; + sa.sa_mask = blocking_mask; + sa.sa_flags = 0; + + for (std::vector::const_iterator it = quitSignals.begin(); it != quitSignals.end(); ++it) { + sigaction(*it, &sa, 0); + } +} + +static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *logger) +{ + QCoreApplication a(argc, argv); + + QCoreApplication::setOrganizationName("f4exb"); + QCoreApplication::setApplicationName("SDRangelBench"); + QCoreApplication::setApplicationVersion("3.14.5"); + + int catchSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP}; + std::vector vsig(catchSignals, catchSignals + sizeof(catchSignals) / sizeof(int)); + catchUnixSignals(vsig); + + ParserBench parser; + parser.parse(a); + +#if QT_VERSION >= 0x050400 + qInfo("%s %s Qt %s %db %s %s DSP Rx:%db Tx:%db PID %lld", + qPrintable(QCoreApplication::applicationName()), + qPrintable(QCoreApplication::applicationVersion()), + qPrintable(QString(QT_VERSION_STR)), + QT_POINTER_SIZE*8, + qPrintable(QSysInfo::currentCpuArchitecture()), + qPrintable(QSysInfo::prettyProductName()), + SDR_RX_SAMP_SZ, + SDR_TX_SAMP_SZ, + QCoreApplication::applicationPid()); +#else + qInfo("%s %s Qt %s %db DSP Rx:%db Tx:%db PID %lld", + qPrintable(QCoreApplication::applicationName()), + qPrintable((QCoreApplication::>applicationVersion()), + qPrintable(QString(QT_VERSION_STR)), + QT_POINTER_SIZE*8, + SDR_RX_SAMP_SZ, + SDR_TX_SAMP_SZ, + QCoreApplication::applicationPid()); +#endif + + MainBench m(logger, parser, &a); + + // This will cause the application to exit when the main core is finished + QObject::connect(&m, SIGNAL(finished()), &a, SLOT(quit())); + // This will run the task from the application event loop + QTimer::singleShot(0, &m, SLOT(run())); + + return a.exec(); +} + +int main(int argc, char* argv[]) +{ + qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp); + logger->installMsgHandler(); + int res = runQtApplication(argc, argv, logger); + qWarning("SDRangel quit."); + return res; +} + + diff --git a/sdrbench/CMakeLists.txt b/sdrbench/CMakeLists.txt new file mode 100644 index 000000000..94975cdd3 --- /dev/null +++ b/sdrbench/CMakeLists.txt @@ -0,0 +1,42 @@ +project (sdrbench) + +set(sdrbench_SOURCES + mainbench.cpp + parserbench.cpp +) + +set(sdrbench_HEADERS + mainbench.h + parserbench.h +) + +set(sdrbench_SOURCES + ${sdrbench_SOURCES} + ${sdrbench_HEADERS} +) + +add_definitions(${QT_DEFINITIONS}) +add_definitions(-DQT_SHARED) + +add_library(sdrbench SHARED + ${sdrbench_SOURCES} + ${sdrbench_HEADERS_MOC} +) + +include_directories( + . + ${CMAKE_SOURCE_DIR}/logging + ${CMAKE_CURRENT_BINARY_DIR} +) + +target_link_libraries(sdrbench + ${QT_LIBRARIES} + logging +) + +target_compile_features(sdrbench PRIVATE cxx_generalized_initializers) # cmake >= 3.1.0 + +qt5_use_modules(sdrbench Core Gui) + +install(TARGETS sdrbench DESTINATION lib) + diff --git a/sdrbench/mainbench.cpp b/sdrbench/mainbench.cpp new file mode 100644 index 000000000..4da6db668 --- /dev/null +++ b/sdrbench/mainbench.cpp @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include "mainbench.h" + +MainBench *MainBench::m_instance = 0; + +MainBench::MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent) : + QObject(parent), + m_logger(logger), + m_parser(parser) +{ + qDebug() << "MainBench::MainBench: start"; + m_instance = this; + qDebug() << "MainBench::MainBench: end"; +} + +void MainBench::run() +{ + qDebug() << "MainBench::run: work in progress"; + qDebug() << "MainBench::run: parameters:" + << " test: " << m_parser.getTest() + << " nsamples: " << m_parser.getNbSamples() + << " repet: " << m_parser.getRepetition() + << " log2f: " << m_parser.getLog2Factor(); + emit finished(); +} + +MainBench::~MainBench() +{} \ No newline at end of file diff --git a/sdrbench/mainbench.h b/sdrbench/mainbench.h new file mode 100644 index 000000000..a94ec05b9 --- /dev/null +++ b/sdrbench/mainbench.h @@ -0,0 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 Edouard Griffiths, F4EXB. // +// // +// Swagger server adapter interface // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBENCH_MAINBENCH_H_ +#define SDRBENCH_MAINBENCH_H_ + +#include + +#include "parserbench.h" + +namespace qtwebapp { + class LoggerWithFile; +} + +class MainBench: public QObject { + Q_OBJECT + +public: + explicit MainBench(qtwebapp::LoggerWithFile *logger, const ParserBench& parser, QObject *parent = 0); + ~MainBench(); + +public slots: + void run(); + +signals: + void finished(); + +private: + static MainBench *m_instance; + qtwebapp::LoggerWithFile *m_logger; + const ParserBench& m_parser; +}; + +#endif // SDRBENCH_MAINBENCH_H_ diff --git a/sdrbench/parserbench.cpp b/sdrbench/parserbench.cpp new file mode 100644 index 000000000..8f914a72e --- /dev/null +++ b/sdrbench/parserbench.cpp @@ -0,0 +1,113 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +#include "parserbench.h" + +ParserBench::ParserBench() : + m_testOption(QStringList() << "t" << "test", + "Test type.", + "test", + "decimate"), + m_nbSamplesOption(QStringList() << "n" << "nb-samples", + "Number of sample to deal with.", + "samples", + "1048576"), + m_repetitionOption(QStringList() << "r" << "repeat", + "Number of repetitions.", + "repetition", + "1"), + m_log2FactorOption(QStringList() << "l" << "log2-factor", + "Log2 factor for rate conversion.", + "log2", + "2") +{ + m_test = "decimate"; + m_nbSamples = 1048576; + m_repetition = 1; + m_log2Factor = 4; + + m_parser.setApplicationDescription("Software Defined Radio application benchmarks"); + m_parser.addHelpOption(); + m_parser.addVersionOption(); + + m_parser.addOption(m_testOption); + m_parser.addOption(m_nbSamplesOption); + m_parser.addOption(m_repetitionOption); + m_parser.addOption(m_log2FactorOption); +} + +ParserBench::~ParserBench() +{ } + +void ParserBench::parse(const QCoreApplication& app) +{ + m_parser.process(app); + + int pos; + bool ok; + + // test switch + + QString test = m_parser.value(m_testOption); + + QString testStr = "(decimate)"; + QRegExp ipRegex ("^" + testStr + "$"); + QRegExpValidator ipValidator(ipRegex); + + if (ipValidator.validate(test, pos) == QValidator::Acceptable) { + m_test = test; + } else { + qWarning() << "ParserBench::parse: test type invalid. Defaulting to " << m_test; + } + + // number of samples + + QString nbSamplesStr = m_parser.value(m_nbSamplesOption); + int nbSamples = nbSamplesStr.toInt(&ok); + + if (ok && (nbSamples > 1024) && (nbSamples < 1073741824)) { + m_nbSamples = nbSamples; + } else { + qWarning() << "ParserBench::parse: number of samples invalid. Defaulting to " << m_nbSamples; + } + + // repetition + + QString repetitionStr = m_parser.value(m_repetitionOption); + int repetition = repetitionStr.toInt(&ok); + + if (ok && (repetition >= 0)) { + m_repetition = repetition; + } else { + qWarning() << "ParserBench::parse: repetition invalid. Defaulting to " << m_repetition; + } + + // log2 factor + + QString log2FactorStr = m_parser.value(m_log2FactorOption); + int log2Factor = log2FactorStr.toInt(&ok); + + if (ok && (log2Factor >= 0) && (log2Factor <= 6)) { + m_log2Factor = log2Factor; + } else { + qWarning() << "ParserBench::parse: repetilog2 factortion invalid. Defaulting to " << m_log2Factor; + } +} diff --git a/sdrbench/parserbench.h b/sdrbench/parserbench.h new file mode 100644 index 000000000..a7b7a2660 --- /dev/null +++ b/sdrbench/parserbench.h @@ -0,0 +1,52 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2018 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program 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 General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBENCH_PARSERBENCH_H_ +#define SDRBENCH_PARSERBENCH_H_ + +#include +#include + +class ParserBench +{ +public: + ParserBench(); + ~ParserBench(); + + void parse(const QCoreApplication& app); + + const QString& getTest() const { return m_test; } + uint32_t getNbSamples() const { return m_nbSamples; } + uint32_t getRepetition() const { return m_repetition; } + uint32_t getLog2Factor() const { return m_log2Factor; } + +private: + QString m_test; + uint32_t m_nbSamples; + uint32_t m_repetition; + uint32_t m_log2Factor; + + QCommandLineParser m_parser; + QCommandLineOption m_testOption; + QCommandLineOption m_nbSamplesOption; + QCommandLineOption m_repetitionOption; + QCommandLineOption m_log2FactorOption; +}; + + + +#endif /* SDRBENCH_PARSERBENCH_H_ */