Fix ticket #113 (Add support for multi core CPUs and -w parameter to specifify amount of worker threads)

This commit is contained in:
Reijo Tomperi 2009-02-20 19:40:42 +00:00
parent 439b8c4051
commit 61587c42ae
8 changed files with 104 additions and 29 deletions

View File

@ -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 &lt;dir&gt;</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>

View File

@ -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"

View File

@ -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

View File

@ -31,6 +31,7 @@ Settings::Settings()
_unusedFunctions = false;
_security = false;
_vcl = false;
_workers = 1;
}
Settings::~Settings()

View File

@ -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

View File

@ -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

View File

@ -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