CLI: Add -l command line option

This commit is contained in:
Troshin V.S 2014-03-25 18:35:59 +01:00 committed by Daniel Marjamäki
parent 05a7e7e008
commit 840fba7672
5 changed files with 64 additions and 3 deletions

View File

@ -576,6 +576,29 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
PrintMessage("cppcheck: argument for '-j' is allowed to be 10000 at max."); PrintMessage("cppcheck: argument for '-j' is allowed to be 10000 at max.");
return false; return false;
} }
} else if (std::strncmp(argv[i], "-l", 2) == 0) {
std::string numberString;
// "-l 3"
if (std::strcmp(argv[i], "-l") == 0) {
++i;
if (i >= argc || argv[i][0] == '-') {
PrintMessage("cppcheck: argument to '-l' is missing.");
return false;
}
numberString = argv[i];
}
// "-l3"
else
numberString = argv[i]+2;
std::istringstream iss(numberString);
if (!(iss >> _settings->_loadAverage)) {
PrintMessage("cppcheck: argument to '-l' is not a number.");
return false;
}
} }
// print all possible error messages.. // print all possible error messages..
@ -869,6 +892,9 @@ void CmdLineParser::PrintHelp()
" more comments, like: '// cppcheck-suppress warningId'\n" " more comments, like: '// cppcheck-suppress warningId'\n"
" on the lines before the warning to suppress.\n" " on the lines before the warning to suppress.\n"
" -j <jobs> Start [jobs] threads to do the checking simultaneously.\n" " -j <jobs> Start [jobs] threads to do the checking simultaneously.\n"
" -l <load> Specifies that no new threads should be started if there\n"
" are other threads running and the load average is at least\n"
" load (ignored on non UNIX-like systems)\n"
" --language=<language>, -x <language>\n" " --language=<language>, -x <language>\n"
" Forces cppcheck to check all files as the given\n" " Forces cppcheck to check all files as the given\n"
" language. Valid values are: c, c++\n" " language. Valid values are: c, c++\n"

View File

@ -138,6 +138,22 @@ int ThreadExecutor::handleRead(int rpipe, unsigned int &result)
return 1; return 1;
} }
bool ThreadExecutor::checkLoadAverage(size_t nchilds)
{
if (!nchilds || !_settings._loadAverage) {
return true;
}
double sample;
if (getloadavg(&sample, 1) != 1) {
// disable load average cheking on getloadavg error
return true;
} else if (sample < _settings._loadAverage) {
return true;
}
return false;
}
unsigned int ThreadExecutor::check() unsigned int ThreadExecutor::check()
{ {
_fileCount = 0; _fileCount = 0;
@ -155,7 +171,8 @@ unsigned int ThreadExecutor::check()
std::map<std::string, std::size_t>::const_iterator i = _files.begin(); std::map<std::string, std::size_t>::const_iterator i = _files.begin();
for (;;) { for (;;) {
// Start a new child // Start a new child
if (i != _files.end() && rpipes.size() < _settings._jobs) { size_t nchilds = rpipes.size();
if (i != _files.end() && nchilds < _settings._jobs && checkLoadAverage(nchilds)) {
int pipes[2]; int pipes[2];
if (pipe(pipes) == -1) { if (pipe(pipes) == -1) {
std::cerr << "pipe() failed: "<< std::strerror(errno) << std::endl; std::cerr << "pipe() failed: "<< std::strerror(errno) << std::endl;
@ -211,8 +228,10 @@ unsigned int ThreadExecutor::check()
FD_ZERO(&rfds); FD_ZERO(&rfds);
for (std::list<int>::const_iterator rp = rpipes.begin(); rp != rpipes.end(); ++rp) for (std::list<int>::const_iterator rp = rpipes.begin(); rp != rpipes.end(); ++rp)
FD_SET(*rp, &rfds); FD_SET(*rp, &rfds);
struct timeval tv; // for every second polling of load average condition
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, NULL); tv.tv_sec = 1;
tv.tv_usec = 0;
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, &tv);
if (r > 0) { if (r > 0) {
std::list<int>::iterator rp = rpipes.begin(); std::list<int>::iterator rp = rpipes.begin();
@ -320,6 +339,11 @@ void ThreadExecutor::addFileContent(const std::string &path, const std::string &
_fileContents[path] = content; _fileContents[path] = content;
} }
bool ThreadExecutor::checkLoadAverage(size_t nchilds)
{
return true;
}
unsigned int ThreadExecutor::check() unsigned int ThreadExecutor::check()
{ {
HANDLE *threadHandles = new HANDLE[_settings._jobs]; HANDLE *threadHandles = new HANDLE[_settings._jobs];

View File

@ -87,6 +87,13 @@ private:
std::list<std::string> _errorList; std::list<std::string> _errorList;
int _wpipe; int _wpipe;
/**
* @brief Check load average condition
* @param nchilds - count of currently runned childs
* @return true - if new process can be started
*/
bool checkLoadAverage(size_t nchilds);
public: public:
/** /**
* @return true if support for threads exist. * @return true if support for threads exist.

View File

@ -34,6 +34,7 @@ Settings::Settings()
_relativePaths(false), _relativePaths(false),
_xml(false), _xml_version(1), _xml(false), _xml_version(1),
_jobs(1), _jobs(1),
_loadAverage(0),
_exitCode(0), _exitCode(0),
_showtime(SHOWTIME_NONE), _showtime(SHOWTIME_NONE),
_maxConfigs(12), _maxConfigs(12),

View File

@ -115,6 +115,9 @@ public:
time. Default is 1. (-j N) */ time. Default is 1. (-j N) */
unsigned int _jobs; unsigned int _jobs;
/** @brief Load average value */
unsigned int _loadAverage;
/** @brief If errors are found, this value is returned from main(). /** @brief If errors are found, this value is returned from main().
Default value is 0. */ Default value is 0. */
int _exitCode; int _exitCode;