@@ -105,19 +105,96 @@ static U32 use_pause = 0;
105
105
#define MAX (a ,b ) ( (a) > (b) ? (a) : (b) )
106
106
107
107
typedef struct {
108
- int nbAllocs ;
108
+ uintptr_t ptr ;
109
+ size_t size ;
110
+ } Test_alloc_alloc ;
111
+
112
+ typedef struct {
113
+ Test_alloc_alloc * allocs ;
114
+ size_t allocs_capacity ;
115
+
116
+ size_t live_alloc_count ;
117
+ size_t live_alloc_total_space ;
109
118
} Test_alloc_state ;
110
- static Test_alloc_state g_testAllocState = { 0 };
119
+
120
+ static Test_alloc_state g_testAllocState ;
121
+
122
+ static void alloc_state_init (Test_alloc_state * state ) {
123
+ state -> allocs = NULL ;
124
+ state -> allocs_capacity = 0 ;
125
+
126
+ state -> live_alloc_count = 0 ;
127
+ state -> live_alloc_total_space = 0 ;
128
+ }
129
+
130
+ static void alloc_state_destroy (Test_alloc_state * state ) {
131
+ free (state -> allocs );
132
+ alloc_state_init (state );
133
+ }
134
+
135
+ static void alloc_state_record_alloc (Test_alloc_state * state , uintptr_t ptr , size_t size ) {
136
+ size_t i ;
137
+ Test_alloc_alloc * alloc = NULL ;
138
+ if (ptr == (uintptr_t )NULL ) {
139
+ assert (size == 0 );
140
+ return ;
141
+ }
142
+ for (i = 0 ; i < state -> allocs_capacity ; i ++ ) {
143
+ if (state -> allocs [i ].ptr == (uintptr_t )NULL ) {
144
+ alloc = & state -> allocs [i ];
145
+ break ;
146
+ }
147
+ }
148
+ if (alloc == NULL ) {
149
+ const size_t old_capacity = state -> allocs_capacity ;
150
+ const size_t new_capacity = (old_capacity + !old_capacity ) * 2 ;
151
+ Test_alloc_alloc * new_allocs = (Test_alloc_alloc * )realloc (
152
+ state -> allocs , new_capacity * sizeof (state -> allocs [0 ]));
153
+ assert (state -> live_alloc_count == old_capacity );
154
+ assert (new_allocs != NULL );
155
+ memset (& new_allocs [old_capacity ], 0 , (new_capacity - old_capacity ) * sizeof (state -> allocs [0 ]));
156
+ state -> allocs = new_allocs ;
157
+ state -> allocs_capacity = new_capacity ;
158
+ alloc = & state -> allocs [old_capacity ];
159
+ }
160
+ assert (alloc != NULL );
161
+ assert (alloc -> ptr == (uintptr_t )NULL );
162
+ alloc -> ptr = ptr ;
163
+ alloc -> size = size ;
164
+ state -> live_alloc_count ++ ;
165
+ state -> live_alloc_total_space += size ;
166
+ }
167
+
168
+ static void alloc_state_record_free (Test_alloc_state * state , uintptr_t ptr ) {
169
+ size_t i ;
170
+ if (ptr == (uintptr_t )NULL ) {
171
+ return ;
172
+ }
173
+ for (i = 0 ; i < state -> allocs_capacity ; i ++ ) {
174
+ Test_alloc_alloc * alloc = & state -> allocs [i ];
175
+ if (alloc -> ptr == ptr ) {
176
+ const size_t size = alloc -> size ;
177
+ assert (state -> live_alloc_count >= 1 );
178
+ assert (state -> live_alloc_total_space >= size );
179
+ state -> live_alloc_count -- ;
180
+ state -> live_alloc_total_space -= size ;
181
+ alloc -> ptr = (uintptr_t )NULL ;
182
+ alloc -> size = 0 ;
183
+ return ;
184
+ }
185
+ }
186
+ assert (0 ); /* didn't find matching entry */
187
+ }
111
188
112
189
static void * dummy_malloc (void * state , size_t s )
113
190
{
114
191
Test_alloc_state * const t = (Test_alloc_state * )state ;
115
192
void * const p = malloc (s );
116
193
if (p == NULL ) return NULL ;
117
194
assert (t != NULL );
118
- t -> nbAllocs += 1 ;
119
- DISPLAYLEVEL (6 , "Allocating %u bytes at address %p \n" , (unsigned )s , p );
120
- DISPLAYLEVEL (5 , "nb allocated memory segments : %i \n" , t -> nbAllocs );
195
+ alloc_state_record_alloc ( t , ( uintptr_t ) p , s ) ;
196
+ DISPLAYLEVEL (6 , "Allocating %llu bytes at address %p \n" , (long long unsigned )s , p );
197
+ DISPLAYLEVEL (5 , "nb allocated memory segments : %llu \n" , ( long long unsigned ) t -> live_alloc_count );
121
198
return p ;
122
199
}
123
200
@@ -127,9 +204,9 @@ static void* dummy_calloc(void* state, size_t s)
127
204
void * const p = calloc (1 , s );
128
205
if (p == NULL ) return NULL ;
129
206
assert (t != NULL );
130
- t -> nbAllocs += 1 ;
131
- DISPLAYLEVEL (6 , "Allocating and zeroing %u bytes at address %p \n" , (unsigned )s , p );
132
- DISPLAYLEVEL (5 , "nb allocated memory segments : %i \n" , t -> nbAllocs );
207
+ alloc_state_record_alloc ( t , ( uintptr_t ) p , s ) ;
208
+ DISPLAYLEVEL (6 , "Allocating and zeroing %llu bytes at address %p \n" , (long long unsigned )s , p );
209
+ DISPLAYLEVEL (5 , "nb allocated memory segments : %llu \n" , ( long long unsigned ) t -> live_alloc_count );
133
210
return p ;
134
211
}
135
212
@@ -141,11 +218,10 @@ static void dummy_free(void* state, void* p)
141
218
return ;
142
219
}
143
220
DISPLAYLEVEL (6 , "freeing memory at address %p \n" , p );
144
- free (p );
145
221
assert (t != NULL );
146
- t -> nbAllocs -= 1 ;
147
- DISPLAYLEVEL ( 5 , "nb of allocated memory segments after this free : %i \n" , t -> nbAllocs );
148
- assert ( t -> nbAllocs >= 0 );
222
+ alloc_state_record_free ( t , ( uintptr_t ) p ) ;
223
+ free ( p );
224
+ DISPLAYLEVEL ( 5 , "nb of allocated memory segments after this free : %llu \n" , ( long long unsigned ) t -> live_alloc_count );
149
225
}
150
226
151
227
static const LZ4F_CustomMem lz4f_cmem_test = {
@@ -293,6 +369,7 @@ static int unitTests(U32 seed, double compressibility)
293
369
int basicTests_error = 0 ;
294
370
LZ4F_preferences_t prefs ;
295
371
memset (& prefs , 0 , sizeof (prefs ));
372
+ alloc_state_init ((Test_alloc_state * )lz4f_cmem_test .opaqueState );
296
373
297
374
if (!CNBuffer || !compressedBuffer || !decodedBuffer ) {
298
375
DISPLAY ("allocation error, not enough memory to start fuzzer tests \n" );
@@ -624,6 +701,7 @@ static int unitTests(U32 seed, double compressibility)
624
701
/* dictID tests */
625
702
{ size_t cErr ;
626
703
U32 const dictID = 0x99 ;
704
+
627
705
/* test advanced variant with custom allocator functions */
628
706
cctx = LZ4F_createCompressionContext_advanced (lz4f_cmem_test , LZ4F_VERSION );
629
707
if (cctx == NULL ) goto _output_error ;
@@ -956,13 +1034,73 @@ static int unitTests(U32 seed, double compressibility)
956
1034
DISPLAYLEVEL (3 , "Skipped %i bytes \n" , (int )(ip - (BYTE * )compressedBuffer - 8 ));
957
1035
}
958
1036
1037
+ DISPLAYLEVEL (3 , "Context size test: " );
1038
+ {
1039
+ size_t c_result ;
1040
+ size_t d_result ;
1041
+ LZ4F_cctx * cc ;
1042
+ LZ4F_dctx * dc ;
1043
+ Test_alloc_state c_allocs ;
1044
+ Test_alloc_state d_allocs ;
1045
+ LZ4F_CustomMem c_mem = lz4f_cmem_test ;
1046
+ LZ4F_CustomMem d_mem = lz4f_cmem_test ;
1047
+
1048
+ alloc_state_init (& c_allocs );
1049
+ alloc_state_init (& d_allocs );
1050
+ c_mem .opaqueState = & c_allocs ;
1051
+ d_mem .opaqueState = & d_allocs ;
1052
+
1053
+ if (c_allocs .live_alloc_total_space != 0 ) goto _output_error ;
1054
+ if (d_allocs .live_alloc_total_space != 0 ) goto _output_error ;
1055
+
1056
+ if (LZ4F_cctx_size (NULL ) != 0 ) goto _output_error ;
1057
+ if (LZ4F_dctx_size (NULL ) != 0 ) goto _output_error ;
1058
+
1059
+ cc = LZ4F_createCompressionContext_advanced (c_mem , LZ4F_VERSION );
1060
+ dc = LZ4F_createDecompressionContext_advanced (d_mem , LZ4F_VERSION );
1061
+
1062
+ if (cc == NULL ) goto _output_error ;
1063
+ if (dc == NULL ) goto _output_error ;
1064
+
1065
+ if (LZ4F_cctx_size (cc ) != c_allocs .live_alloc_total_space ) goto _output_error ;
1066
+ if (LZ4F_dctx_size (dc ) != d_allocs .live_alloc_total_space ) goto _output_error ;
1067
+
1068
+ c_result = LZ4F_compressFrame_usingCDict (
1069
+ cc ,
1070
+ compressedBuffer , LZ4F_compressFrameBound (testSize , NULL ),
1071
+ CNBuffer , testSize ,
1072
+ NULL , NULL );
1073
+ CHECK (c_result );
1074
+
1075
+ d_result = testSize + 1 ;
1076
+ CHECK (LZ4F_decompress (dc , decodedBuffer , & d_result , compressedBuffer , & c_result , NULL ));
1077
+
1078
+ if (d_result != testSize ) goto _output_error ;
1079
+
1080
+ if (LZ4F_cctx_size (cc ) != c_allocs .live_alloc_total_space ) {
1081
+ DISPLAYLEVEL (3 , "%lu allocated in cctx but it says its size is %lu.\n" , c_allocs .live_alloc_total_space , LZ4F_cctx_size (cc ));
1082
+ goto _output_error ;
1083
+ }
1084
+ if (LZ4F_dctx_size (dc ) != d_allocs .live_alloc_total_space ) {
1085
+ DISPLAYLEVEL (3 , "%lu allocated in dctx but it says its size is %lu.\n" , d_allocs .live_alloc_total_space , LZ4F_dctx_size (dc ));
1086
+ goto _output_error ;
1087
+ }
1088
+
1089
+ LZ4F_freeCompressionContext (cc );
1090
+ LZ4F_freeDecompressionContext (dc );
1091
+ alloc_state_destroy (& c_allocs );
1092
+ alloc_state_destroy (& d_allocs );
1093
+ }
1094
+ DISPLAYLEVEL (3 , "OK \n" );
1095
+
959
1096
DISPLAY ("Basic tests completed \n" );
960
1097
_end :
961
1098
free (CNBuffer );
962
1099
free (compressedBuffer );
963
1100
free (decodedBuffer );
964
1101
LZ4F_freeDecompressionContext (dCtx ); dCtx = NULL ;
965
1102
LZ4F_freeCompressionContext (cctx ); cctx = NULL ;
1103
+ alloc_state_destroy ((Test_alloc_state * )lz4f_cmem_test .opaqueState );
966
1104
return basicTests_error ;
967
1105
968
1106
_output_error :
0 commit comments