Hello community, here is the log from the commit of package cpulimit for openSUSE:Factory checked in at 2018-02-19 13:03:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cpulimit (Old) and /work/SRC/openSUSE:Factory/.cpulimit.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cpulimit" Mon Feb 19 13:03:32 2018 rev:2 rq:577907 version:2.5 Changes: -------- --- /work/SRC/openSUSE:Factory/cpulimit/cpulimit.changes 2015-01-08 23:01:44.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.cpulimit.new/cpulimit.changes 2018-02-19 13:04:10.759128089 +0100 @@ -1,0 +2,18 @@ +Sun Feb 18 08:34:12 UTC 2018 - [email protected] + +- new upstream version 2.5 + * Added some protection against causing a fork bomb when the + throttled process is a parent to LimitCPU. +- includes 2.4 + * Introduced ability to watch children of the target process. This + means forks of the process we are throttling can also be + throttled, using the "-m" or "--monitor-forks" flags. +- includes 2.3 + * Applied patch to man page which fixes -s description. + * Added --foreground, -f flag for launching target programs in the + foreground. LimitCPU then waits for the target process to exit. + Should be useful in scripts. +- rebase cpulimit-2.2-do_not_forget_version.patch +- cleanup with spec-cleaner + +------------------------------------------------------------------- Old: ---- cpulimit-2.2.tar.gz New: ---- cpulimit-2.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cpulimit.spec ++++++ --- /var/tmp/diff_new_pack.cKKSmU/_old 2018-02-19 13:04:12.107079477 +0100 +++ /var/tmp/diff_new_pack.cKKSmU/_new 2018-02-19 13:04:12.115079188 +0100 @@ -2,7 +2,7 @@ # # spec file for package cpulimit # -# Copyright (c) 2012-2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,18 +18,17 @@ Name: cpulimit -Version: 2.2 +Version: 2.5 Release: 0 Summary: Limit the CPU Usage of a Process License: GPL-2.0+ Group: System/Monitoring Url: http://limitcpu.sourceforge.net/ -Source0: http://prdownloads.sourceforge.net/limitcpu/cpulimit-%{version}.tar.gz +Source0: http://prdownloads.sourceforge.net/limitcpu/%{name}-%{version}.tar.gz Patch0: %{name}-2.2-do_not_forget_version.patch BuildRequires: gcc BuildRequires: glibc-devel BuildRequires: make -BuildRoot: %{_tmppath}/%{name}-%{version}-build %description LimitCPU is a program to throttle the CPU cycles used by other applications. @@ -47,21 +46,15 @@ %patch0 -p1 %build -make %{?_smp_flags} \ - PREFIX="%{_prefix}" \ +make %{?_smp_mflags} \ CFLAGS="%{optflags}" %install -install -D -m0755 %{name} "%{buildroot}%{_bindir}/%{name}" -install -D -m0644 %{name}.1 "%{buildroot}%{_mandir}/man1/%{name}.1" - -%clean -%{?buildroot:rm -rf %{buildroot}} +%make_install PREFIX=%{buildroot}/%{_prefix} %files -%defattr(-,root,root) %doc LICENSE CHANGELOG README TODO %{_bindir}/%{name} -%doc %{_mandir}/man1/%{name}.1%{ext_man} +%{_mandir}/man1/%{name}.1%{ext_man} %changelog ++++++ cpulimit-2.2-do_not_forget_version.patch ++++++ --- /var/tmp/diff_new_pack.cKKSmU/_old 2018-02-19 13:04:12.139078323 +0100 +++ /var/tmp/diff_new_pack.cKKSmU/_new 2018-02-19 13:04:12.139078323 +0100 @@ -1,12 +1,11 @@ -diff -uNr old-cpulimit-2.2/cpulimit.c cpulimit-2.2/cpulimit.c ---- old-cpulimit-2.2/cpulimit.c 2014-12-26 10:24:53.788487238 +0100 -+++ cpulimit-2.2/cpulimit.c 2014-12-26 10:25:17.024096912 +0100 +--- a/cpulimit.c 2014-12-26 10:24:53.788487238 +0100 ++++ b/cpulimit.c 2014-12-26 10:25:17.024096912 +0100 @@ -80,7 +80,7 @@ #endif #ifndef VERSION --#define VERSION 2.1 -+#define VERSION 2.2 +-#define VERSION 2.4 ++#define VERSION 2.5 #endif //pid of the controlled process ++++++ cpulimit-2.2.tar.gz -> cpulimit-2.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/CHANGELOG new/cpulimit-2.5/CHANGELOG --- old/cpulimit-2.2/CHANGELOG 2014-05-24 00:09:14.000000000 +0200 +++ new/cpulimit-2.5/CHANGELOG 2017-03-27 19:03:18.000000000 +0200 @@ -1,3 +1,24 @@ +========== Changes in 2.5 ================= + +* Added some protection against causing a fork bomb + when the throttled process is a parent to LimitCPU. + Patch provided by Johann Felix. + +========== Changes in 2.4 ================= + +* Introduced ability to watch children of the target + process. This means forks of the process we are throttling + can also be throttled, using the "-m" or "--monitor-forks" flags. + +=========== Changes in 2.3 ================ + +* Applied patch to man page which fixes -s description. + +* Added --foreground, -f flag for launching target programs in + the foreground. LimitCPU then waits for the target process to exit. + Should be useful in scripts. Closes Debian bug #836027. + + =========== Changes in 2.2 ================ * Escaped double-dashed in manual page to avoid diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/Makefile new/cpulimit-2.5/Makefile --- old/cpulimit-2.2/Makefile 2014-05-22 23:20:06.000000000 +0200 +++ new/cpulimit-2.5/Makefile 2017-03-27 19:01:48.000000000 +0200 @@ -1,4 +1,4 @@ -VERSION?=2.2 +VERSION?=2.5 PREFIX?=/usr CFLAGS?=-Wall -O2 -DVERSION=$(VERSION) CC?=gcc @@ -15,7 +15,7 @@ $(CC) -o cpulimit cpulimit.c -lrt -DFREEBSD $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) cpulimit: cpulimit.c - $(CC) -o cpulimit cpulimit.c -lrt -DLINUX $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + $(CC) -o cpulimit cpulimit.c -pthread -lrt -DLINUX $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) tests: $(MAKE) -C test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/README new/cpulimit-2.5/README --- old/cpulimit-2.2/README 2014-05-24 00:17:00.000000000 +0200 +++ new/cpulimit-2.5/README 2016-11-19 23:23:20.000000000 +0100 @@ -22,7 +22,7 @@ file named LICENSE. Copyright 2005, Angelo Marletta <[email protected]> -Copyright 2011-2014, Jesse Smith <[email protected]> +Copyright 2011-2016, Jesse Smith <[email protected]> @@ -181,6 +181,13 @@ cpulimit -l 25 -p 1234 --signal=15 +LimitCPU can be used to watch not only one target process, but also +child processes the target spawns. This means new processs the +target creates will also be throttled. By default, LimitCPU +only watches one target process and ignores children, but monitoring +children can be enabled using the "-m" or "--monitor-forks" flag. + +cpulimit -l 25 -p 1234 -m diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/TODO new/cpulimit-2.5/TODO --- old/cpulimit-2.2/TODO 2014-04-07 01:39:56.000000000 +0200 +++ new/cpulimit-2.5/TODO 2016-11-19 23:23:20.000000000 +0100 @@ -1,3 +1 @@ -- light and scalable algorithm for subprocesses detection and limitation - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/cpulimit.1 new/cpulimit-2.5/cpulimit.1 --- old/cpulimit-2.2/cpulimit.1 2014-05-24 00:16:02.000000000 +0200 +++ new/cpulimit-2.5/cpulimit.1 2016-11-19 23:23:20.000000000 +0100 @@ -22,6 +22,9 @@ \fB\-b\fR, \fB\-\-background\fR run cpulimit in the background, freeing up the terminal .TP +\fB\-f\fR, \fB\-\-foreground\fR +run cpulimit in foreground while waiting for launched process to finish +.TP \fB\-c\fR, \fB\-\-cpu\fR specify the number of CPU cores available. Usually this is detected for us. .TP @@ -34,6 +37,9 @@ \fB\-k\fR, \fB\-\-kill\fR kill target process instead of throttling its CPU usage .TP +\fB\-m\fR, \fB\-\-monitor\-forks\fR +watch and throttle child processes of the target process +.TP \fB\-r\fR, \fB\-\-restore\fR restore a process killed using the \-k flag. .TP @@ -90,7 +96,7 @@ Launch the Firefox program and kill it if the process goes over 20% CPU usage. .TP -\[sh] \fBcpulimit \-l 20 \-p 1234 -s SIGTERM +\[sh] \fBcpulimit \-l 20 \-p 1234 \-s SIGTERM Throttle process 1234 at 20% CPU usage. If cpulimit is forced to exit, it sends the watched process the SIGTERM signal. .SH NOTES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cpulimit-2.2/cpulimit.c new/cpulimit-2.5/cpulimit.c --- old/cpulimit-2.2/cpulimit.c 2014-05-25 17:09:17.000000000 +0200 +++ new/cpulimit-2.5/cpulimit.c 2017-03-27 18:59:11.000000000 +0200 @@ -56,6 +56,11 @@ #include <sys/user.h> #endif +#ifdef LINUX +#include <dirent.h> +#define PROC_FILENAME 64 +#define LINE_LENGTH 256 +#endif //kernel time resolution (inverse of one jiffy interval) in Hertz //i don't know how to detect it, then define to the default (not very clean!) @@ -80,7 +85,7 @@ #endif #ifndef VERSION -#define VERSION 2.1 +#define VERSION 2.4 #endif //pid of the controlled process @@ -123,6 +128,29 @@ } +#ifdef LINUX +#include <pthread.h> + +typedef struct +{ + pid_t child; // the child of our target process + pid_t monitor; // the LimitCPU fork monitoring the child + void *next; +} CHILD; + +int quitting = FALSE; // Have we receive a quit signal +int monitor_children = FALSE; // are we monitoring children of target + +// Data passed to the monitor thread +typedef struct +{ + int limit; // per cent limit to place on a process + char *this_program; // copy of argv[0] +} PROGRAM_DATA; + +#endif + + int Check_Us(pid_t target_pid) { @@ -325,13 +353,38 @@ void quit(int sig) { //let the process continue if we are stopped kill(pid, send_signal); + #ifdef LINUX + if (monitor_children) + { + quitting = TRUE; + printf("Asking children to quit...\n"); + sleep(2); // wait for thread clean-up + } + #endif printf("Exiting...\n"); exit(0); } +// Handle a child process quitting +void Child_Done(int sig) +{ + pid_t caught_child; + caught_child = waitpid(-1, NULL, WNOHANG); + if (verbose) + { + printf("Caught child process: %d\n", (int) caught_child); + printf("%d\n", errno); + } + // If this was the one process we were watching, we can quit now. + if (caught_child == pid) + { + printf("Child process is finished, exiting...\n"); + exit(0); + } +} + #ifdef FREEBSD -//get jiffies count from /proc filesystem int getjiffies(int pid) { kvm_t *my_kernel = NULL; @@ -359,6 +412,7 @@ #endif #ifdef LINUX +//get jiffies count from /proc filesystem int getjiffies(int pid) { static char stat[20]; static char buffer[1024]; @@ -500,6 +554,248 @@ +#ifdef LINUX +// This following functions are for detecting and limiting child +// processes on Linux. + +// This function adds a new child process to our list of child processes. +CHILD *Add_Child(CHILD *all_children, pid_t new_pid) +{ + CHILD *new_child = (CHILD *) calloc(sizeof(CHILD), 1); + CHILD *current; + + if (! new_child) + return all_children; + + new_child->next = NULL; + new_child->child = new_pid; + new_child->monitor = 0; + + if (all_children) + { + current = all_children; + while (current->next) + current = current->next; + current->next = new_child; + return all_children; + } + else // this is the first node + return new_child; +} + + + +// This function removes a child PID node. +CHILD *Remove_Child(CHILD *all_children, pid_t old_pid) +{ + CHILD *current, *previous = NULL; + int found = FALSE; + + current = all_children; + while ( (! found) && (current) ) + { + if (current->child == old_pid) + { + if (previous) + previous->next = current->next; + else + all_children = current->next; + + free(current); + found = TRUE; + } + else + { + previous = current; + current = current->next; + } + } + return all_children; +} + + +// This function cleans up all remaining child nodes. +void Clean_Up_Children(CHILD *all_children) +{ + CHILD *current, *next; + + current = all_children; + while (current) + { + next = current->next; + free(current); + current = next; + } +} + + +// This function searches the linked list for a matching PID. +// It returns NULL if no match is found and a pointer to the +// node is a match is located. +CHILD *Find_Child(CHILD *children, pid_t target) +{ + CHILD *current; + int found = FALSE; + + current = children; + while ( (!found) && (current) ) + { + if (current->child == target) + found = TRUE; + else + current = current->next; + } + return current; +} + + + +// This function returns a list of process IDs of children +// of the given process (PID). It does this by searching the /proc +// file system and looking in the /proc/pid/status file for the PPid field. +// A linked list of child PIDs is returned on success or NULL on failure or +// if no child PIDs are found. +CHILD *Find_Child_PIDs(CHILD *all_children, pid_t parent_pid) +{ + int found = FALSE; + DIR *proc; + struct dirent *proc_entry; + char filename[PROC_FILENAME]; + FILE *status_file; + char *reading_file; + char line[256]; + pid_t new_ppid; + int current_pid; + + proc = opendir("/proc"); + if (! proc) + return all_children; + + proc_entry = readdir(proc); + while (proc_entry) + { + snprintf(filename, PROC_FILENAME, "/proc/%s/status", proc_entry->d_name); + status_file = fopen(filename, "r"); + if (status_file) + { + found = FALSE; + reading_file = fgets(line, LINE_LENGTH, status_file); + while ( (! found) && (reading_file) ) + { + if (! strncmp(line, "PPid:", 5) ) + { + sscanf(&(line[6]), "%d", &new_ppid); + if (new_ppid == parent_pid && current_pid != getpid() ) + { + sscanf(proc_entry->d_name, "%d", ¤t_pid); + if (! Find_Child(all_children, current_pid) ) + all_children = Add_Child(all_children, current_pid); + } + found = TRUE; + } + else + reading_file = fgets(line, LINE_LENGTH, status_file); + } // done reading status file + + fclose(status_file); + } + proc_entry = readdir(proc); + } // done reading proc file system + closedir(proc); + return all_children; +} + + +// This function (which should probably be called as a thread) monitors the +// system for child processes of the current target process. When a new +// child of the target is located, it is added to the CHILD list. +// New children result in a new fork of this program being spawned to +// monitor the child process and its children. + +void *Monitor_Children(void *all_data) +{ + CHILD *all_children = NULL; + CHILD *current; + PROGRAM_DATA *program_data = (PROGRAM_DATA *) all_data; + + while (! quitting ) + { + // Check for new child processes + all_children = Find_Child_PIDs(all_children, pid); + + // Find any children without monitors and create a monitoring process + // Clean out old processes while we are looking + current = all_children; + while (current) + { + // First see if the child process is still running. If not, + // we can remote its node. + if (current->child) + { + char filename[PROC_FILENAME]; + DIR *child_directory; + snprintf(filename, PROC_FILENAME, "/proc/%d", current->child); + child_directory = opendir(filename); + if (child_directory) + closedir(child_directory); + else + { + if (verbose) + printf("Child process %d done, cleaning up.\n", + (int) current->child); + all_children = Remove_Child(all_children, current->child); + } + } // end of clean up children processes no longer running + + // The child process is still running, but it might not have + // a monitor. Create a new monitoring process. + if ( (current->child) && (! current->monitor) ) + { + pid_t returned_pid; + + if (verbose) + printf("Creating monitoring process for %d\n", + (int) current->child); + + returned_pid = fork(); + if (returned_pid > 0) + { + // parent + current->monitor = returned_pid; + } + else if (returned_pid == 0) + { + // child + char limit_amount[16]; + char process_identifier[16]; + snprintf(limit_amount, 16, "%d", (int) program_data->limit); + snprintf(process_identifier, 16, "%d", current->child); + if (verbose) + printf("Starting monitor with: %s -l %s -p %s -z -m\n", + program_data->this_program, limit_amount, + process_identifier); + execl(program_data->this_program, program_data->this_program, + "-l", limit_amount, "-p", process_identifier, + "-z", "-m", (char *) NULL); + } + + } // end of creating a new monitor + if (verbose) + { + printf("Watching child: %d with %d\n", + (int) current->child, (int) current->monitor); + } + current = current->next; + } + sleep(1); + } // end LimitCPU is still running + pthread_exit(NULL); +} + +#endif // end of monitoring children processes on Linux + + + void print_usage(FILE *stream,int exit_code) { fprintf(stream, "CPUlimit version %1.1f\n", VERSION); fprintf(stream, "Usage: %s TARGET [OPTIONS...] [-- PROGRAM]\n",program_name); @@ -512,10 +808,14 @@ fprintf(stream, " executable program file\n"); fprintf(stream, " OPTIONS\n"); fprintf(stream, " -b --background run in background\n"); + fprintf(stream, " -f --foreground launch target process in foreground and wait for it to exit\n"); fprintf(stream, " -c --cpu=N override the detection of CPUs on the machine.\n"); fprintf(stream, " -l, --limit=N percentage of cpu allowed from 1 up.\n"); fprintf(stream, " Usually 1 - %d00, but can be higher\n", NCPU); fprintf(stream, " on multi-core CPUs (mandatory)\n"); + #ifdef LINUX + fprintf(stream, " -m, --monitor-forks Watch children/forks of the target process\n"); + #endif fprintf(stream, " -q, --quiet run in quiet mode (only print errors).\n"); fprintf(stream, " -k, --kill kill processes going over their limit\n"); fprintf(stream, " instead of just throttling them.\n"); @@ -585,7 +885,12 @@ //parse arguments int next_option; /* A string listing valid short options letters. */ - const char* short_options="p:e:P:l:c:s:bqkrvzh"; + #ifdef LINUX + const char* short_options="p:e:P:l:c:s:bfqkmrvzh"; + PROGRAM_DATA program_data; + #else + const char* short_options="p:e:P:l:c:s:bfqkrvzh"; + #endif /* An array describing valid long options. */ const struct option long_options[] = { { "pid", required_argument, NULL, 'p' }, @@ -593,17 +898,21 @@ { "path", required_argument, NULL, 'P' }, { "limit", required_argument, NULL, 'l' }, { "background", no_argument, NULL, 'b' }, + { "foreground", no_argument, NULL, 'f' }, { "quiet", no_argument, NULL, 'q' }, { "verbose", no_argument, NULL, 'v' }, { "lazy", no_argument, NULL, 'z' }, { "help", no_argument, NULL, 'h' }, { "cpu", required_argument, NULL, 'c'}, { "signal", required_argument, NULL, 's'}, + #ifdef LINUX + { "monitor-forks", no_argument, NULL, 'm'}, + #endif { NULL, 0, NULL, 0 } }; //argument variables const char *exe=NULL; - const char *path=NULL; + const char *path=NULL; int perclimit=0; int pid_ok = FALSE; int process_ok = FALSE; @@ -611,6 +920,8 @@ int last_known_argument = 0; int kill_process = FALSE; // kill process instead of stopping it int restore_process = FALSE; // restore killed process + int run_child_in_background = TRUE; // run cpulimit in background when + // we launch new process // struct rlimit maxlimit; NCPU = get_ncpu(); @@ -623,6 +934,11 @@ run_in_background = TRUE; last_known_argument++; break; + case 'f': + run_child_in_background = FALSE; + run_in_background = FALSE; + last_known_argument++; + break; case 'p': pid=atoi(optarg); if (pid) // valid PID @@ -663,6 +979,12 @@ kill_process = TRUE; last_known_argument++; break; + #ifdef LINUX + case 'm': + monitor_children = TRUE; + last_known_argument++; + break; + #endif case 'r': restore_process = TRUE; last_known_argument++; @@ -699,6 +1021,7 @@ } } while(next_option != -1); + signal(SIGCHLD, Child_Done); // try to launch a program passed on the command line // But only if we do not already have a PID to watch @@ -737,39 +1060,34 @@ // a running head start to avoid death at start-up if (kill_process) sleep(5); - - limit_pid = fork(); - if (limit_pid == 0) // child + + /* The following block assumes we want to run cpulimit in the + background. This is the default behaviour. + */ + if (run_child_in_background) { - pid = forked_pid; // the first child - lazy = TRUE; - pid_ok = TRUE; - if (verbose) - printf("Throttling process %d\n", (int) pid); - } - else // parent - exit(0); - } + limit_pid = fork(); + if (limit_pid == 0) // child cpulimit process running in background + { + pid = forked_pid; // the first child, target process + lazy = TRUE; + pid_ok = TRUE; + if (verbose) + printf("Throttling process %d\n", (int) pid); + } + else // parent cpulimit process which can quit + exit(0); + } // end of running in background + else + { + pid = forked_pid; + lazy = TRUE; + pid_ok = TRUE; + run_in_background = FALSE; + } // end of running in foreground + + } // end of parent that launched target - /* - else if (forked_pid == 0) // child - { - lazy = TRUE; - pid_ok = TRUE; - pid = getppid(); - if (verbose) - printf("Throttling process %d\n", (int) pid); - } - else // parent - { - execvp(argv[last_known_argument], - &(argv[last_known_argument])); - - // we should never return - exit(2); - } - */ - } // end of launching child process if (!process_ok && !pid_ok) { @@ -820,50 +1138,6 @@ printf("%d CPUs detected.\n", NCPU); increase_priority(); -/* -Instead of all this big block of code to detect and change -priority settings, let us just use the increase_priority() -function. It is a little more simple and takes a more -gradual approach, rather than "all or nothing". --- Jesse - - if (setpriority(PRIO_PROCESS, my_pid,-20)!=0) { - //if that failed, check if we have a limit - // by how much we can raise the priority -#ifdef RLIMIT_NICE -//check if non-root can even make changes -// (ifdef because it's only available in linux >= 2.6.13) - nice_lim=getpriority(PRIO_PROCESS, my_pid); - getrlimit(RLIMIT_NICE, &maxlimit); - -//if we can do better then current - if( (20 - (signed)maxlimit.rlim_cur) < nice_lim && - setpriority(PRIO_PROCESS, my_pid, - 20 - (signed)maxlimit.rlim_cur)==0 //and it actually works - ) { - - //if we can do better, but not by much, warn about it - if( (nice_lim - (20 - (signed)maxlimit.rlim_cur)) < 9) - { - printf("Warning, can only increase priority by %d.\n", nice_lim - (20 - (signed)maxlimit.rlim_cur)); - } - //our new limit - nice_lim = 20 - (signed)maxlimit.rlim_cur; - - } else -// otherwise don't try to change priority. -// The below will also run if it's not possible -// for non-root to change priority -#endif - { - printf("Warning: cannot renice.\nTo work better you should run this program as root, or adjust RLIMIT_NICE.\nFor example in /etc/security/limits.conf add a line with: * - nice -10\n\n"); - nice_lim=INT_MAX; - } - } else { - nice_lim=-20; - } -*/ - //time quantum in microseconds. it's splitted in a working period and a sleeping one int period=100000; @@ -896,6 +1170,23 @@ float pcpu_avg=0; + // On Linux we can monitor child processes of the target + #ifdef LINUX + if (monitor_children) + { + pthread_t my_thread; + int thread_status; + if (verbose) + printf("Starting fork monitoring thread...\n"); + program_data.this_program = argv[0]; + program_data.limit = perclimit; + thread_status = pthread_create(&my_thread, NULL, + Monitor_Children, &program_data); + if ( (thread_status) && (verbose) ) + printf("Creating fork monitoring thread failed.\n"); + } + #endif + //here we should already have high priority, for time precision while(1) { @@ -945,9 +1236,9 @@ // printf("Continue\n"); //resume process if (kill(pid,SIGCONT)!=0) { - if (!quiet) + if (!quiet) fprintf(stderr,"Process %d dead!\n",pid); - if (lazy) exit(2); + if (lazy) exit(2); //wait until our process appears goto wait_for_process; } @@ -1024,16 +1315,16 @@ } } } - // do not kll process, just throttle it + // do not kill process, just throttle it else { // printf("Stop\n"); //stop process, it has worked enough if (kill(pid,SIGSTOP)!=0) { - if (!quiet) + if (!quiet) fprintf(stderr,"Process %d dead!\n", pid); - if (lazy) exit(2); + if (lazy) exit(2); //wait until our process appears goto wait_for_process; }
