diff --git a/include/libbb.h b/include/libbb.h index 03fc5d44b..21e144144 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1479,6 +1479,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) FAST_FUNC; void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC; pid_t *find_pid_by_name(const char* procName) FAST_FUNC; pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC; +int starts_with_cpu(const char *str) FAST_FUNC; +unsigned get_cpu_count(void) FAST_FUNC; extern const char bb_uuenc_tbl_base64[]; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 5c567000a..6081ebe4b 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -157,6 +157,9 @@ lib-$(CONFIG_MOUNT) += find_mount_point.o lib-$(CONFIG_HWCLOCK) += rtc.o lib-$(CONFIG_RTCWAKE) += rtc.o +lib-$(CONFIG_IOSTAT) += get_cpu_count.o +lib-$(CONFIG_MPSTAT) += get_cpu_count.o + # We shouldn't build xregcomp.c if we don't need it - this ensures we don't # require regex.h to be in the include dir even if we don't need it thereby # allowing us to build busybox even if uclibc regex support is disabled. diff --git a/libbb/get_cpu_count.c b/libbb/get_cpu_count.c new file mode 100644 index 000000000..a0dcb45f5 --- /dev/null +++ b/libbb/get_cpu_count.c @@ -0,0 +1,47 @@ +/* vi: set sw=4 ts=4: */ +/* + * Factored out of mpstat/iostat. + * + * Copyright (C) 2010 Marek Polacek + * + * Licensed under GPLv2, see file License in this tarball for details. + */ +#include "libbb.h" + +/* Does str start with "cpu"? */ +int FAST_FUNC starts_with_cpu(const char *str) +{ + return ((str[0] - 'c') | (str[1] - 'p') | (str[2] - 'u')) == 0; +} + +/* + * Get number of processors. Uses /proc/stat. + * Return value 0 means one CPU and non SMP kernel. + * Otherwise N means N processor(s) and SMP kernel. + */ +unsigned FAST_FUNC get_cpu_count(void) +{ + FILE *fp; + char line[256]; + int proc_nr = -1; + + fp = xfopen_for_read("/proc/stat"); + while (fgets(line, sizeof(line), fp)) { + if (!starts_with_cpu(line)) { + if (proc_nr >= 0) + break; /* we are past "cpuN..." lines */ + continue; + } + if (line[3] != ' ') { /* "cpuN" */ + int num_proc; + if (sscanf(line + 3, "%u", &num_proc) == 1 + && num_proc > proc_nr + ) { + proc_nr = num_proc; + } + } + } + + fclose(fp); + return proc_nr + 1; +} diff --git a/procps/iostat.c b/procps/iostat.c index 76c5353cc..e8e321b8d 100644 --- a/procps/iostat.c +++ b/procps/iostat.c @@ -114,26 +114,6 @@ static void print_header(void) buf, uts.machine, G.total_cpus); } -static int get_number_of_cpus(void) -{ -#ifdef _SC_NPROCESSORS_CONF - return sysconf(_SC_NPROCESSORS_CONF); -#else - char buf[128]; - int n = 0; - FILE *fp; - - fp = xfopen_for_read("/proc/cpuinfo"); - - while (fgets(buf, sizeof(buf), fp)) - if (strncmp(buf, "processor\t:", 11) == 0) - n++; - - fclose(fp); - return n; -#endif -} - static void get_localtime(struct tm *ptm) { time_t timer; @@ -148,12 +128,6 @@ static void print_timestamp(void) printf("%s\n", buf); } -/* Does str start with "cpu"? */ -static int starts_with_cpu(const char *str) -{ - return ((str[0] - 'c') | (str[1] - 'p') | (str[2] - 'u')) == 0; -} - /* Fetch CPU statistics from /proc/stat */ static void get_cpu_statistics(struct stats_cpu *sc) { @@ -509,7 +483,9 @@ int iostat_main(int argc, char **argv) G.clk_tck = get_user_hz(); /* Determine number of CPUs */ - G.total_cpus = get_number_of_cpus(); + G.total_cpus = get_cpu_count(); + if (G.total_cpus == 0) + G.total_cpus = 1; /* Parse and process arguments */ /* -k and -m are mutually exclusive */ diff --git a/procps/mpstat.c b/procps/mpstat.c index 85cbb45db..b4520cb55 100644 --- a/procps/mpstat.c +++ b/procps/mpstat.c @@ -119,12 +119,6 @@ enum { }; -/* Does str start with "cpu"? */ -static int starts_with_cpu(const char *str) -{ - return !((str[0] - 'c') | (str[1] - 'p') | (str[2] - 'u')); -} - /* Is option on? */ static ALWAYS_INLINE int display_opt(int opt) { @@ -815,38 +809,6 @@ static void print_header(struct tm *t) uts.sysname, uts.release, uts.nodename, cur_date, uts.machine, G.cpu_nr); } -/* - * Get number of processors in /proc/stat - * Return value '0' means one CPU and non SMP kernel. - * Otherwise N means N processor(s) and SMP kernel. - */ -static int get_cpu_nr(void) -{ - FILE *fp; - char line[256]; - int proc_nr = -1; - - fp = xfopen_for_read(PROCFS_STAT); - while (fgets(line, sizeof(line), fp)) { - if (!starts_with_cpu(line)) { - if (proc_nr >= 0) - break; /* we are past "cpuN..." lines */ - continue; - } - if (line[3] != ' ') { /* "cpuN" */ - int num_proc; - if (sscanf(line + 3, "%u", &num_proc) == 1 - && num_proc > proc_nr - ) { - proc_nr = num_proc; - } - } - } - - fclose(fp); - return proc_nr + 1; -} - /* * Get number of interrupts available per processor */ @@ -910,7 +872,7 @@ int mpstat_main(int UNUSED_PARAM argc, char **argv) G.interval = -1; /* Get number of processors */ - G.cpu_nr = get_cpu_nr(); + G.cpu_nr = get_cpu_count(); /* Get number of clock ticks per sec */ G.hz = get_hz();