diff --git a/adaptive_compress.c b/adaptive_compress.c index 4f99be4..27ef558 100644 --- a/adaptive_compress.c +++ b/adaptive_compress.c @@ -82,6 +82,10 @@ extern int lz4_init(void **data, int *level, int nthreads, uint64_t chunksize, int file_version, compress_op_t op); extern int lz4_deinit(void **data); +extern int ppmd_alloc(void *data); +extern void ppmd_free(void *data); +extern int ppmd_state_init(void **data, int *level, int alloc); + struct adapt_data { void *lzma_data; void *ppmd_data; @@ -129,7 +133,7 @@ adapt_init(void **data, int *level, int nthreads, uint64_t chunksize, if (!adat) { adat = (struct adapt_data *)slab_alloc(NULL, sizeof (struct adapt_data)); adat->adapt_mode = 1; - rv = ppmd_init(&(adat->ppmd_data), level, nthreads, chunksize, file_version, op); + rv = ppmd_state_init(&(adat->ppmd_data), level, 0); /* * LZ4 is used to tackle some embedded archive headers and/or zero paddings in @@ -165,7 +169,7 @@ adapt2_init(void **data, int *level, int nthreads, uint64_t chunksize, adat->bsc_data = NULL; lv = *level; if (lv > 10) lv = 10; - rv = ppmd_init(&(adat->ppmd_data), &lv, nthreads, chunksize, file_version, op); + rv = ppmd_state_init(&(adat->ppmd_data), level, 0); lv = *level; if (rv == 0) rv = lzma_init(&(adat->lzma_data), &lv, nthreads, chunksize, file_version, op); @@ -305,7 +309,11 @@ adapt_compress(void *src, uint64_t srclen, void *dst, bsc_count++; } else { #endif + rv = ppmd_alloc(adat->ppmd_data); + if (rv < 0) + return (rv); rv = ppmd_compress(src, srclen, dst, dstlen, level, chdr, btype, adat->ppmd_data); + ppmd_free(adat->ppmd_data); if (rv < 0) return (rv); rv = ADAPT_COMPRESS_PPMD; diff --git a/allocator.c b/allocator.c index b281a37..2879930 100644 --- a/allocator.c +++ b/allocator.c @@ -444,8 +444,8 @@ slab_alloc(void *p, uint64_t size) } } -void -slab_free(void *p, void *address) +static void +slab_free_real(void *p, void *address, int do_free) { struct bufentry *buf, *pbuf; int found = 0; @@ -471,7 +471,7 @@ slab_free(void *p, void *address) pthread_mutex_unlock(&hbucket_locks[hindx]); ATOMIC_SUB(hash_entries, 1); - if (buf->slab == NULL) { + if (buf->slab == NULL || do_free) { free(buf->ptr); free(buf); found = 1; @@ -497,6 +497,18 @@ slab_free(void *p, void *address) } } +void +slab_free(void *p, void *address) +{ + slab_free_real(p, address, 0); +} + +void +slab_release(void *p, void *address) +{ + slab_free_real(p, address, 1); +} + #else void slab_init() {} @@ -522,6 +534,12 @@ slab_free(void *p, void *address) free(address); } +void +slab_release(void *p, void *address) +{ + free(address); +} + int slab_cache_add(uint64_t size) { diff --git a/allocator.h b/allocator.h index 9c54c1e..e23b09d 100644 --- a/allocator.h +++ b/allocator.h @@ -34,6 +34,7 @@ void slab_cleanup(int quiet); void *slab_alloc(void *p, uint64_t size); void *slab_calloc(void *p, uint64_t items, uint64_t size); void slab_free(void *p, void *address); +void slab_release(void *p, void *address); int slab_cache_add(uint64_t size); #endif diff --git a/lzma/Ppmd8.c b/lzma/Ppmd8.c index 7087196..bb55bf2 100755 --- a/lzma/Ppmd8.c +++ b/lzma/Ppmd8.c @@ -1,28 +1,28 @@ -/* - * This file is a part of Pcompress, a chunked parallel multi- - * algorithm lossless compression and decompression program. - * - * Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved. - * Use is subject to license terms. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program. - * If not, see . - * - * moinakg@belenix.org, http://moinakg.wordpress.com/ - * - */ - +/* + * This file is a part of Pcompress, a chunked parallel multi- + * algorithm lossless compression and decompression program. + * + * Copyright (C) 2012-2013 Moinak Ghosh. All rights reserved. + * Use is subject to license terms. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program. + * If not, see . + * + * moinakg@belenix.org, http://moinakg.wordpress.com/ + * + */ + /* Ppmd8.c -- PPMdI codec 2010-03-24 : Igor Pavlov : Public domain This code is based on PPMd var.I (2002): Dmitry Shkarin : Public domain */ @@ -109,9 +109,11 @@ void Ppmd8_Construct(CPpmd8 *p) void Ppmd8_Free(CPpmd8 *p, ISzAlloc *alloc) { - alloc->Free(alloc, p->Base); - p->Size = 0; - p->Base = 0; + if (p->Base != 0) { + alloc->Free(alloc, p->Base); + p->Size = 0; + p->Base = 0; + } } Bool Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAlloc *alloc) diff --git a/lzma_compress.c b/lzma_compress.c index b113eb0..c7589a2 100644 --- a/lzma_compress.c +++ b/lzma_compress.c @@ -39,7 +39,7 @@ CLzmaEncProps *p = NULL; static ISzAlloc g_Alloc = { slab_alloc, - slab_free, + slab_release, NULL }; @@ -140,7 +140,7 @@ int lzma_deinit(void **data) { if (p) { - slab_free(NULL, p); + slab_release(NULL, p); p = NULL; } *data = NULL; diff --git a/ppmd_compress.c b/ppmd_compress.c index 609af42..14aa6d5 100644 --- a/ppmd_compress.c +++ b/ppmd_compress.c @@ -58,10 +58,59 @@ static int mem_inited = 0; static ISzAlloc g_Alloc = { slab_alloc, - slab_free, + slab_release, NULL }; +int +ppmd_alloc(void *data) +{ + CPpmd8 *_ppmd = (CPpmd8 *)data; + + if (!Ppmd8_Alloc(_ppmd, ppmd8_mem_sz[_ppmd->Order], &g_Alloc)) { + log_msg(LOG_ERR, 0, "PPMD: Out of memory.\n"); + return (-1); + } + Ppmd8_Construct(_ppmd); + return (0); +} + +void +ppmd_free(void *data) +{ + CPpmd8 *_ppmd = (CPpmd8 *)data; + Ppmd8_Free(_ppmd, &g_Alloc); +} + +int +ppmd_state_init(void **data, int *level, int alloc) +{ + CPpmd8 *_ppmd; + + pthread_mutex_lock(&mem_init_lock); + if (!mem_inited) { + slab_cache_add(sizeof (CPpmd8)); + slab_cache_add(ppmd8_mem_sz[*level]); + } + pthread_mutex_unlock(&mem_init_lock); + _ppmd = (CPpmd8 *)slab_alloc(NULL, sizeof (CPpmd8)); + if (!_ppmd) + return (-1); + + /* Levels 0 - 14 correspond to PPMd model orders 0 - 14. */ + if (*level > 14) *level = 14; + _ppmd->Order = *level; + + _ppmd->Base = 0; + _ppmd->Size = 0; + *data = _ppmd; + if (*level > 9) *level = 9; + + if (alloc) + return (ppmd_alloc(*data)); + return (0); +} + void ppmd_stats(int show) { @@ -77,33 +126,7 @@ int ppmd_init(void **data, int *level, int nthreads, uint64_t chunksize, int file_version, compress_op_t op) { - CPpmd8 *_ppmd; - - pthread_mutex_lock(&mem_init_lock); - if (!mem_inited) { - slab_cache_add(sizeof (CPpmd8)); - slab_cache_add(ppmd8_mem_sz[*level]); - mem_inited = 1; - } - pthread_mutex_unlock(&mem_init_lock); - _ppmd = (CPpmd8 *)slab_alloc(NULL, sizeof (CPpmd8)); - if (!_ppmd) - return (-1); - - /* Levels 0 - 14 correspond to PPMd model orders 0 - 14. */ - if (*level > 14) *level = 14; - _ppmd->Order = *level; - - _ppmd->Base = 0; - _ppmd->Size = 0; - if (!Ppmd8_Alloc(_ppmd, ppmd8_mem_sz[*level], &g_Alloc)) { - log_msg(LOG_ERR, 0, "PPMD: Out of memory.\n"); - return (-1); - } - Ppmd8_Construct(_ppmd); - *data = _ppmd; - if (*level > 9) *level = 9; - return (0); + return (ppmd_state_init(data, level, 1)); } int @@ -111,8 +134,8 @@ ppmd_deinit(void **data) { CPpmd8 *_ppmd = (CPpmd8 *)(*data); if (_ppmd) { - Ppmd8_Free(_ppmd, &g_Alloc); - slab_free(NULL, _ppmd); + ppmd_free(*data); + slab_release(NULL, _ppmd); } *data = NULL; return (0);