first proposal for LZ4_USER_MEMORY_FUNCTIONS
authorYann Collet <cyan@fb.com>
Mon, 9 Nov 2020 05:17:32 +0000 (21:17 -0800)
committerYann Collet <cyan@fb.com>
Mon, 9 Nov 2020 05:17:32 +0000 (21:17 -0800)
makes it possible to replace at link time
malloc, calloc and free
by user-provided functions
which must be named LZ4_malloc(), LZ4_calloc() and LZ4_free().

answer #937

.travis.yml
lib/README.md
lib/lz4.c
lib/lz4hc.c
tests/Makefile
tests/fullbench.c

index 2281394df42c040d3e7c48f01275b246f23dff86..de9dce883fb71191b63af34fa097b536b494d276 100644 (file)
@@ -31,11 +31,13 @@ matrix:
       script:
         - CC=clang MOREFLAGS=-fsanitize=address make -C tests test-frametest test-fuzzer
 
-    - name: Custom LZ4_DISTANCE_MAX ; Build lz4-wlib (CLI linked to dynamic library)
+    - name: Custom LZ4_DISTANCE_MAX ; lz4-wlib (CLI linked to dynamic library); LZ4_USER_MEMORY_FUNCTIONS
       script:
         - MOREFLAGS=-DLZ4_DISTANCE_MAX=8000 make check
         - make clean
         - make -C programs lz4-wlib
+        - make clean
+        - make fullbench-wmalloc  # test LZ4_USER_MEMORY_FUNCTIONS
 
     - name: (Precise) g++ and clang CMake test
       dist: precise
index 318106dd7bc4b6f6c98cbadcecf689a67c235205..e2af868ff4ad354cf8f60faea3216579eb54e940 100644 (file)
@@ -69,6 +69,10 @@ The following build macro can be selected to adjust source code behavior at comp
   This build macro offers another project-specific method
   by defining `LZ4_DISABLE_DEPRECATE_WARNINGS` before including the LZ4 header files.
 
+- `LZ4_USER_MEMORY_FUNCTIONS` : replace calls to <stdlib>'s `malloc`, `calloc` and `free`
+  by user-defined functions, which must be called `LZ4_malloc()`, `LZ4_calloc()` and `LZ4_free()`.
+  User functions must be available at link time.
+
 - `LZ4_FORCE_SW_BITCOUNT` : by default, the compression algorithm tries to determine lengths
   by using bitcount instructions, generally implemented as fast single instructions in many cpus.
   In case the target cpus doesn't support it, or compiler intrinsic doesn't work, or feature bad performance,
index 427673eb4ec5513f88ab6a43442d8edaed75072b..a8cc420b09582cb0b0bc98fa72a6924065c0f168 100644 (file)
--- a/lib/lz4.c
+++ b/lib/lz4.c
 /*-************************************
 *  Memory routines
 **************************************/
-#include <stdlib.h>   /* malloc, calloc, free */
-#define ALLOC(s)          malloc(s)
-#define ALLOC_AND_ZERO(s) calloc(1,s)
-#define FREEMEM(p)        free(p)
+#ifdef LZ4_USER_MEMORY_FUNCTIONS
+/* memory management functions can be customized by user project.
+ * Below functions must exist somewhere in the Project
+ * and be available at link time */
+void* LZ4_malloc(size_t s);
+void* LZ4_calloc(size_t s);
+void  LZ4_free(void* p);
+# define ALLOC(s)          LZ4_malloc(s)
+# define ALLOC_AND_ZERO(s) LZ4_calloc(s)
+# define FREEMEM(p)        LZ4_free(p)
+#else
+# include <stdlib.h>   /* malloc, calloc, free */
+# define ALLOC(s)          malloc(s)
+# define ALLOC_AND_ZERO(s) calloc(1,s)
+# define FREEMEM(p)        free(p)
+#endif
+
 #include <string.h>   /* memset, memcpy */
 #define MEM_INIT(p,v,s)   memset((p),(v),(s))
 
index 8875f1af8c1110adb1a9ff62b7e618890a2cfc0a..8320f334573aa73fbbf77491ce736bdae5b5f1af 100644 (file)
@@ -93,7 +93,7 @@ static U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(LZ4_read32(ptr)
 **************************************/
 static void LZ4HC_clearTables (LZ4HC_CCtx_internal* hc4)
 {
-    MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
+    MEM_INIT(hc4->hashTable, 0, sizeof(hc4->hashTable));
     MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
 }
 
@@ -983,11 +983,10 @@ int LZ4_compress_HC_destSize(void* state, const char* source, char* dest, int* s
 /* allocation */
 LZ4_streamHC_t* LZ4_createStreamHC(void)
 {
-    LZ4_streamHC_t* const state = (LZ4_streamHC_t*)ALLOC(sizeof(LZ4_streamHC_t));
-    if (LZ4_initStreamHC(state, sizeof(*state)) == NULL) {
-        free(state);
-        return NULL;
-    }
+    LZ4_streamHC_t* const state =
+        (LZ4_streamHC_t*)ALLOC_AND_ZERO(sizeof(LZ4_streamHC_t));
+    if (state == NULL) return NULL;
+    LZ4_setCompressionLevel(state, LZ4HC_CLEVEL_DEFAULT);
     return state;
 }
 
@@ -1323,7 +1322,7 @@ static int LZ4HC_compress_optimal ( LZ4HC_CCtx_internal* ctx,
     int retval = 0;
 #define TRAILING_LITERALS 3
 #ifdef LZ4HC_HEAPMODE
-    LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)malloc(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS));
+    LZ4HC_optimal_t* const opt = (LZ4HC_optimal_t*)ALLOC(sizeof(LZ4HC_optimal_t) * (LZ4_OPT_NUM + TRAILING_LITERALS));
 #else
     LZ4HC_optimal_t opt[LZ4_OPT_NUM + TRAILING_LITERALS];   /* ~64 KB, which is a bit large for stack... */
 #endif
@@ -1606,7 +1605,7 @@ if (limit == fillOutput) {
 }
 _return_label:
 #ifdef LZ4HC_HEAPMODE
-     free(opt);
+     FREEMEM(opt);
 #endif
      return retval;
 }
index 43c96516a8a34160b02a6712dce6bd5946ba0174..476849e61b955cf5786756bea35d2de3f389379c 100644 (file)
@@ -53,6 +53,7 @@ TEST_FILES   := COPYING
 FUZZER_TIME  := -T90s
 NB_LOOPS     ?= -i1
 
+.PHONY: default
 default: all
 
 all: fullbench fuzzer frametest roundTripTest datagen checkFrame decompress-partial
@@ -89,6 +90,10 @@ fullbench-dll: fullbench.c $(LZ4DIR)/xxhash.c
        $(MAKE) -C $(LZ4DIR) liblz4
        $(CC) $(FLAGS) $^ -o $@$(EXT) -DLZ4_DLL_IMPORT=1 $(LZ4DIR)/dll/$(LIBLZ4).dll
 
+# test LZ4_USER_MEMORY_FUNCTIONS
+fullbench-wmalloc: CPPFLAGS += -DLZ4_USER_MEMORY_FUNCTIONS
+fullbench-wmalloc: fullbench
+
 fuzzer  : lz4.o lz4hc.o xxhash.o fuzzer.c
        $(CC) $(FLAGS) $^ -o $@$(EXT)
 
@@ -107,6 +112,7 @@ checkFrame : lz4frame.o lz4.o lz4hc.o xxhash.o checkFrame.c
 decompress-partial: lz4.o decompress-partial.c
        $(CC) $(FLAGS) $^ -o $@$(EXT)
 
+.PHONY: clean
 clean:
        @$(MAKE) -C $(LZ4DIR) $@ > $(VOID)
        @$(MAKE) -C $(PRGDIR) $@ > $(VOID)
@@ -170,9 +176,6 @@ test32: test
 
 test-amalgamation: lz4_all.o
 
-lz4_all.o: lz4_all.c
-       $(CC) $(CFLAGS) $(CPPFLAGS) -c $^ -o $@
-
 lz4_all.c: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c $(LZ4DIR)/lz4frame.c
        $(CAT) $^ > $@
 
index 77f475ba6d9f5ac30d93f210a2258115e9ca6c61..0e3c009335241b60919ed3ea60b37d0319d6f2b5 100644 (file)
@@ -155,6 +155,14 @@ static size_t BMK_findMaxMem(U64 requiredMem)
 }
 
 
+/*********************************************************
+*  Memory management, to test LZ4_USER_MEMORY_FUNCTIONS
+*********************************************************/
+void* LZ4_malloc(size_t s) { return malloc(s); }
+void* LZ4_calloc(size_t s) { return calloc(1,s); }
+void  LZ4_free(void* p) { return free(p); }
+
+
 /*********************************************************
 *  Benchmark function
 *********************************************************/