From dc42add0cf96183e56b3777dde0a1d0500c0884e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 4 Dec 2010 08:39:52 +1100 Subject: [PATCH] Since 32 bit seems to fall over so easily, get ruthless with limits on it, while still maintaining a large window with sliding mmap. --- rzip.c | 20 ++++++++++---------- stream.c | 13 +++++++++---- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/rzip.c b/rzip.c index 6e22756..e3281a1 100644 --- a/rzip.c +++ b/rzip.c @@ -709,10 +709,7 @@ static void rzip_chunk(struct rzip_state *st, int fd_in, int fd_out, i64 offset, { init_sliding_mmap(st, fd_in, offset); - if (MAXRAM) - st->ss = open_stream_out(fd_out, NUM_STREAMS, st->chunk_size); - else - st->ss = open_stream_out(fd_out, NUM_STREAMS, st->mmap_size); + st->ss = open_stream_out(fd_out, NUM_STREAMS, st->chunk_size); if (unlikely(!st->ss)) fatal("Failed to open streams in rzip_chunk\n"); @@ -770,13 +767,16 @@ void rzip_fd(int fd_in, int fd_out) } else control.st_size = 0; - /* Optimal use of ram involves no more than 2/3 of it, so if we - * expressly request more with -M or -U, use a sliding mmap */ - control.max_mmap = control.ramsize / 3 * 2; - /* On 32 bits we can have a big window with sliding mmap, but can - * not enable much per mmap/malloc with 3 big buffers required*/ + /* Optimal use of ram involves no more than 2/3 of it, but 32 bit + * kernels struggle to dish out enough ram */ if (BITS32) - control.max_mmap = MIN(control.max_mmap, two_gig / 3); + control.max_mmap = control.ramsize / 6; + else + control.max_mmap = control.ramsize / 3 * 2; + /* On 32 bits we can have a big window with sliding mmap, but can + * not enable much per mmap/malloc */ + if (BITS32) + control.max_mmap = MIN(control.max_mmap, two_gig / 2); round_to_page(&control.max_mmap); /* Set maximum chunk size to proportion of ram according to mode */ diff --git a/stream.c b/stream.c index 2adbb83..de408d2 100644 --- a/stream.c +++ b/stream.c @@ -650,6 +650,7 @@ void *open_stream_out(int f, int n, i64 limit) { struct stream_info *sinfo; uchar *testmalloc; + i64 testsize; int i; sinfo = malloc(sizeof(*sinfo)); @@ -689,7 +690,7 @@ void *open_stream_out(int f, int n, i64 limit) /* Serious limits imposed on 32 bit capabilities */ if (BITS32) - limit = MIN(limit, two_gig / 3); + limit = MIN(limit, two_gig / 6); sinfo->initial_pos = lseek(f, 0, SEEK_CUR); @@ -703,13 +704,17 @@ void *open_stream_out(int f, int n, i64 limit) * ram. We need enough for the 2 streams and for the compression * backend at most, being conservative. */ retest_malloc: - testmalloc = malloc(limit * (n + 1)); + if (BITS32) + testsize = limit * n * 3; + else + testsize = limit * (n + 1); + testmalloc = malloc(testsize); if (!testmalloc) { limit = limit / 10 * 9; goto retest_malloc; } free(testmalloc); - print_maxverbose("Succeeded in testing %lld sized malloc for back end compression\n", limit * (n + 1)); + print_maxverbose("Succeeded in testing %lld sized malloc for back end compression\n", testsize); sinfo->bufsize = limit; @@ -765,7 +770,7 @@ void *open_stream_in(int f, int n) ucthread = calloc(sizeof(struct uncomp_thread), total_threads); if (unlikely(!ucthread)) - fatal("Unable to calloc cthread in open_stream_out\n"); + fatal("Unable to calloc cthread in open_stream_in\n"); for (i = 0; i < total_threads; i++) { init_sem(&ucthread[i].complete);