]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | /********************************************************************** |
2 | Copyright(c) 2011-2018 Intel Corporation All rights reserved. | |
3 | ||
4 | Redistribution and use in source and binary forms, with or without | |
5 | modification, are permitted provided that the following conditions | |
6 | are met: | |
7 | * Redistributions of source code must retain the above copyright | |
8 | notice, this list of conditions and the following disclaimer. | |
9 | * Redistributions in binary form must reproduce the above copyright | |
10 | notice, this list of conditions and the following disclaimer in | |
11 | the documentation and/or other materials provided with the | |
12 | distribution. | |
13 | * Neither the name of Intel Corporation nor the names of its | |
14 | contributors may be used to endorse or promote products derived | |
15 | from this software without specific prior written permission. | |
16 | ||
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | **********************************************************************/ | |
29 | ||
30 | #define _FILE_OFFSET_BITS 64 | |
31 | #include <stdio.h> | |
f67539c2 | 32 | #include <stdlib.h> |
9f95a23c TL |
33 | #include <assert.h> |
34 | #include <getopt.h> | |
35 | #include "huff_codes.h" | |
36 | #include "igzip_lib.h" | |
37 | #include "test.h" | |
38 | ||
39 | #include <zlib.h> | |
40 | ||
41 | #define BUF_SIZE 1024 | |
9f95a23c | 42 | |
f67539c2 | 43 | #define OPTARGS "hl:f:z:i:d:stub:y:w:o:" |
9f95a23c TL |
44 | |
45 | #define COMPRESSION_QUEUE_LIMIT 32 | |
f67539c2 TL |
46 | #define UNSET -1 |
47 | ||
48 | #define xstr(a) str(a) | |
49 | #define str(a) #a | |
50 | ||
51 | /* Limit output buffer size to 2 Gigabytes. Since stream->avail_out is a | |
52 | * uint32_t and there is no logic for handling an overflowed output buffer in | |
53 | * the perf test, this define must be less then 4 Gigabytes */ | |
54 | #define MAX_COMPRESS_BUF_SIZE (1 << 31) | |
9f95a23c TL |
55 | |
56 | int level_size_buf[10] = { | |
57 | #ifdef ISAL_DEF_LVL0_DEFAULT | |
58 | ISAL_DEF_LVL0_DEFAULT, | |
59 | #else | |
60 | 0, | |
61 | #endif | |
62 | #ifdef ISAL_DEF_LVL1_DEFAULT | |
63 | ISAL_DEF_LVL1_DEFAULT, | |
64 | #else | |
65 | 0, | |
66 | #endif | |
67 | #ifdef ISAL_DEF_LVL2_DEFAULT | |
68 | ISAL_DEF_LVL2_DEFAULT, | |
69 | #else | |
70 | 0, | |
71 | #endif | |
72 | #ifdef ISAL_DEF_LVL3_DEFAULT | |
73 | ISAL_DEF_LVL3_DEFAULT, | |
74 | #else | |
75 | 0, | |
76 | #endif | |
77 | #ifdef ISAL_DEF_LVL4_DEFAULT | |
78 | ISAL_DEF_LVL4_DEFAULT, | |
79 | #else | |
80 | 0, | |
81 | #endif | |
82 | #ifdef ISAL_DEF_LVL5_DEFAULT | |
83 | ISAL_DEF_LVL5_DEFAULT, | |
84 | #else | |
85 | 0, | |
86 | #endif | |
87 | #ifdef ISAL_DEF_LVL6_DEFAULT | |
88 | ISAL_DEF_LVL6_DEFAULT, | |
89 | #else | |
90 | 0, | |
91 | #endif | |
92 | #ifdef ISAL_DEF_LVL7_DEFAULT | |
93 | ISAL_DEF_LVL7_DEFAULT, | |
94 | #else | |
95 | 0, | |
96 | #endif | |
97 | #ifdef ISAL_DEF_LVL8_DEFAULT | |
98 | ISAL_DEF_LVL8_DEFAULT, | |
99 | #else | |
100 | 0, | |
101 | #endif | |
102 | #ifdef ISAL_DEF_LVL9_DEFAULT | |
103 | ISAL_DEF_LVL9_DEFAULT, | |
104 | #else | |
105 | 0, | |
106 | #endif | |
107 | }; | |
108 | ||
109 | enum { | |
110 | ISAL_STATELESS, | |
111 | ISAL_STATEFUL, | |
112 | ZLIB | |
113 | }; | |
114 | ||
115 | struct compress_strategy { | |
116 | int32_t mode; | |
117 | int32_t level; | |
118 | }; | |
119 | ||
120 | struct inflate_modes { | |
121 | int32_t stateless; | |
122 | int32_t stateful; | |
123 | int32_t zlib; | |
124 | }; | |
125 | ||
126 | struct perf_info { | |
127 | char *file_name; | |
128 | size_t file_size; | |
129 | size_t deflate_size; | |
9f95a23c | 130 | uint32_t inblock_size; |
f67539c2 TL |
131 | uint32_t flush_type; |
132 | int32_t hist_bits; | |
133 | int32_t deflate_time; | |
134 | int32_t inflate_time; | |
9f95a23c TL |
135 | struct compress_strategy strategy; |
136 | uint32_t inflate_mode; | |
137 | struct perf start; | |
9f95a23c TL |
138 | }; |
139 | ||
f67539c2 TL |
140 | void init_perf_info(struct perf_info *info) |
141 | { | |
142 | memset(info, 0, sizeof(*info)); | |
143 | info->deflate_time = BENCHMARK_TIME; | |
144 | info->inflate_time = BENCHMARK_TIME; | |
145 | } | |
146 | ||
9f95a23c TL |
147 | int usage(void) |
148 | { | |
149 | fprintf(stderr, | |
f67539c2 | 150 | "Usage: igzip_perf [options] <infile>\n" |
9f95a23c | 151 | " -h help, print this message\n" |
f67539c2 TL |
152 | " The options -l, -f, -z may be used up to " |
153 | xstr(COMPRESSION_QUEUE_LIMIT) " times\n" | |
154 | " -l <level> isa-l stateless deflate level to test (" | |
155 | xstr(ISAL_DEF_MIN_LEVEL) "-" xstr(ISAL_DEF_MAX_LEVEL) ")\n" | |
156 | " -f <level> isa-l stateful deflate level to test (" | |
157 | xstr(ISAL_DEF_MIN_LEVEL) "-" xstr(ISAL_DEF_MAX_LEVEL) ")\n" | |
9f95a23c | 158 | " -z <level> zlib deflate level to test\n" |
f67539c2 TL |
159 | " -d <time> approx time in seconds for deflate (at least 0)\n" |
160 | " -i <time> approx time in seconds for inflate (at least 0)\n" | |
9f95a23c TL |
161 | " -s performance test isa-l stateful inflate\n" |
162 | " -t performance test isa-l stateless inflate\n" | |
163 | " -u performance test zlib inflate\n" | |
f67539c2 TL |
164 | " -o <file> output file to store compressed data (last one if multiple)\n" |
165 | " -b <size> input buffer size, applies to stateful options (-f,-z,-s)\n" | |
166 | " -y <type> flush type: 0 (default: no flush), 1 (sync flush), 2 (full flush)\n" | |
167 | " -w <size> log base 2 size of history window, between 9 and 15\n"); | |
9f95a23c TL |
168 | exit(0); |
169 | } | |
170 | ||
171 | void print_perf_info_line(struct perf_info *info) | |
172 | { | |
f67539c2 TL |
173 | printf("igzip_perf-> compress level: %d flush_type: %d block_size: %d\n", |
174 | info->strategy.level, info->flush_type, info->inblock_size); | |
9f95a23c TL |
175 | } |
176 | ||
177 | void print_file_line(struct perf_info *info) | |
178 | { | |
179 | printf(" file info-> name: %s file_size: %lu compress_size: %lu ratio: %2.02f%%\n", | |
180 | info->file_name, info->file_size, info->deflate_size, | |
181 | 100.0 * info->deflate_size / info->file_size); | |
182 | } | |
183 | ||
184 | void print_deflate_perf_line(struct perf_info *info) | |
185 | { | |
186 | if (info->strategy.mode == ISAL_STATELESS) | |
187 | printf(" isal_stateless_deflate-> "); | |
188 | else if (info->strategy.mode == ISAL_STATEFUL) | |
189 | printf(" isal_stateful_deflate-> "); | |
190 | else if (info->strategy.mode == ZLIB) | |
191 | printf(" zlib_deflate-> "); | |
192 | ||
f67539c2 | 193 | perf_print(info->start, info->file_size); |
9f95a23c TL |
194 | } |
195 | ||
196 | void print_inflate_perf_line(struct perf_info *info) | |
197 | { | |
198 | if (info->inflate_mode == ISAL_STATELESS) | |
199 | printf(" isal_stateless_inflate-> "); | |
200 | else if (info->inflate_mode == ISAL_STATEFUL) | |
201 | printf(" isal_stateful_inflate-> "); | |
202 | else if (info->inflate_mode == ZLIB) | |
203 | printf(" zlib_inflate-> "); | |
204 | ||
f67539c2 TL |
205 | perf_print(info->start, info->file_size); |
206 | } | |
207 | ||
208 | int isal_deflate_round(struct isal_zstream *stream, uint8_t * outbuf, uint32_t outbuf_size, | |
209 | uint8_t * inbuf, uint32_t inbuf_size, | |
210 | uint32_t level, uint8_t * level_buf, uint32_t level_buf_size, | |
211 | int flush_type, int hist_bits) | |
212 | { | |
213 | int check; | |
214 | ||
215 | /* Setup stream for stateless compression */ | |
216 | isal_deflate_init(stream); | |
217 | stream->end_of_stream = 1; /* Do the entire file at once */ | |
218 | stream->flush = flush_type; | |
219 | stream->next_in = inbuf; | |
220 | stream->avail_in = inbuf_size; | |
221 | stream->next_out = outbuf; | |
222 | stream->avail_out = outbuf_size; | |
223 | stream->level = level; | |
224 | stream->level_buf = level_buf; | |
225 | stream->level_buf_size = level_buf_size; | |
226 | stream->hist_bits = hist_bits; | |
227 | ||
228 | /* Compress stream */ | |
229 | check = isal_deflate_stateless(stream); | |
230 | ||
231 | /* Verify compression success */ | |
232 | if (check || stream->avail_in) | |
233 | return 1; | |
234 | ||
235 | return 0; | |
236 | } | |
237 | ||
238 | int isal_inflate_round(struct inflate_state *state, uint8_t * inbuf, uint32_t inbuf_size, | |
239 | uint8_t * outbuf, uint32_t outbuf_size, int hist_bits) | |
240 | { | |
241 | int check = 0; | |
242 | ||
243 | /* Setup for stateless inflate */ | |
244 | state->next_in = inbuf; | |
245 | state->avail_in = inbuf_size; | |
246 | state->next_out = outbuf; | |
247 | state->avail_out = outbuf_size; | |
248 | state->crc_flag = ISAL_DEFLATE; | |
249 | state->hist_bits = hist_bits; | |
250 | ||
251 | /* Inflate data */ | |
252 | check = isal_inflate_stateless(state); | |
253 | ||
254 | /* Verify inflate was successful */ | |
255 | if (check) | |
256 | return 1; | |
257 | ||
258 | return 0; | |
259 | } | |
260 | ||
261 | int isal_deflate_stateful_round(struct isal_zstream *stream, uint8_t * outbuf, | |
262 | uint32_t outbuf_size, uint8_t * inbuf, | |
263 | uint32_t inbuf_size, uint32_t in_block_size, uint32_t level, | |
264 | uint8_t * level_buf, uint32_t level_buf_size, int flush_type, | |
265 | int hist_bits) | |
266 | { | |
267 | uint64_t inbuf_remaining; | |
268 | int check = COMP_OK; | |
269 | ||
270 | /* Setup stream for stateful compression */ | |
271 | inbuf_remaining = inbuf_size; | |
272 | isal_deflate_init(stream); | |
273 | stream->flush = flush_type; | |
274 | stream->next_in = inbuf; | |
275 | stream->next_out = outbuf; | |
276 | stream->avail_out = outbuf_size; | |
277 | stream->level = level; | |
278 | stream->level_buf = level_buf; | |
279 | stream->level_buf_size = level_buf_size; | |
280 | stream->hist_bits = hist_bits; | |
281 | ||
282 | /* Keep compressing so long as more data is available and no error has | |
283 | * been hit */ | |
284 | while (COMP_OK == check && inbuf_remaining > in_block_size) { | |
285 | /* Setup next in buffer, assumes out buffer is sufficiently | |
286 | * large */ | |
287 | stream->avail_in = in_block_size; | |
288 | inbuf_remaining -= in_block_size; | |
289 | ||
290 | /* Compress stream */ | |
291 | check = isal_deflate(stream); | |
292 | } | |
293 | ||
294 | /* Finish compressing all remaining input */ | |
295 | if (COMP_OK == check) { | |
296 | stream->avail_in = inbuf_remaining; | |
297 | stream->end_of_stream = 1; | |
298 | check = isal_deflate(stream); | |
299 | } | |
300 | ||
301 | /* Verify Compression Success */ | |
302 | if (COMP_OK != check || stream->avail_in > 0) | |
303 | return 1; | |
304 | ||
305 | return 0; | |
306 | } | |
307 | ||
308 | int isal_inflate_stateful_round(struct inflate_state *state, uint8_t * inbuf, | |
309 | uint32_t inbuf_size, uint32_t in_block_size, uint8_t * outbuf, | |
310 | uint32_t outbuf_size, int hist_bits) | |
311 | { | |
312 | int check = ISAL_DECOMP_OK; | |
313 | uint64_t inbuf_remaining; | |
314 | ||
315 | isal_inflate_init(state); | |
316 | state->next_in = inbuf; | |
317 | state->next_out = outbuf; | |
318 | state->avail_out = outbuf_size; | |
319 | state->hist_bits = hist_bits; | |
320 | inbuf_remaining = inbuf_size; | |
321 | ||
322 | while (ISAL_DECOMP_OK == check && inbuf_remaining >= in_block_size) { | |
323 | state->avail_in = in_block_size; | |
324 | inbuf_remaining -= in_block_size; | |
325 | check = isal_inflate(state); | |
326 | } | |
327 | if (ISAL_DECOMP_OK == check && inbuf_remaining > 0) { | |
328 | state->avail_in = inbuf_remaining; | |
329 | check = isal_inflate(state); | |
330 | } | |
331 | ||
332 | if (ISAL_DECOMP_OK != check || state->avail_in > 0) | |
333 | return 1; | |
334 | ||
335 | return 0; | |
336 | } | |
337 | ||
338 | int zlib_deflate_round(z_stream * gstream, uint8_t * outbuf, uInt outbuf_size, | |
339 | uint8_t * inbuf, uLong inbuf_size, | |
340 | uLong in_block_size, int level, int flush_type) | |
341 | { | |
342 | uLong inbuf_remaining; | |
343 | int check = Z_OK; | |
344 | ||
345 | inbuf_remaining = inbuf_size; | |
346 | ||
347 | /* Setup stream for stateful compression */ | |
348 | if (0 != deflateReset(gstream)) | |
349 | return 1; | |
350 | ||
351 | gstream->next_in = inbuf; | |
352 | gstream->next_out = outbuf; | |
353 | gstream->avail_out = outbuf_size; | |
354 | ||
355 | /* Keep compressing so long as more data is available and no error has | |
356 | * been hit */ | |
357 | while (Z_OK == check && inbuf_remaining > in_block_size) { | |
358 | gstream->avail_in = in_block_size; | |
359 | inbuf_remaining -= in_block_size; | |
360 | check = deflate(gstream, flush_type); | |
361 | } | |
362 | ||
363 | /* Finish compressing all remaining input */ | |
364 | if (Z_OK == check) { | |
365 | gstream->avail_in = inbuf_remaining; | |
366 | check = deflate(gstream, Z_FINISH); | |
367 | } | |
368 | ||
369 | /* Verify Compression Success */ | |
370 | if (Z_STREAM_END != check) | |
371 | return 1; | |
372 | ||
373 | return 0; | |
374 | } | |
375 | ||
376 | int zlib_inflate_round(z_stream * gstream, uint8_t * inbuf, | |
377 | uLong inbuf_size, uint8_t * outbuf, uInt outbuf_size) | |
378 | { | |
379 | int check = 0; | |
380 | ||
381 | if (0 != inflateReset(gstream)) | |
382 | return 1; | |
383 | ||
384 | gstream->next_in = inbuf; | |
385 | gstream->avail_in = inbuf_size; | |
386 | gstream->next_out = outbuf; | |
387 | gstream->avail_out = outbuf_size; | |
388 | check = inflate(gstream, Z_FINISH); | |
389 | if (check != Z_STREAM_END) | |
390 | return 1; | |
391 | ||
392 | return 0; | |
9f95a23c TL |
393 | } |
394 | ||
395 | int isal_deflate_perf(uint8_t * outbuf, uint64_t * outbuf_size, uint8_t * inbuf, | |
f67539c2 TL |
396 | uint64_t inbuf_size, int level, int flush_type, int hist_bits, int time, |
397 | struct perf *start) | |
9f95a23c TL |
398 | { |
399 | struct isal_zstream stream; | |
400 | uint8_t *level_buf = NULL; | |
f67539c2 | 401 | int check; |
9f95a23c TL |
402 | |
403 | if (level_size_buf[level] > 0) { | |
404 | level_buf = malloc(level_size_buf[level]); | |
405 | if (level_buf == NULL) | |
406 | return 1; | |
407 | } | |
408 | ||
f67539c2 TL |
409 | BENCHMARK(start, time, check = |
410 | isal_deflate_round(&stream, outbuf, *outbuf_size, inbuf, | |
411 | inbuf_size, level, level_buf, | |
412 | level_size_buf[level], flush_type, hist_bits)); | |
9f95a23c | 413 | *outbuf_size = stream.total_out; |
f67539c2 | 414 | return check; |
9f95a23c TL |
415 | } |
416 | ||
417 | int isal_deflate_stateful_perf(uint8_t * outbuf, uint64_t * outbuf_size, uint8_t * inbuf, | |
f67539c2 TL |
418 | uint64_t inbuf_size, int level, int flush_type, |
419 | uint64_t in_block_size, int hist_bits, int time, | |
420 | struct perf *start) | |
9f95a23c TL |
421 | { |
422 | struct isal_zstream stream; | |
423 | uint8_t *level_buf = NULL; | |
f67539c2 | 424 | int check; |
9f95a23c TL |
425 | |
426 | if (in_block_size == 0) | |
427 | in_block_size = inbuf_size; | |
428 | ||
429 | if (level_size_buf[level] > 0) { | |
430 | level_buf = malloc(level_size_buf[level]); | |
431 | if (level_buf == NULL) | |
432 | return 1; | |
433 | } | |
434 | ||
f67539c2 TL |
435 | BENCHMARK(start, time, check = |
436 | isal_deflate_stateful_round(&stream, outbuf, *outbuf_size, inbuf, inbuf_size, | |
437 | in_block_size, level, level_buf, | |
438 | level_size_buf[level], flush_type, hist_bits)); | |
9f95a23c | 439 | *outbuf_size = stream.total_out; |
f67539c2 | 440 | return check; |
9f95a23c TL |
441 | |
442 | } | |
443 | ||
444 | int zlib_deflate_perf(uint8_t * outbuf, uint64_t * outbuf_size, uint8_t * inbuf, | |
f67539c2 TL |
445 | uint64_t inbuf_size, int level, int flush_type, |
446 | uint64_t in_block_size, int hist_bits, int time, struct perf *start) | |
9f95a23c | 447 | { |
f67539c2 | 448 | int check; |
9f95a23c | 449 | z_stream gstream; |
f67539c2 TL |
450 | int flush_translator[] = { Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FULL_FLUSH }; |
451 | ||
452 | if (in_block_size == 0) | |
453 | in_block_size = inbuf_size; | |
9f95a23c | 454 | |
f67539c2 TL |
455 | flush_type = flush_translator[flush_type]; |
456 | ||
457 | /* Initialize the gstream buffer */ | |
9f95a23c TL |
458 | gstream.next_in = inbuf; |
459 | gstream.avail_in = inbuf_size; | |
460 | gstream.zalloc = Z_NULL; | |
461 | gstream.zfree = Z_NULL; | |
462 | gstream.opaque = Z_NULL; | |
9f95a23c | 463 | |
f67539c2 TL |
464 | if (hist_bits == 0) |
465 | hist_bits = -15; | |
466 | else | |
467 | hist_bits = -hist_bits; | |
468 | ||
469 | if (0 != deflateInit2(&gstream, level, Z_DEFLATED, hist_bits, 9, Z_DEFAULT_STRATEGY)) | |
9f95a23c TL |
470 | return 1; |
471 | ||
f67539c2 TL |
472 | BENCHMARK(start, time, check = |
473 | zlib_deflate_round(&gstream, outbuf, *outbuf_size, inbuf, inbuf_size, | |
474 | in_block_size, level, flush_type)); | |
9f95a23c | 475 | |
f67539c2 | 476 | *outbuf_size = gstream.total_out; |
9f95a23c TL |
477 | deflateEnd(&gstream); |
478 | ||
f67539c2 | 479 | return check; |
9f95a23c TL |
480 | } |
481 | ||
482 | int isal_inflate_perf(uint8_t * inbuf, uint64_t inbuf_size, uint8_t * outbuf, | |
483 | uint64_t outbuf_size, uint8_t * filebuf, uint64_t file_size, | |
f67539c2 | 484 | int hist_bits, int time, struct perf *start) |
9f95a23c TL |
485 | { |
486 | struct inflate_state state; | |
f67539c2 | 487 | int check; |
9f95a23c TL |
488 | |
489 | /* Check that data decompresses */ | |
f67539c2 | 490 | check = isal_inflate_round(&state, inbuf, inbuf_size, outbuf, outbuf_size, hist_bits); |
9f95a23c TL |
491 | if (check || state.total_out != file_size || memcmp(outbuf, filebuf, file_size)) |
492 | return 1; | |
493 | ||
f67539c2 TL |
494 | BENCHMARK(start, time, isal_inflate_round(&state, inbuf, inbuf_size, |
495 | outbuf, outbuf_size, hist_bits)); | |
9f95a23c | 496 | |
f67539c2 | 497 | return check; |
9f95a23c TL |
498 | } |
499 | ||
500 | int isal_inflate_stateful_perf(uint8_t * inbuf, uint64_t inbuf_size, uint8_t * outbuf, | |
501 | uint64_t outbuf_size, uint8_t * filebuf, uint64_t file_size, | |
f67539c2 TL |
502 | uint64_t in_block_size, int hist_bits, int time, |
503 | struct perf *start) | |
9f95a23c TL |
504 | { |
505 | struct inflate_state state; | |
f67539c2 | 506 | int check; |
9f95a23c TL |
507 | |
508 | if (in_block_size == 0) | |
509 | in_block_size = inbuf_size; | |
9f95a23c | 510 | |
f67539c2 | 511 | check = isal_inflate_round(&state, inbuf, inbuf_size, outbuf, outbuf_size, hist_bits); |
9f95a23c TL |
512 | if (check || state.total_out != file_size || memcmp(outbuf, filebuf, file_size)) |
513 | return 1; | |
514 | ||
f67539c2 TL |
515 | BENCHMARK(start, time, |
516 | isal_inflate_stateful_round(&state, inbuf, inbuf_size, in_block_size, outbuf, | |
517 | outbuf_size, hist_bits)); | |
9f95a23c TL |
518 | |
519 | return 0; | |
520 | ||
521 | } | |
522 | ||
523 | int zlib_inflate_perf(uint8_t * inbuf, uint64_t inbuf_size, uint8_t * outbuf, | |
524 | uint64_t outbuf_size, uint8_t * filebuf, uint64_t file_size, | |
f67539c2 | 525 | int hist_bits, int time, struct perf *start) |
9f95a23c | 526 | { |
f67539c2 | 527 | int check; |
9f95a23c TL |
528 | z_stream gstream; |
529 | ||
530 | gstream.next_in = inbuf; | |
531 | gstream.avail_in = inbuf_size; | |
532 | gstream.zalloc = Z_NULL; | |
533 | gstream.zfree = Z_NULL; | |
534 | gstream.opaque = Z_NULL; | |
f67539c2 TL |
535 | |
536 | if (hist_bits == 0) | |
537 | hist_bits = -15; | |
538 | else | |
539 | hist_bits = -hist_bits; | |
540 | ||
541 | if (0 != inflateInit2(&gstream, hist_bits)) | |
9f95a23c TL |
542 | return 1; |
543 | ||
f67539c2 TL |
544 | check = zlib_inflate_round(&gstream, inbuf, inbuf_size, outbuf, outbuf_size); |
545 | if (check || gstream.total_out != file_size || memcmp(outbuf, filebuf, file_size)) | |
9f95a23c TL |
546 | return 1; |
547 | ||
f67539c2 TL |
548 | BENCHMARK(start, time, |
549 | zlib_inflate_round(&gstream, inbuf, inbuf_size, outbuf, outbuf_size)); | |
9f95a23c | 550 | |
9f95a23c TL |
551 | inflateEnd(&gstream); |
552 | return 0; | |
553 | } | |
554 | ||
555 | int main(int argc, char *argv[]) | |
556 | { | |
557 | FILE *in = NULL; | |
558 | unsigned char *compressbuf, *decompbuf, *filebuf; | |
f67539c2 | 559 | char *outfile = NULL; |
9f95a23c TL |
560 | int i, c, ret = 0; |
561 | uint64_t decompbuf_size, compressbuf_size; | |
f67539c2 | 562 | uint64_t block_count; |
9f95a23c TL |
563 | |
564 | struct compress_strategy compression_queue[COMPRESSION_QUEUE_LIMIT]; | |
565 | ||
566 | int compression_queue_size = 0; | |
567 | struct compress_strategy compress_strat; | |
568 | struct inflate_modes inflate_strat = { 0 }; | |
569 | struct perf_info info; | |
f67539c2 | 570 | init_perf_info(&info); |
9f95a23c TL |
571 | |
572 | while ((c = getopt(argc, argv, OPTARGS)) != -1) { | |
573 | switch (c) { | |
574 | case 'l': | |
575 | if (compression_queue_size >= COMPRESSION_QUEUE_LIMIT) { | |
576 | printf("Too many levels specified"); | |
577 | exit(0); | |
578 | } | |
579 | ||
580 | compress_strat.mode = ISAL_STATELESS; | |
581 | compress_strat.level = atoi(optarg); | |
582 | if (compress_strat.level > ISAL_DEF_MAX_LEVEL) { | |
583 | printf("Unsupported isa-l compression level\n"); | |
584 | exit(0); | |
585 | } | |
586 | ||
587 | compression_queue[compression_queue_size] = compress_strat; | |
588 | compression_queue_size++; | |
589 | break; | |
590 | case 'f': | |
591 | if (compression_queue_size >= COMPRESSION_QUEUE_LIMIT) { | |
592 | printf("Too many levels specified"); | |
593 | exit(0); | |
594 | } | |
595 | ||
596 | compress_strat.mode = ISAL_STATEFUL; | |
597 | compress_strat.level = atoi(optarg); | |
598 | if (compress_strat.level > ISAL_DEF_MAX_LEVEL) { | |
599 | printf("Unsupported isa-l compression level\n"); | |
600 | exit(0); | |
601 | } | |
602 | ||
603 | compression_queue[compression_queue_size] = compress_strat; | |
604 | compression_queue_size++; | |
605 | break; | |
606 | case 'z': | |
607 | if (compression_queue_size >= COMPRESSION_QUEUE_LIMIT) { | |
608 | printf("Too many levels specified"); | |
609 | exit(0); | |
610 | } | |
611 | ||
612 | compress_strat.mode = ZLIB; | |
613 | compress_strat.level = atoi(optarg); | |
614 | if (compress_strat.level > Z_BEST_COMPRESSION) { | |
615 | printf("Unsupported zlib compression level\n"); | |
616 | exit(0); | |
617 | } | |
618 | compression_queue[compression_queue_size] = compress_strat; | |
619 | compression_queue_size++; | |
620 | break; | |
621 | case 'i': | |
f67539c2 TL |
622 | info.inflate_time = atoi(optarg); |
623 | if (info.inflate_time < 0) | |
9f95a23c TL |
624 | usage(); |
625 | break; | |
626 | case 'd': | |
f67539c2 TL |
627 | info.deflate_time = atoi(optarg); |
628 | if (info.deflate_time < 0) | |
9f95a23c TL |
629 | usage(); |
630 | break; | |
631 | case 's': | |
632 | inflate_strat.stateful = 1; | |
633 | break; | |
634 | case 't': | |
635 | inflate_strat.stateless = 1; | |
636 | break; | |
637 | case 'u': | |
638 | inflate_strat.zlib = 1; | |
639 | break; | |
640 | case 'b': | |
641 | inflate_strat.stateful = 1; | |
642 | info.inblock_size = atoi(optarg); | |
643 | break; | |
f67539c2 TL |
644 | case 'y': |
645 | info.flush_type = atoi(optarg); | |
646 | if (info.flush_type != NO_FLUSH && info.flush_type != SYNC_FLUSH | |
647 | && info.flush_type != FULL_FLUSH) { | |
648 | printf("Unsupported flush type\n"); | |
649 | exit(0); | |
650 | } | |
651 | break; | |
652 | ||
653 | case 'w': | |
654 | info.hist_bits = atoi(optarg); | |
655 | if (info.hist_bits > 15 || info.hist_bits < 9) | |
656 | usage(); | |
657 | break; | |
658 | case 'o': | |
659 | outfile = optarg; | |
660 | break; | |
9f95a23c TL |
661 | case 'h': |
662 | default: | |
663 | usage(); | |
664 | break; | |
665 | } | |
666 | } | |
667 | ||
668 | if (optind >= argc) | |
669 | usage(); | |
670 | ||
671 | if (!inflate_strat.stateless && !inflate_strat.stateful && !inflate_strat.zlib) { | |
672 | if (info.inblock_size == 0) | |
673 | inflate_strat.stateless = 1; | |
674 | else | |
675 | inflate_strat.stateful = 1; | |
676 | } | |
677 | ||
678 | /* Allocate space for entire input file and output | |
679 | * (assuming some possible expansion on output size) | |
680 | */ | |
681 | info.file_name = argv[optind]; | |
682 | in = fopen(info.file_name, "rb"); | |
683 | if (NULL == in) { | |
684 | printf("Error: Can not find file %s\n", info.file_name); | |
685 | exit(0); | |
686 | } | |
687 | ||
688 | info.file_size = get_filesize(in); | |
689 | if (info.file_size == 0) { | |
690 | printf("Error: input file has 0 size\n"); | |
691 | exit(0); | |
692 | } | |
693 | ||
694 | decompbuf_size = info.file_size; | |
9f95a23c TL |
695 | |
696 | if (compression_queue_size == 0) { | |
697 | if (info.inblock_size == 0) | |
698 | compression_queue[0].mode = ISAL_STATELESS; | |
699 | else | |
700 | compression_queue[0].mode = ISAL_STATEFUL; | |
701 | compression_queue[0].level = 1; | |
702 | compression_queue_size = 1; | |
703 | } | |
704 | ||
705 | filebuf = malloc(info.file_size); | |
706 | if (filebuf == NULL) { | |
707 | fprintf(stderr, "Can't allocate temp buffer memory\n"); | |
708 | exit(0); | |
709 | } | |
710 | ||
f67539c2 TL |
711 | block_count = 1; |
712 | if (info.flush_type > 0) | |
713 | block_count = (info.file_size + info.inblock_size - 1) / info.inblock_size; | |
714 | ||
715 | /* Way overestimate likely compressed size to handle bad type 0 and | |
716 | * small block_size case */ | |
717 | compressbuf_size = block_count * ISAL_DEF_MAX_HDR_SIZE + 2 * info.file_size; | |
718 | if (compressbuf_size >= MAX_COMPRESS_BUF_SIZE) | |
719 | compressbuf_size = MAX_COMPRESS_BUF_SIZE; | |
720 | ||
9f95a23c TL |
721 | compressbuf = malloc(compressbuf_size); |
722 | if (compressbuf == NULL) { | |
723 | fprintf(stderr, "Can't allocate input buffer memory\n"); | |
724 | exit(0); | |
725 | } | |
f67539c2 | 726 | |
9f95a23c TL |
727 | decompbuf = malloc(decompbuf_size); |
728 | if (decompbuf == NULL) { | |
729 | fprintf(stderr, "Can't allocate output buffer memory\n"); | |
730 | exit(0); | |
731 | } | |
732 | ||
733 | if (info.file_size != fread(filebuf, 1, info.file_size, in)) { | |
734 | fprintf(stderr, "Could not read in all input\n"); | |
735 | exit(0); | |
736 | } | |
737 | fclose(in); | |
738 | ||
739 | for (i = 0; i < compression_queue_size; i++) { | |
740 | if (i > 0) | |
741 | printf("\n\n"); | |
742 | ||
743 | info.strategy = compression_queue[i]; | |
744 | print_perf_info_line(&info); | |
745 | ||
746 | info.deflate_size = compressbuf_size; | |
747 | ||
748 | if (info.strategy.mode == ISAL_STATELESS) | |
749 | ret = isal_deflate_perf(compressbuf, &info.deflate_size, filebuf, | |
750 | info.file_size, compression_queue[i].level, | |
f67539c2 TL |
751 | info.flush_type, info.hist_bits, |
752 | info.deflate_time, &info.start); | |
9f95a23c TL |
753 | else if (info.strategy.mode == ISAL_STATEFUL) |
754 | ret = | |
755 | isal_deflate_stateful_perf(compressbuf, &info.deflate_size, | |
756 | filebuf, info.file_size, | |
757 | compression_queue[i].level, | |
f67539c2 TL |
758 | info.flush_type, info.inblock_size, |
759 | info.hist_bits, info.deflate_time, | |
760 | &info.start); | |
9f95a23c TL |
761 | else if (info.strategy.mode == ZLIB) |
762 | ret = zlib_deflate_perf(compressbuf, &info.deflate_size, filebuf, | |
763 | info.file_size, compression_queue[i].level, | |
f67539c2 TL |
764 | info.flush_type, info.inblock_size, |
765 | info.hist_bits, info.deflate_time, | |
766 | &info.start); | |
9f95a23c TL |
767 | |
768 | if (ret) { | |
769 | printf(" Error in compression\n"); | |
770 | continue; | |
771 | } | |
772 | ||
773 | print_file_line(&info); | |
774 | printf("\n"); | |
775 | print_deflate_perf_line(&info); | |
776 | printf("\n"); | |
777 | ||
f67539c2 TL |
778 | if (outfile != NULL && i + 1 == compression_queue_size) { |
779 | FILE *out; | |
780 | out = fopen(outfile, "wb"); | |
781 | fwrite(compressbuf, 1, info.deflate_size, out); | |
782 | fclose(out); | |
783 | } | |
784 | ||
785 | if (info.inflate_time == 0) | |
786 | continue; | |
787 | ||
9f95a23c TL |
788 | if (inflate_strat.stateless) { |
789 | info.inflate_mode = ISAL_STATELESS; | |
790 | ret = isal_inflate_perf(compressbuf, info.deflate_size, decompbuf, | |
791 | decompbuf_size, filebuf, info.file_size, | |
f67539c2 TL |
792 | info.hist_bits, info.inflate_time, |
793 | &info.start); | |
9f95a23c TL |
794 | if (ret) |
795 | printf(" Error in isal stateless inflate\n"); | |
796 | else | |
797 | print_inflate_perf_line(&info); | |
798 | } | |
799 | ||
800 | if (inflate_strat.stateful) { | |
801 | info.inflate_mode = ISAL_STATEFUL; | |
802 | ret = | |
803 | isal_inflate_stateful_perf(compressbuf, info.deflate_size, | |
804 | decompbuf, decompbuf_size, filebuf, | |
805 | info.file_size, info.inblock_size, | |
f67539c2 TL |
806 | info.hist_bits, info.inflate_time, |
807 | &info.start); | |
9f95a23c TL |
808 | |
809 | if (ret) | |
810 | printf(" Error in isal stateful inflate\n"); | |
811 | else | |
812 | print_inflate_perf_line(&info); | |
813 | } | |
814 | ||
815 | if (inflate_strat.zlib) { | |
816 | info.inflate_mode = ZLIB; | |
817 | ret = zlib_inflate_perf(compressbuf, info.deflate_size, decompbuf, | |
818 | decompbuf_size, filebuf, info.file_size, | |
f67539c2 TL |
819 | info.hist_bits, info.inflate_time, |
820 | &info.start); | |
9f95a23c TL |
821 | if (ret) |
822 | printf(" Error in zlib inflate\n"); | |
823 | else | |
824 | print_inflate_perf_line(&info); | |
825 | } | |
826 | } | |
827 | ||
828 | free(compressbuf); | |
829 | free(decompbuf); | |
830 | free(filebuf); | |
831 | return 0; | |
832 | } |