aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngelo Marletta <angelo.marletta@gmail.com>2014-03-09 15:44:38 -0700
committerAngelo Marletta <angelo.marletta@gmail.com>2014-03-09 15:44:38 -0700
commitcabeb9947ccddd9a6e6ba14503e2a33063ac1b21 (patch)
tree9dc211ac8439d72510d9b9a8eb3bd657499ddf55
parent3cdc520637fcfd7e72c9c60d90fad1a194d2f8b6 (diff)
parent82fa2cb97759fa32b71b2c67cae71bd5a2ce737f (diff)
downloadcpulimit-cabeb9947ccddd9a6e6ba14503e2a33063ac1b21.tar.gz
merge from develop and fix conflict
-rw-r--r--README36
-rw-r--r--src/cpulimit.c35
-rw-r--r--src/process_group.c48
3 files changed, 48 insertions, 71 deletions
diff --git a/README b/README
index 7b9ddd3..af00bf9 100644
--- a/README
+++ b/README
@@ -1,47 +1,45 @@
CPULIMIT
+========
-=======
- About
-=======
+About
+-----
Cpulimit is a tool which limits the CPU usage of a process (expressed in percentage, not in CPU time). It is useful to control batch jobs, when you don't want them to eat too many CPU cycles. The goal is prevent a process from running for more than a specified time ratio. It does not change the nice value or other scheduling priority settings, but the real CPU usage. Also, it is able to adapt itself to the overall system load, dynamically and quickly.
-The control of the used cpu amount is done sending SIGSTOP and SIGCONT POSIX signals to processes.
-All the children processes and threads of the specified process will share the same percent of CPU.
+The control of the used CPU amount is done sending SIGSTOP and SIGCONT POSIX signals to processes.
+All the children processes and threads of the specified process will share the same percentage of CPU.
Developed by Angelo Marletta.
Please send your feedback, bug reports, feature requests or just thanks.
-============================
- Get the latest source code
-============================
+Get the latest source code
+--------------------------
The latest available code is here:
https://github.com/opsengine/cpulimit
-======================
- Install instructions
-======================
+Install instructions
+--------------------
On Linux/OS X:
-$ make
-# cp src/cpulimit /usr/bin
+ $ make
+ # cp src/cpulimit /usr/bin
On FreeBSD:
-$ gmake
-# cp src/cpulimit /usr/bin
+ $ gmake
+ # cp src/cpulimit /usr/bin
Run unit tests:
-$ ./tests/process_iterator_test
+ $ ./tests/process_iterator_test
-===============
- Contributions
-===============
+
+Contributions
+-------------
You are welcome to contribute to cpulimit with bugfixes, new features, or support for a new OS.
If you want to submit a pull request, please do it on the branch develop and make sure all tests pass.
diff --git a/src/cpulimit.c b/src/cpulimit.c
index 5c85da2..9b25b87 100644
--- a/src/cpulimit.c
+++ b/src/cpulimit.c
@@ -46,6 +46,10 @@
#include "process_group.h"
#include "list.h"
+#ifdef HAVE_SYS_SYSINFO_H
+#include <sys/sysinfo.h>
+#endif
+
#ifdef __APPLE__
#include "memrchr.c"
#endif
@@ -88,14 +92,15 @@ int lazy = 0;
static void quit(int sig)
{
//let all the processes continue if stopped
- if (pgroup.proclist != NULL){
- struct list_node *node = NULL;
- for (node=pgroup.proclist->first; node!= NULL; node=node->next) {
- struct process *p = (struct process*)(node->data);
- kill(p->pid, SIGCONT);
- }
- close_process_group(&pgroup);
- }
+ struct list_node *node = NULL;
+ if (pgroup.proclist != NULL)
+ {
+ for (node = pgroup.proclist->first; node != NULL; node = node->next) {
+ struct process *p = (struct process*)(node->data);
+ kill(p->pid, SIGCONT);
+ }
+ close_process_group(&pgroup);
+ }
//fix ^C little problem
printf("\r");
fflush(stdout);
@@ -115,7 +120,7 @@ static void print_usage(FILE *stream, int exit_code)
fprintf(stream, " -l, --limit=N percentage of cpu allowed from 0 to %d (required)\n", 100*NCPU);
fprintf(stream, " -v, --verbose show control statistics\n");
fprintf(stream, " -z, --lazy exit if there is no target process, or if it dies\n");
- fprintf(stream, " -i, --ignore-children don't limit children processes\n");
+ fprintf(stream, " -i, --include-children limit also the children processes\n");
fprintf(stream, " -h, --help display this help and exit\n");
fprintf(stream, " TARGET must be exactly one of these:\n");
fprintf(stream, " -p, --pid=N pid of the process (implies -z)\n");
@@ -149,6 +154,8 @@ static int get_ncpu() {
int mib[2] = {CTL_HW, HW_NCPU};
size_t len = sizeof(ncpu);
sysctl(mib, 2, &ncpu, &len, NULL, 0);
+#elif defined _GNU_SOURCE
+ ncpu = get_nprocs();
#endif
return ncpu;
}
@@ -309,7 +316,7 @@ int main(int argc, char **argv) {
int pid_ok = 0;
int limit_ok = 0;
pid_t pid = 0;
- int ignore_children = 0;
+ int include_children = 0;
//get program name
char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0]));
@@ -331,7 +338,7 @@ int main(int argc, char **argv) {
{ "limit", required_argument, NULL, 'l' },
{ "verbose", no_argument, NULL, 'v' },
{ "lazy", no_argument, NULL, 'z' },
- { "ignore-children", no_argument, NULL, 'i' },
+ { "include-children", no_argument, NULL, 'i' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
@@ -358,7 +365,7 @@ int main(int argc, char **argv) {
lazy = 1;
break;
case 'i':
- ignore_children = 1;
+ include_children = 1;
break;
case 'h':
print_usage(stdout, 1);
@@ -468,7 +475,7 @@ int main(int argc, char **argv) {
else {
//limiter code
if (verbose) printf("Limiting process %d\n",child);
- limit_process(child, limit, !ignore_children);
+ limit_process(child, limit, include_children);
exit(0);
}
}
@@ -507,7 +514,7 @@ int main(int argc, char **argv) {
}
printf("Process %d found\n", pid);
//control
- limit_process(pid, limit, ignore_children);
+ limit_process(pid, limit, include_children);
}
if (lazy) break;
sleep(2);
diff --git a/src/process_group.c b/src/process_group.c
index cb84deb..f1be459 100644
--- a/src/process_group.c
+++ b/src/process_group.c
@@ -48,10 +48,7 @@ int find_process_by_pid(pid_t pid)
// negative pid, if it is found but it's not possible to control it
int find_process_by_name(const char *process_name)
{
- //whether the variable process_name is the absolute path or not
- int is_absolute_path = process_name[0] == '/';
- //flag indicating if the a process with given name was found
- int found = 0;
+ //pid of the target process
pid_t pid = -1;
//process iterator
@@ -63,47 +60,22 @@ int find_process_by_name(const char *process_name)
init_process_iterator(&it, &filter);
while (get_next_process(&it, &proc) != -1)
{
- pid = proc.pid;
- int size = strlen(proc.command);
-
- found = 0;
- if (is_absolute_path && strncmp(proc.command, process_name, size)==0 && size==strlen(process_name)) {
- //process found
- found = 1;
- }
- else {
- //process found
- if (strncmp(proc.command + size - strlen(process_name), process_name, strlen(process_name))==0) {
- found = 1;
- }
- }
- if (found==1) {
- if (kill(pid,SIGCONT)==0) {
- //process is ok!
- break;
- }
- else {
- //we don't have permission to send signal to that process
- //so, don't exit from the loop and look for another one with the same name
- found = -1;
- }
+ //process found
+ if (strncmp(basename(proc.command), process_name, strlen(process_name))==0 && kill(pid,SIGCONT)==0) {
+ //process is ok!
+ pid = proc.pid;
+ break;
}
}
- if (close_process_iterator(&it) != 1) exit(1);
- if (found == 1) {
+ if (close_process_iterator(&it) != 0) exit(1);
+ if (pid >= 0) {
//ok, the process was found
return pid;
}
- else if (found == 0) {
- //no process found
+ else {
+ //process not found
return 0;
}
- else if (found == -1) {
- //the process was found, but we haven't permission to control it
- return -pid;
- }
- //this MUST NOT happen
- exit(2);
}
int init_process_group(struct process_group *pgroup, int target_pid, int include_children)
Un proyecto texto-plano.xyz