From a6ab7c875b0a03cbbd597067d8643ffea281aaaf Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 11 Dec 2010 00:04:30 +1100 Subject: [PATCH] Limit the number of threads decompressing stream 0 to just 1 since it's always followed by stream 1 chunks, and it may lead to failure to decompress due to running out of memory by running too many threads. --- rzip.h | 1 + stream.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rzip.h b/rzip.h index 2b4c062..03955c2 100644 --- a/rzip.h +++ b/rzip.h @@ -274,6 +274,7 @@ struct stream { long uthread_no; long unext_thread; long base_thread; + int total_threads; }; struct stream_info { diff --git a/stream.c b/stream.c index 80c12b3..b49c469 100644 --- a/stream.c +++ b/stream.c @@ -789,7 +789,7 @@ void *open_stream_in(int f, int n) if (unlikely(!sinfo)) return NULL; - total_threads = control.threads * n; + total_threads = control.threads + 1; threads = calloc(sizeof(pthread_t), total_threads); if (unlikely(!threads)) return NULL; @@ -815,11 +815,14 @@ void *open_stream_in(int f, int n) return NULL; } + sinfo->s[0].total_threads = 1; + sinfo->s[1].total_threads = control.threads; + for (i = 0; i < n; i++) { uchar c; i64 v1, v2; - sinfo->s[i].base_thread = control.threads * i; + sinfo->s[i].base_thread = i; sinfo->s[i].uthread_no = sinfo->s[i].base_thread; sinfo->s[i].unext_thread = sinfo->s[i].base_thread; @@ -1104,9 +1107,10 @@ fill_another: if (!last_head) s->eos = 1; - if (++s->uthread_no == s->base_thread + control.threads) + if (++s->uthread_no == s->base_thread + s->total_threads) s->uthread_no = s->base_thread; - if (!trywait_sem(&ucthread[s->uthread_no].free)) { + if (s->uthread_no != s->unext_thread && + !trywait_sem(&ucthread[s->uthread_no].free)) { post_sem(&ucthread[s->uthread_no].free); goto fill_another; } @@ -1119,7 +1123,7 @@ out: post_sem(&ucthread[s->unext_thread].ready); - if (++s->unext_thread == s->base_thread + control.threads) + if (++s->unext_thread == s->base_thread + s->total_threads) s->unext_thread = s->base_thread; return 0;