diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-19 13:46:24 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-19 13:46:24 +0000 |
commit | 3afac4ce0659553ca3e3daf6a8b2131a0607e729 (patch) | |
tree | 6bb173fc034d8e717c5120566341650618e354ac /libbb | |
parent | 08a61180ceeafaa09e33ef5afc8af45a219ccdf1 (diff) | |
download | busybox-w32-3afac4ce0659553ca3e3daf6a8b2131a0607e729.tar.gz busybox-w32-3afac4ce0659553ca3e3daf6a8b2131a0607e729.tar.bz2 busybox-w32-3afac4ce0659553ca3e3daf6a8b2131a0607e729.zip |
top,ps: reduce CPU usage in decimal conversion (optional)
text data bss dec hex filename
734651 3040 14416 752107 b79eb busybox_old
734751 3040 14416 752207 b7a4f busybox_unstripped
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Config.in | 7 | ||||
-rw-r--r-- | libbb/procps.c | 55 |
2 files changed, 60 insertions, 2 deletions
diff --git a/libbb/Config.in b/libbb/Config.in index 5f4e416dd..f82a2b1ce 100644 --- a/libbb/Config.in +++ b/libbb/Config.in | |||
@@ -26,6 +26,13 @@ config MD5_SIZE_VS_SPEED | |||
26 | 2 3.0 5088 | 26 | 2 3.0 5088 |
27 | 3 (smallest) 5.1 4912 | 27 | 3 (smallest) 5.1 4912 |
28 | 28 | ||
29 | config FEATURE_FAST_TOP | ||
30 | bool "Faster /proc scanning code (+100 bytes)" | ||
31 | default n | ||
32 | help | ||
33 | This option makes top (and ps) ~20% faster (or 20% less CPU hungry), | ||
34 | but code size is slightly bigger. | ||
35 | |||
29 | config FEATURE_ETC_NETWORKS | 36 | config FEATURE_ETC_NETWORKS |
30 | bool "Support for /etc/networks" | 37 | bool "Support for /etc/networks" |
31 | default n | 38 | default n |
diff --git a/libbb/procps.c b/libbb/procps.c index 1e2495a5a..879cc105a 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -107,6 +107,28 @@ void free_procps_scan(procps_status_t* sp) | |||
107 | free(sp); | 107 | free(sp); |
108 | } | 108 | } |
109 | 109 | ||
110 | #if ENABLE_FEATURE_FAST_TOP | ||
111 | /* We cut a lot of corners here for speed */ | ||
112 | static unsigned long fast_strtoul_10(char *str, char **endptr) | ||
113 | { | ||
114 | char c; | ||
115 | unsigned long n = *str - '0'; | ||
116 | |||
117 | while ((c = *++str) != ' ') | ||
118 | n = n*10 + (c - '0'); | ||
119 | |||
120 | *endptr = str + 1; /* We skip trailing space! */ | ||
121 | return n; | ||
122 | } | ||
123 | static char *skip_fields(char *str, int count) | ||
124 | { | ||
125 | do { | ||
126 | str = skip_non_whitespace(str); str++; | ||
127 | } while (--count); | ||
128 | return str; | ||
129 | } | ||
130 | #endif | ||
131 | |||
110 | void BUG_comm_size(void); | 132 | void BUG_comm_size(void); |
111 | procps_status_t* procps_scan(procps_status_t* sp, int flags) | 133 | procps_status_t* procps_scan(procps_status_t* sp, int flags) |
112 | { | 134 | { |
@@ -160,7 +182,9 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) | |||
160 | 182 | ||
161 | if (flags & PSSCAN_STAT) { | 183 | if (flags & PSSCAN_STAT) { |
162 | char *cp; | 184 | char *cp; |
185 | #if !ENABLE_FEATURE_FAST_TOP | ||
163 | unsigned long vsz, rss; | 186 | unsigned long vsz, rss; |
187 | #endif | ||
164 | int tty; | 188 | int tty; |
165 | 189 | ||
166 | /* see proc(5) for some details on this */ | 190 | /* see proc(5) for some details on this */ |
@@ -175,6 +199,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) | |||
175 | if (sizeof(sp->comm) < 16) | 199 | if (sizeof(sp->comm) < 16) |
176 | BUG_comm_size(); | 200 | BUG_comm_size(); |
177 | sscanf(buf, "%*s (%15c", sp->comm); | 201 | sscanf(buf, "%*s (%15c", sp->comm); |
202 | |||
203 | #if !ENABLE_FEATURE_FAST_TOP | ||
178 | n = sscanf(cp+2, | 204 | n = sscanf(cp+2, |
179 | "%c %u " /* state, ppid */ | 205 | "%c %u " /* state, ppid */ |
180 | "%u %u %d %*s " /* pgid, sid, tty, tpgid */ | 206 | "%u %u %d %*s " /* pgid, sid, tty, tpgid */ |
@@ -197,6 +223,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) | |||
197 | &rss); | 223 | &rss); |
198 | if (n != 10) | 224 | if (n != 10) |
199 | break; | 225 | break; |
226 | sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */ | ||
227 | sp->rss = rss >> 10; | ||
200 | 228 | ||
201 | sp->tty_str[0] = '?'; | 229 | sp->tty_str[0] = '?'; |
202 | /* sp->tty_str[1] = '\0'; - done by memset */ | 230 | /* sp->tty_str[1] = '\0'; - done by memset */ |
@@ -204,6 +232,31 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) | |||
204 | snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u", | 232 | snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u", |
205 | (tty >> 8) & 0xfff, /* major */ | 233 | (tty >> 8) & 0xfff, /* major */ |
206 | (tty & 0xff) | ((tty >> 12) & 0xfff00)); | 234 | (tty & 0xff) | ((tty >> 12) & 0xfff00)); |
235 | #else | ||
236 | /* This costs ~100 bytes more but makes top faster by 20% | ||
237 | * If you run 10000 processes, this may be important for you */ | ||
238 | cp += 2; | ||
239 | sp->state[0] = *cp++; cp++; | ||
240 | sp->ppid = fast_strtoul_10(cp, &cp); | ||
241 | sp->pgid = fast_strtoul_10(cp, &cp); | ||
242 | sp->sid = fast_strtoul_10(cp, &cp); | ||
243 | sp->tty_str[0] = '?'; | ||
244 | /* sp->tty_str[1] = '\0'; - done by memset */ | ||
245 | tty = fast_strtoul_10(cp, &cp); | ||
246 | if (tty) /* tty field of "0" means "no tty" */ | ||
247 | snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u", | ||
248 | (tty >> 8) & 0xfff, /* major */ | ||
249 | (tty & 0xff) | ((tty >> 12) & 0xfff00)); | ||
250 | cp = skip_fields(cp, 6); /* tpgid, flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ | ||
251 | sp->utime = fast_strtoul_10(cp, &cp); | ||
252 | sp->stime = fast_strtoul_10(cp, &cp); | ||
253 | cp = skip_fields(cp, 3); /* cutime, cstime, priority */ | ||
254 | tasknice = fast_strtoul_10(cp, &cp); | ||
255 | cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */ | ||
256 | sp->vsz = fast_strtoul_10(cp, &cp) >> 10; /* vsize is in bytes and we want kb */ | ||
257 | sp->rss = fast_strtoul_10(cp, &cp) >> 10; | ||
258 | #endif | ||
259 | |||
207 | if (sp->vsz == 0 && sp->state[0] != 'Z') | 260 | if (sp->vsz == 0 && sp->state[0] != 'Z') |
208 | sp->state[1] = 'W'; | 261 | sp->state[1] = 'W'; |
209 | else | 262 | else |
@@ -215,8 +268,6 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags) | |||
215 | else | 268 | else |
216 | sp->state[2] = ' '; | 269 | sp->state[2] = ' '; |
217 | 270 | ||
218 | sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */ | ||
219 | sp->rss = rss >> 10; | ||
220 | } | 271 | } |
221 | 272 | ||
222 | if (flags & PSSCAN_CMD) { | 273 | if (flags & PSSCAN_CMD) { |