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
This commit is contained in:
parent
08a61180ce
commit
3afac4ce06
@ -26,6 +26,13 @@ config MD5_SIZE_VS_SPEED
|
|||||||
2 3.0 5088
|
2 3.0 5088
|
||||||
3 (smallest) 5.1 4912
|
3 (smallest) 5.1 4912
|
||||||
|
|
||||||
|
config FEATURE_FAST_TOP
|
||||||
|
bool "Faster /proc scanning code (+100 bytes)"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This option makes top (and ps) ~20% faster (or 20% less CPU hungry),
|
||||||
|
but code size is slightly bigger.
|
||||||
|
|
||||||
config FEATURE_ETC_NETWORKS
|
config FEATURE_ETC_NETWORKS
|
||||||
bool "Support for /etc/networks"
|
bool "Support for /etc/networks"
|
||||||
default n
|
default n
|
||||||
|
@ -107,6 +107,28 @@ void free_procps_scan(procps_status_t* sp)
|
|||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_FAST_TOP
|
||||||
|
/* We cut a lot of corners here for speed */
|
||||||
|
static unsigned long fast_strtoul_10(char *str, char **endptr)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
unsigned long n = *str - '0';
|
||||||
|
|
||||||
|
while ((c = *++str) != ' ')
|
||||||
|
n = n*10 + (c - '0');
|
||||||
|
|
||||||
|
*endptr = str + 1; /* We skip trailing space! */
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
static char *skip_fields(char *str, int count)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
str = skip_non_whitespace(str); str++;
|
||||||
|
} while (--count);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void BUG_comm_size(void);
|
void BUG_comm_size(void);
|
||||||
procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
||||||
{
|
{
|
||||||
@ -160,7 +182,9 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
|||||||
|
|
||||||
if (flags & PSSCAN_STAT) {
|
if (flags & PSSCAN_STAT) {
|
||||||
char *cp;
|
char *cp;
|
||||||
|
#if !ENABLE_FEATURE_FAST_TOP
|
||||||
unsigned long vsz, rss;
|
unsigned long vsz, rss;
|
||||||
|
#endif
|
||||||
int tty;
|
int tty;
|
||||||
|
|
||||||
/* see proc(5) for some details on this */
|
/* see proc(5) for some details on this */
|
||||||
@ -175,6 +199,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
|||||||
if (sizeof(sp->comm) < 16)
|
if (sizeof(sp->comm) < 16)
|
||||||
BUG_comm_size();
|
BUG_comm_size();
|
||||||
sscanf(buf, "%*s (%15c", sp->comm);
|
sscanf(buf, "%*s (%15c", sp->comm);
|
||||||
|
|
||||||
|
#if !ENABLE_FEATURE_FAST_TOP
|
||||||
n = sscanf(cp+2,
|
n = sscanf(cp+2,
|
||||||
"%c %u " /* state, ppid */
|
"%c %u " /* state, ppid */
|
||||||
"%u %u %d %*s " /* pgid, sid, tty, tpgid */
|
"%u %u %d %*s " /* pgid, sid, tty, tpgid */
|
||||||
@ -197,6 +223,8 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
|||||||
&rss);
|
&rss);
|
||||||
if (n != 10)
|
if (n != 10)
|
||||||
break;
|
break;
|
||||||
|
sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
|
||||||
|
sp->rss = rss >> 10;
|
||||||
|
|
||||||
sp->tty_str[0] = '?';
|
sp->tty_str[0] = '?';
|
||||||
/* sp->tty_str[1] = '\0'; - done by memset */
|
/* sp->tty_str[1] = '\0'; - done by memset */
|
||||||
@ -204,6 +232,31 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
|||||||
snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
|
snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
|
||||||
(tty >> 8) & 0xfff, /* major */
|
(tty >> 8) & 0xfff, /* major */
|
||||||
(tty & 0xff) | ((tty >> 12) & 0xfff00));
|
(tty & 0xff) | ((tty >> 12) & 0xfff00));
|
||||||
|
#else
|
||||||
|
/* This costs ~100 bytes more but makes top faster by 20%
|
||||||
|
* If you run 10000 processes, this may be important for you */
|
||||||
|
cp += 2;
|
||||||
|
sp->state[0] = *cp++; cp++;
|
||||||
|
sp->ppid = fast_strtoul_10(cp, &cp);
|
||||||
|
sp->pgid = fast_strtoul_10(cp, &cp);
|
||||||
|
sp->sid = fast_strtoul_10(cp, &cp);
|
||||||
|
sp->tty_str[0] = '?';
|
||||||
|
/* sp->tty_str[1] = '\0'; - done by memset */
|
||||||
|
tty = fast_strtoul_10(cp, &cp);
|
||||||
|
if (tty) /* tty field of "0" means "no tty" */
|
||||||
|
snprintf(sp->tty_str, sizeof(sp->tty_str), "%u,%u",
|
||||||
|
(tty >> 8) & 0xfff, /* major */
|
||||||
|
(tty & 0xff) | ((tty >> 12) & 0xfff00));
|
||||||
|
cp = skip_fields(cp, 6); /* tpgid, flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
|
||||||
|
sp->utime = fast_strtoul_10(cp, &cp);
|
||||||
|
sp->stime = fast_strtoul_10(cp, &cp);
|
||||||
|
cp = skip_fields(cp, 3); /* cutime, cstime, priority */
|
||||||
|
tasknice = fast_strtoul_10(cp, &cp);
|
||||||
|
cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */
|
||||||
|
sp->vsz = fast_strtoul_10(cp, &cp) >> 10; /* vsize is in bytes and we want kb */
|
||||||
|
sp->rss = fast_strtoul_10(cp, &cp) >> 10;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sp->vsz == 0 && sp->state[0] != 'Z')
|
if (sp->vsz == 0 && sp->state[0] != 'Z')
|
||||||
sp->state[1] = 'W';
|
sp->state[1] = 'W';
|
||||||
else
|
else
|
||||||
@ -215,8 +268,6 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
|
|||||||
else
|
else
|
||||||
sp->state[2] = ' ';
|
sp->state[2] = ' ';
|
||||||
|
|
||||||
sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */
|
|
||||||
sp->rss = rss >> 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & PSSCAN_CMD) {
|
if (flags & PSSCAN_CMD) {
|
||||||
|
Loading…
Reference in New Issue
Block a user