Skip to content

Commit 840fba7

Browse files
VollmondTdanmar
authored andcommitted
CLI: Add -l command line option
1 parent 05a7e7e commit 840fba7

File tree

5 files changed

+64
-3
lines changed

5 files changed

+64
-3
lines changed

cli/cmdlineparser.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,29 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
576576
PrintMessage("cppcheck: argument for '-j' is allowed to be 10000 at max.");
577577
return false;
578578
}
579+
} else if (std::strncmp(argv[i], "-l", 2) == 0) {
580+
std::string numberString;
581+
582+
// "-l 3"
583+
if (std::strcmp(argv[i], "-l") == 0) {
584+
++i;
585+
if (i >= argc || argv[i][0] == '-') {
586+
PrintMessage("cppcheck: argument to '-l' is missing.");
587+
return false;
588+
}
589+
590+
numberString = argv[i];
591+
}
592+
593+
// "-l3"
594+
else
595+
numberString = argv[i]+2;
596+
597+
std::istringstream iss(numberString);
598+
if (!(iss >> _settings->_loadAverage)) {
599+
PrintMessage("cppcheck: argument to '-l' is not a number.");
600+
return false;
601+
}
579602
}
580603

581604
// print all possible error messages..
@@ -869,6 +892,9 @@ void CmdLineParser::PrintHelp()
869892
" more comments, like: '// cppcheck-suppress warningId'\n"
870893
" on the lines before the warning to suppress.\n"
871894
" -j <jobs> Start [jobs] threads to do the checking simultaneously.\n"
895+
" -l <load> Specifies that no new threads should be started if there\n"
896+
" are other threads running and the load average is at least\n"
897+
" load (ignored on non UNIX-like systems)\n"
872898
" --language=<language>, -x <language>\n"
873899
" Forces cppcheck to check all files as the given\n"
874900
" language. Valid values are: c, c++\n"

cli/threadexecutor.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,22 @@ int ThreadExecutor::handleRead(int rpipe, unsigned int &result)
138138
return 1;
139139
}
140140

141+
bool ThreadExecutor::checkLoadAverage(size_t nchilds)
142+
{
143+
if (!nchilds || !_settings._loadAverage) {
144+
return true;
145+
}
146+
147+
double sample;
148+
if (getloadavg(&sample, 1) != 1) {
149+
// disable load average cheking on getloadavg error
150+
return true;
151+
} else if (sample < _settings._loadAverage) {
152+
return true;
153+
}
154+
return false;
155+
}
156+
141157
unsigned int ThreadExecutor::check()
142158
{
143159
_fileCount = 0;
@@ -155,7 +171,8 @@ unsigned int ThreadExecutor::check()
155171
std::map<std::string, std::size_t>::const_iterator i = _files.begin();
156172
for (;;) {
157173
// Start a new child
158-
if (i != _files.end() && rpipes.size() < _settings._jobs) {
174+
size_t nchilds = rpipes.size();
175+
if (i != _files.end() && nchilds < _settings._jobs && checkLoadAverage(nchilds)) {
159176
int pipes[2];
160177
if (pipe(pipes) == -1) {
161178
std::cerr << "pipe() failed: "<< std::strerror(errno) << std::endl;
@@ -211,8 +228,10 @@ unsigned int ThreadExecutor::check()
211228
FD_ZERO(&rfds);
212229
for (std::list<int>::const_iterator rp = rpipes.begin(); rp != rpipes.end(); ++rp)
213230
FD_SET(*rp, &rfds);
214-
215-
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, NULL);
231+
struct timeval tv; // for every second polling of load average condition
232+
tv.tv_sec = 1;
233+
tv.tv_usec = 0;
234+
int r = select(*std::max_element(rpipes.begin(), rpipes.end()) + 1, &rfds, NULL, NULL, &tv);
216235

217236
if (r > 0) {
218237
std::list<int>::iterator rp = rpipes.begin();
@@ -320,6 +339,11 @@ void ThreadExecutor::addFileContent(const std::string &path, const std::string &
320339
_fileContents[path] = content;
321340
}
322341

342+
bool ThreadExecutor::checkLoadAverage(size_t nchilds)
343+
{
344+
return true;
345+
}
346+
323347
unsigned int ThreadExecutor::check()
324348
{
325349
HANDLE *threadHandles = new HANDLE[_settings._jobs];

cli/threadexecutor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ class ThreadExecutor : public ErrorLogger {
8787
std::list<std::string> _errorList;
8888
int _wpipe;
8989

90+
/**
91+
* @brief Check load average condition
92+
* @param nchilds - count of currently runned childs
93+
* @return true - if new process can be started
94+
*/
95+
bool checkLoadAverage(size_t nchilds);
96+
9097
public:
9198
/**
9299
* @return true if support for threads exist.

lib/settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Settings::Settings()
3434
_relativePaths(false),
3535
_xml(false), _xml_version(1),
3636
_jobs(1),
37+
_loadAverage(0),
3738
_exitCode(0),
3839
_showtime(SHOWTIME_NONE),
3940
_maxConfigs(12),

lib/settings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ class CPPCHECKLIB Settings {
115115
time. Default is 1. (-j N) */
116116
unsigned int _jobs;
117117

118+
/** @brief Load average value */
119+
unsigned int _loadAverage;
120+
118121
/** @brief If errors are found, this value is returned from main().
119122
Default value is 0. */
120123
int _exitCode;

0 commit comments

Comments
 (0)