Fix ticket #113 (Add support for multi core CPUs and -w parameter to specifify amount of worker threads)
This commit is contained in:
parent
439b8c4051
commit
61587c42ae
|
@ -105,11 +105,12 @@ man(1), man(7), http://www.tldp.org/HOWTO/Man-Page/
|
|||
<arg choice="opt"><option>--all</option></arg>
|
||||
<arg choice="opt"><option>--force</option></arg>
|
||||
<arg choice="opt"><option>--help</option></arg>
|
||||
<arg choice="opt"><option>-Idir</option></arg>
|
||||
<arg choice="opt"><option>-I[dir]</option></arg>
|
||||
<arg choice="opt"><option>--quiet</option></arg>
|
||||
<arg choice="opt"><option>--style</option></arg>
|
||||
<arg choice="opt"><option>--unused-functions</option></arg>
|
||||
<arg choice="opt"><option>--verbose</option></arg>
|
||||
<arg choice="opt"><option>-w[workers]</option></arg>
|
||||
<arg choice="opt"><option>--xml</option></arg>
|
||||
<arg choice="opt"><option>file or path</option></arg>
|
||||
<arg choice="plain"><option>...</option></arg>
|
||||
|
@ -153,7 +154,7 @@ default.</para>
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-I <dir></option></term>
|
||||
<term><option>-I [dir]</option></term>
|
||||
<listitem>
|
||||
<para>Give include path. Give several -I parameters to give several paths. First given path is checked first. If paths are relative to source
|
||||
files, this is not needed.</para>
|
||||
|
@ -186,6 +187,12 @@ files, this is not needed.</para>
|
|||
<para>More detailed error reports</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-w [workers]</option></term>
|
||||
<listitem>
|
||||
<para>Start [workers] threads to do the checking work.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>--xml</option></term>
|
||||
<listitem>
|
||||
|
|
|
@ -146,6 +146,39 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
_includePaths.push_back(path);
|
||||
}
|
||||
|
||||
// Include paths
|
||||
else if (strcmp(argv[i], "-w") == 0 ||
|
||||
strncmp(argv[i], "-w", 2) == 0)
|
||||
{
|
||||
std::string numberString;
|
||||
|
||||
// "-w 3"
|
||||
if (strcmp(argv[i], "-w") == 0)
|
||||
{
|
||||
++i;
|
||||
if (i >= argc)
|
||||
return "cppcheck: argument to '-w' is missing\n";
|
||||
|
||||
numberString = argv[i];
|
||||
}
|
||||
|
||||
// "-w3"
|
||||
else if (strncmp(argv[i], "-w", 2) == 0)
|
||||
{
|
||||
numberString = argv[i];
|
||||
numberString = numberString.substr(2);
|
||||
}
|
||||
|
||||
std::istringstream iss(numberString);
|
||||
if (!(iss >> _settings._workers))
|
||||
return "cppcheck: argument to '-w' is not a number\n";
|
||||
|
||||
if (_settings._workers > 1000)
|
||||
{
|
||||
return "cppcheck: argument for '-w' is allowed to be 1000 at max\n";
|
||||
}
|
||||
}
|
||||
|
||||
else if (strncmp(argv[i], "-", 1) == 0 || strncmp(argv[i], "--", 2) == 0)
|
||||
{
|
||||
return "cppcheck: error: unrecognized command line option \"" + std::string(argv[i]) + "\"\n";
|
||||
|
@ -184,7 +217,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
" -f, --force Force checking on files that have \"too many\"\n"
|
||||
" configurations\n"
|
||||
" -h, --help Print this help\n"
|
||||
" -I <dir> Give include path. Give several -I parameters to give\n"
|
||||
" -I [dir] Give include path. Give several -I parameters to give\n"
|
||||
" several paths. First given path is checked first. If\n"
|
||||
" paths are relative to source files, this is not needed\n"
|
||||
" -q, --quiet Only print error messages\n"
|
||||
|
@ -192,6 +225,7 @@ std::string CppCheck::parseFromArgs(int argc, const char* const argv[])
|
|||
" --unused-functions Check if there are unused functions\n"
|
||||
" --vcl Suppress messages about memory leaks when using VCL classes\n"
|
||||
" -v, --verbose More detailed error reports\n"
|
||||
" -w [workers] Start [workers] threads to do the checking work.\n"
|
||||
" --xml Write results in xml to error stream.\n"
|
||||
"\n"
|
||||
"Example usage:\n"
|
||||
|
|
|
@ -47,11 +47,15 @@ unsigned int CppCheckExecutor::check(int argc, const char* const argv[])
|
|||
}
|
||||
|
||||
unsigned int returnValue = 0;
|
||||
if (1)
|
||||
if (_settings._workers == 1)
|
||||
{
|
||||
// Single process
|
||||
returnValue = cppCheck.check();
|
||||
}
|
||||
else if (!ThreadExecutor::isEnabled())
|
||||
{
|
||||
std::cout << "No thread support yet implemented for this platform." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple processes
|
||||
|
|
|
@ -31,6 +31,7 @@ Settings::Settings()
|
|||
_unusedFunctions = false;
|
||||
_security = false;
|
||||
_vcl = false;
|
||||
_workers = 1;
|
||||
}
|
||||
|
||||
Settings::~Settings()
|
||||
|
|
|
@ -51,6 +51,10 @@ public:
|
|||
|
||||
/** Disable warnings for VCL classes */
|
||||
bool _vcl;
|
||||
|
||||
/** How many processes/threads should do checking at the same
|
||||
time. Default is 1. */
|
||||
unsigned int _workers;
|
||||
};
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
|
|
@ -19,18 +19,12 @@
|
|||
|
||||
#include "threadexecutor.h"
|
||||
#include "cppcheck.h"
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
This implementation is currently for Linux only and disabled with #if 0 until
|
||||
proper way is invented.
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <iostream>
|
||||
#if defined(__GNUC__) && !defined(__MINGW32__)
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
ThreadExecutor::ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &errorLogger)
|
||||
: _filenames(filenames), _settings(settings), _errorLogger(errorLogger), _fileCount(0)
|
||||
|
@ -43,6 +37,12 @@ ThreadExecutor::~ThreadExecutor()
|
|||
//dtor
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
////// This code is for __GNUC__ only /////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(__GNUC__) && !defined(__MINGW32__)
|
||||
|
||||
bool ThreadExecutor::handleRead(unsigned int &result)
|
||||
{
|
||||
char type = 0;
|
||||
|
@ -53,7 +53,7 @@ bool ThreadExecutor::handleRead(unsigned int &result)
|
|||
|
||||
if (type != '1' && type != '2' && type != '3')
|
||||
{
|
||||
std::cerr << "#### ThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||
std::cerr << "#### You found a bug from cppcheck.\nThreadExecutor::handleRead error, type was:" << type << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ unsigned int ThreadExecutor::check()
|
|||
for (unsigned int i = 0; i < _filenames.size(); i++)
|
||||
{
|
||||
// Keep only wanted amount of child processes running at a time.
|
||||
if (childCount >= 2)
|
||||
if (childCount >= _settings._workers)
|
||||
{
|
||||
while (handleRead(result))
|
||||
{
|
||||
|
@ -187,5 +187,22 @@ void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
|
|||
}
|
||||
|
||||
#else
|
||||
unsigned int ThreadExecutor::check()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ThreadExecutor::reportOut(const std::string &/*outmsg*/)
|
||||
{
|
||||
|
||||
}
|
||||
void ThreadExecutor::reportErr(const ErrorLogger::ErrorMessage &/*msg*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ThreadExecutor::reportStatus(unsigned int /*index*/, unsigned int /*max*/)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
*/
|
||||
class ThreadExecutor : public ErrorLogger
|
||||
{
|
||||
#if 0
|
||||
public:
|
||||
ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &_errorLogger);
|
||||
virtual ~ThreadExecutor();
|
||||
|
@ -39,28 +38,37 @@ public:
|
|||
virtual void reportOut(const std::string &outmsg);
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg);
|
||||
virtual void reportStatus(unsigned int index, unsigned int max);
|
||||
protected:
|
||||
private:
|
||||
bool handleRead(unsigned int &result);
|
||||
void writeToPipe(char type, const std::string &data);
|
||||
|
||||
private:
|
||||
const std::vector<std::string> &_filenames;
|
||||
const Settings &_settings;
|
||||
ErrorLogger &_errorLogger;
|
||||
int _pipe[2];
|
||||
unsigned int _fileCount;
|
||||
|
||||
#if defined(__GNUC__) && !defined(__MINGW32__)
|
||||
private:
|
||||
bool handleRead(unsigned int &result);
|
||||
void writeToPipe(char type, const std::string &data);
|
||||
int _pipe[2];
|
||||
public:
|
||||
/**
|
||||
* @return true if support for threads exist.
|
||||
*/
|
||||
static bool isEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
public:
|
||||
ThreadExecutor(const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &_errorLogger) {};
|
||||
virtual ~ThreadExecutor() {};
|
||||
unsigned int check()
|
||||
/**
|
||||
* @return true if support for threads exist.
|
||||
*/
|
||||
static bool isEnabled()
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
virtual void reportOut(const std::string &outmsg) {}
|
||||
virtual void reportErr(const ErrorLogger::ErrorMessage &msg) {}
|
||||
virtual void reportStatus(unsigned int index, unsigned int max) {}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // THREADEXECUTOR_H
|
||||
|
|
Loading…
Reference in New Issue