top,pmap: speed up /smaps parsing
No binary (build failed)
—
(log yok)
| @@ -209,6 +209,8 @@ | |
| # define SWAP_LE64(x) bb_bswap_64(x) | |
| # define IF_BIG_ENDIAN(...) __VA_ARGS__ | |
| # define IF_LITTLE_ENDIAN(...) | |
| + | /* How do bytes a,b,c,d (sequential in memory) look if fetched into uint32_t? */ |
| + | # define PACK32_BYTES(a,b,c,d) (uint32_t)((d)+((c)<<8)+((b)<<16)+((a)<<24)) |
| #else | |
| # define SWAP_BE16(x) bswap_16(x) | |
| # define SWAP_BE32(x) bswap_32(x) | |
| @@ -218,6 +220,7 @@ | |
| # define SWAP_LE64(x) (x) | |
| # define IF_BIG_ENDIAN(...) | |
| # define IF_LITTLE_ENDIAN(...) __VA_ARGS__ | |
| + | # define PACK32_BYTES(a,b,c,d) (uint32_t)((a)+((b)<<8)+((c)<<16)+((d)<<24)) |
| #endif | |
| @@ -195,7 +195,7 @@ static NOINLINE void procps_read_smaps(pid_t pid, procps_status_t *sp) | |
| FILE *file; | |
| char filename[sizeof("/proc/%u/smaps") + sizeof(int)*3]; | |
| - | char buf[PROCPS_BUFSIZE]; |
| + | char buf[PROCPS_BUFSIZE] ALIGN4; |
| sprintf(filename, "/proc/%u/smaps", (int)pid); | |
| @@ -211,20 +211,27 @@ static NOINLINE void procps_read_smaps(pid_t pid, procps_status_t *sp) | |
| // ..... | |
| char *tp; | |
| - | |
| - | if (buf[0] == 'S' || buf[0] == 'P') { |
| + | #define bytes4 *(uint32_t*)buf |
| + | #define Priv PACK32_BYTES('P','r','i','v') |
| + | #define Shar PACK32_BYTES('S','h','a','r') |
| #define SCAN(S, X) \ | |
| - | if (memcmp(buf, S, sizeof(S)-1) == 0) { \ |
| - | tp = skip_whitespace(buf + sizeof(S)-1); \ |
| - | sp->X += fast_strtoul_10(&tp); \ |
| - | continue; \ |
| - | } |
| - | SCAN("Private_Dirty:", private_dirty) |
| - | SCAN("Private_Clean:", private_clean) |
| - | SCAN("Shared_Dirty:" , shared_dirty ) |
| - | SCAN("Shared_Clean:" , shared_clean ) |
| - | #undef SCAN |
| + | if (memcmp(buf+4, S, sizeof(S)-1) == 0) { \ |
| + | tp = skip_whitespace(buf+4 + sizeof(S)-1); \ |
| + | sp->X += fast_strtoul_10(&tp); \ |
| + | continue; \ |
| + | } |
| + | if (bytes4 == Priv) { |
| + | SCAN("ate_Dirty:", private_dirty) |
| + | SCAN("ate_Clean:", private_clean) |
| + | } |
| + | if (bytes4 == Shar) { |
| + | SCAN("ed_Dirty:" , shared_dirty ) |
| + | SCAN("ed_Clean:" , shared_clean ) |
| } | |
| + | #undef bytes4 |
| + | #undef Priv |
| + | #undef Shar |
| + | #undef SCAN |
| tp = strchr(buf, '-'); | |
| if (tp) { | |
| // We reached next mapping - the line of this form: | |
| @@ -109,18 +109,33 @@ static int read_smaps(pid_t pid, char buf[PMAP_BUFSZ], struct smaprec *total) | |
| char *tp, *p; | |
| - | if (buf[0] == 'S' || buf[0] == 'P') { |
| + | #define bytes4 *(uint32_t*)buf |
| + | #define Pss_ PACK32_BYTES('P','s','s',':') |
| + | #define Swap PACK32_BYTES('S','w','a','p') |
| + | #define Priv PACK32_BYTES('P','r','i','v') |
| + | #define FETCH(X, N) \ |
| + | tp = skip_whitespace(buf+4 + (N)); \ |
| + | total->X += currec.X = fast_strtoul_10(&tp); \ |
| + | continue |
| #define SCAN(S, X) \ | |
| - | if (memcmp(buf, S, sizeof(S)-1) == 0) { \ |
| - | tp = skip_whitespace(buf + sizeof(S)-1); \ |
| - | total->X += currec.X = fast_strtoul_10(&tp); \ |
| - | continue; \ |
| - | } |
| - | SCAN("Pss:" , smap_pss ); |
| - | SCAN("Swap:" , smap_swap ); |
| - | SCAN("Private_Dirty:", private_dirty); |
| - | #undef SCAN |
| + | if (memcmp(buf+4, S, sizeof(S)-1) == 0) { \ |
| + | FETCH(X, sizeof(S)-1); \ |
| + | } |
| + | if (bytes4 == Pss_) { |
| + | FETCH(smap_pss, 0); |
| } | |
| + | if (bytes4 == Swap && buf[4] == ':') { |
| + | FETCH(smap_swap, 1); |
| + | } |
| + | if (bytes4 == Priv) { |
| + | SCAN("ate_Dirty:", private_dirty); |
| + | } |
| + | #undef bytes4 |
| + | #undef Pss_ |
| + | #undef Swap |
| + | #undef Priv |
| + | #undef FETCH |
| + | #undef SCAN |
| tp = strchr(buf, '-'); | |
| if (tp) { | |
| // We reached next mapping - the line of this form: | |
| @@ -162,7 +177,7 @@ static int procps_get_maps(pid_t pid, unsigned opt) | |
| { | |
| struct smaprec total; | |
| int ret; | |
| - | char buf[PMAP_BUFSZ]; |
| + | char buf[PMAP_BUFSZ] ALIGN4; |
| ret = read_cmdline(buf, sizeof(buf), pid, NULL); | |
| if (ret < 0) | |