aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-19 13:46:24 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-19 13:46:24 +0000
commit3afac4ce0659553ca3e3daf6a8b2131a0607e729 (patch)
tree6bb173fc034d8e717c5120566341650618e354ac /libbb
parent08a61180ceeafaa09e33ef5afc8af45a219ccdf1 (diff)
downloadbusybox-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.in7
-rw-r--r--libbb/procps.c55
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
29config 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
29config FEATURE_ETC_NETWORKS 36config 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 */
112static 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}
123static 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
110void BUG_comm_size(void); 132void BUG_comm_size(void);
111procps_status_t* procps_scan(procps_status_t* sp, int flags) 133procps_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) {