← Commit list

0b05a4e71

Denys Vlasenko
Denys Vlasenko
2025-08-06
SUCCESS Duration: 158s

Subject

top,pmap: speed up /smaps parsing

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

include/platform.h+3 -0
@@ -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
libbb/procps.c+20 -13
@@ -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:
procps/pmap.c+26 -11
@@ -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)