[git commit] libbb: add and use infrastructure for fixed page size optimization

Denys Vlasenko vda.linux at googlemail.com
Mon Dec 14 17:54:30 UTC 2020


commit: https://git.busybox.net/busybox/commit/?id=c7b858ff8d2e8b2d785f74b2d319bc9c839f4faa
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
procps_scan                                         1121    1118      -3
getpagesize                                            6       -      -6
rpm_main                                            1037    1027     -10
rpm2cpio_main                                        120     110     -10
ptok                                                  38      21     -17
time_main                                           1282    1261     -21
mkswap_main                                          317     278     -39
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 0/6 up/down: 0/-106)           Total: -106 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 archival/rpm.c      | 10 ++++++----
 include/libbb.h     | 18 ++++++++++++++++++
 libbb/procps.c      |  4 ++--
 miscutils/devmem.c  |  2 +-
 miscutils/hexedit.c | 14 +++-----------
 miscutils/time.c    |  7 ++++++-
 util-linux/mkswap.c |  2 +-
 7 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/archival/rpm.c b/archival/rpm.c
index a4d850b46..af8db99a6 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -83,7 +83,9 @@ struct globals {
 	void *map;
 	rpm_index *mytags;
 	int tagcount;
-	unsigned mapsize, pagesize;
+	unsigned mapsize;
+	IF_VARIABLE_ARCH_PAGESIZE(unsigned pagesize;)
+#define G_pagesize cached_pagesize(G.pagesize)
 } FIX_ALIASING;
 #define G (*(struct globals*)bb_common_bufsiz1)
 #define INIT_G() do { setup_common_bufsiz(); } while (0)
@@ -141,7 +143,7 @@ static int rpm_gettags(const char *filename)
 	G.mytags = tags;
 
 	/* Map the store */
-	storepos = (storepos + G.pagesize) & -(int)G.pagesize;
+	storepos = (storepos + G_pagesize) & -(int)G_pagesize;
 	/* remember size for munmap */
 	G.mapsize = storepos;
 	/* some NOMMU systems prefer MAP_PRIVATE over MAP_SHARED */
@@ -356,7 +358,7 @@ int rpm_main(int argc, char **argv)
 	int opt, func = 0;
 
 	INIT_G();
-	G.pagesize = getpagesize();
+	INIT_PAGESIZE(G.pagesize);
 
 	while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
 		switch (opt) {
@@ -523,7 +525,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
 	int rpm_fd;
 
 	INIT_G();
-	G.pagesize = getpagesize();
+	INIT_PAGESIZE(G.pagesize);
 
 	rpm_fd = rpm_gettags(argv[1]);
 
diff --git a/include/libbb.h b/include/libbb.h
index a74b3119f..db5bf7a51 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -391,6 +391,24 @@ void *mmap_read(int fd, size_t size) FAST_FUNC;
 void *mmap_anon(size_t size) FAST_FUNC;
 void *xmmap_anon(size_t size) FAST_FUNC;
 
+#if defined(__x86_64__) || defined(i386)
+# define BB_ARCH_FIXED_PAGESIZE 4096
+#else /* if defined(ARCH) */
+/* add you favorite arch today! */
+#endif
+
+#if defined BB_ARCH_FIXED_PAGESIZE
+# define IF_VARIABLE_ARCH_PAGESIZE(...) /*nothing*/
+# define bb_getpagesize()     BB_ARCH_FIXED_PAGESIZE
+# define INIT_PAGESIZE(var)   ((void)0)
+# define cached_pagesize(var) BB_ARCH_FIXED_PAGESIZE
+#else
+# define IF_VARIABLE_ARCH_PAGESIZE(...) __VA_ARGS__
+# define bb_getpagesize()     getpagesize()
+# define INIT_PAGESIZE(var)   ((var) = getpagesize())
+# define cached_pagesize(var) (var)
+#endif
+
 
 //TODO: supply a pointer to char[11] buffer (avoid statics)?
 extern const char *bb_mode_string(mode_t mode) FAST_FUNC;
diff --git a/libbb/procps.c b/libbb/procps.c
index 4cc3cb2a1..975e0d4dc 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -94,15 +94,15 @@ static int read_to_buf(const char *filename, void *buf)
 
 static procps_status_t* FAST_FUNC alloc_procps_scan(void)
 {
-	unsigned n = getpagesize();
 	procps_status_t* sp = xzalloc(sizeof(procps_status_t));
-	sp->dir = xopendir("/proc");
+	unsigned n = bb_getpagesize();
 	while (1) {
 		n >>= 1;
 		if (!n) break;
 		sp->shift_pages_to_bytes++;
 	}
 	sp->shift_pages_to_kb = sp->shift_pages_to_bytes - 10;
+	sp->dir = xopendir("/proc");
 	return sp;
 }
 
diff --git a/miscutils/devmem.c b/miscutils/devmem.c
index e8dce5225..f9f0276bc 100644
--- a/miscutils/devmem.c
+++ b/miscutils/devmem.c
@@ -75,7 +75,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
 		bb_show_usage(); /* one of bb_strtouXX failed */
 
 	fd = xopen("/dev/mem", argv[3] ? (O_RDWR | O_SYNC) : (O_RDONLY | O_SYNC));
-	mapped_size = page_size = getpagesize();
+	mapped_size = page_size = bb_getpagesize();
 	offset_in_page = (unsigned)target & (page_size - 1);
 	if (offset_in_page + width > page_size) {
 		/* This access spans pages.
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c
index 898d77376..f8ff9b62b 100644
--- a/miscutils/hexedit.c
+++ b/miscutils/hexedit.c
@@ -31,7 +31,8 @@ struct globals {
 	int fd;
 	unsigned height;
 	unsigned row;
-	unsigned pagesize;
+	IF_VARIABLE_ARCH_PAGESIZE(unsigned pagesize;)
+#define G_pagesize cached_pagesize(G.pagesize)
 	uint8_t *baseaddr;
 	uint8_t *current_byte;
 	uint8_t *eof_byte;
@@ -46,15 +47,6 @@ struct globals {
 	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
 } while (0)
 
-//TODO: move to libbb
-#if defined(__x86_64__) || defined(i386)
-# define G_pagesize 4096
-# define INIT_PAGESIZE() ((void)0)
-#else
-# define G_pagesize (G.pagesize)
-# define INIT_PAGESIZE() ((void)(G.pagesize = getpagesize()))
-#endif
-
 /* hopefully there aren't arches with PAGE_SIZE > 64k */
 #define G_mapsize  (64*1024)
 
@@ -262,7 +254,7 @@ int hexedit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int hexedit_main(int argc UNUSED_PARAM, char **argv)
 {
 	INIT_G();
-	INIT_PAGESIZE();
+	INIT_PAGESIZE(G.pagesize);
 
 	get_terminal_width_height(-1, NULL, &G.height);
 	if (1) {
diff --git a/miscutils/time.c b/miscutils/time.c
index d15d363f3..0006c59d8 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -111,6 +111,10 @@ static void printargv(char *const *argv)
    This is funky since the pagesize could be less than 1K.
    Note: Some machines express getrusage statistics in terms of K,
    others in terms of pages.  */
+#ifdef BB_ARCH_FIXED_PAGESIZE
+# define pagesize BB_ARCH_FIXED_PAGESIZE
+# define ptok(pagesize, pages) ptok(pages)
+#endif
 static unsigned long ptok(const unsigned pagesize, const unsigned long pages)
 {
 	unsigned long tmp;
@@ -124,6 +128,7 @@ static unsigned long ptok(const unsigned pagesize, const unsigned long pages)
 	tmp = pages * pagesize; /* Larger first, */
 	return tmp / 1024;      /* then smaller.  */
 }
+#undef pagesize
 
 /* summarize: Report on the system use of a command.
 
@@ -177,7 +182,7 @@ static void summarize(const char *fmt, char **command, resource_t *resp)
 {
 	unsigned vv_ms;     /* Elapsed virtual (CPU) milliseconds */
 	unsigned cpu_ticks; /* Same, in "CPU ticks" */
-	unsigned pagesize = getpagesize();
+	unsigned pagesize = bb_getpagesize();
 
 	/* Impossible: we do not use WUNTRACED flag in wait()...
 	if (WIFSTOPPED(resp->waitstatus))
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c
index 9e51a1dcc..8fe5d0293 100644
--- a/util-linux/mkswap.c
+++ b/util-linux/mkswap.c
@@ -128,7 +128,7 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv)
 
 	/* Figure out how big the device is */
 	len = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ 1);
-	pagesize = getpagesize();
+	pagesize = bb_getpagesize();
 	len -= pagesize;
 
 	/* Announce our intentions */


More information about the busybox-cvs mailing list