libbb: add and use infrastructure for fixed page size optimization
No binary (build failed)
—
(log yok)
| @@ -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]); | |
| @@ -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; | |
| @@ -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; | |
| } | |
| @@ -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. | |
| @@ -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) { | |
| @@ -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)) | |
| @@ -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 */ | |