pax_global_header00006660000000000000000000000064146516501650014523gustar00rootroot0000000000000052 comment=6d0cfe51892ea6fe93da73326b1d987905e197c8 QATzip-1.2.1/000077500000000000000000000000001465165016500126745ustar00rootroot00000000000000QATzip-1.2.1/.github/000077500000000000000000000000001465165016500142345ustar00rootroot00000000000000QATzip-1.2.1/.github/CODEOWNERS000066400000000000000000000001341465165016500156250ustar00rootroot00000000000000* chengfei.zhu@intel.com xinghong.chen@intel.com lihui.zhang@intel.com david.qian@intel.com QATzip-1.2.1/.github/dependabot.yml000066400000000000000000000010021465165016500170550ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "monthly" QATzip-1.2.1/.gitignore000066400000000000000000000005341465165016500146660ustar00rootroot00000000000000# automake file autom4te.cache m4 src/.deps src/.libs utils/.deps test/.deps aclocal.m4 Makefile Makefile.in ar-lib compile config.guess config.log config.status config.sub configure depcomp install-sh libtool ltmain.sh missing qatzip.spec # compile obj src/*.lo src/*.o src/*.la utils/*.o test/*.o # app test/bt test/test utils/qzip utils/qzstdQATzip-1.2.1/LICENSE000066400000000000000000000033731465165016500137070ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QATzip-1.2.1/LICENSE.LZ4000066400000000000000000000024371465165016500143170ustar00rootroot00000000000000LZ4 Library Copyright (c) 2011-2020, Yann Collet All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.2.1/LICENSE.XXHASH000066400000000000000000000025551465165016500147120ustar00rootroot00000000000000xxHash Library Copyright (c) 2012-2021 Yann Collet All rights reserved. BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.2.1/LICENSE.ZLIB000066400000000000000000000017521465165016500144450ustar00rootroot00000000000000Copyright notice: (C) 1995-2022 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu QATzip-1.2.1/LICENSE.ZSTD000066400000000000000000000030151465165016500144630ustar00rootroot00000000000000BSD License For Zstandard software Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook, nor Meta, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. QATzip-1.2.1/Makefile.am000066400000000000000000000100521465165016500147260ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QZIP_DIR = $(top_builddir)/utils TEST_DIR = $(top_builddir)/test QATZIP_LIB_DIR = $(top_builddir)/src QATZIP_LIB = libqatzip.la CODE_FORMATTING_BIN = $(top_builddir)/test/code_format_tests/format.sh DIST_SUBDIRS = src utils test SUBDIRS = src utils test pkgincludedir = $(includedir) pkginclude_HEADERS = include/qatzip.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = qatzip.pc dist_man_MANS = \ man/qzip.1 EXTRA_DIST = \ LICENSE \ README.md \ include/qz_utils.h \ src/xxhash.h \ src/qatzip_internal.h \ src/qatzip_page_table.h \ utils/qzip.h \ utils/qzstd.h \ test/code_format_tests \ test/performance_tests \ docs/QATzip-man.pdf \ config_file/ $(QATZIP_LIB): @make -C $(QATZIP_LIB_DIR) $(QATZIP_LIB) qzip: $(QATZIP_LIB) @make -C $(QZIP_DIR) qzip qzip_obj_without_main: @make -C $(QZIP_DIR) qzip_obj_without_main qatzip-test:$(QATZIP_LIB) @make -C $(TEST_DIR) qatzip-test bt:$(QATZIP_LIB) @make -C $(TEST_DIR) bt qzstd: $(QATZIP_LIB) if QATZIP_LZ4S_POSTPROCESS_AC @make -C $(QZIP_DIR) qzstd else @echo "Error : please enable lz4s postprocessing in configure!" endif AM_CFLAGS=-DENABLE_TESTLOG testlog: clean @make -C $(QATZIP_LIB_DIR) $(QATZIP_LIB) AM_CFLAGS=$(AM_CFLAGS) @make -C $(QZIP_DIR) qzip @make -C $(TEST_DIR) qatzip-test @make -C $(TEST_DIR) bt if QATZIP_LZ4S_POSTPROCESS_AC @make -C $(QZIP_DIR) qzstd endif check_code: @echo -e "\n\nPerforming code formatting tests..." @if ! $(CODE_FORMATTING_BIN); then \ echo "Check code format FAILED!!! :("; \ exit 1; \ fi clean-local: @make -C $(TEST_DIR) clean ######################## # RPM package building # ######################## rpm: clean dist qatzip.spec @mkdir -p rpmbuild/BUILD rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SPECS rpmbuild/SRPMS @cp $(PACKAGE)-$(VERSION).tar.gz rpmbuild/SOURCES/ @cp qatzip.spec rpmbuild/SPECS/ @rpmbuild --define "_topdir $(abs_srcdir)/rpmbuild" -ba rpmbuild/SPECS/qatzip.spec rpmclean: @rm -fr rpmbuild .PHONY: rpm rpmclean libqatzip qzip qatzip-test check_code \ qzip_obj_without_main bt $(QATZIP_LIB) clean-local \ qzstd QATzip-1.2.1/README.md000066400000000000000000000407441465165016500141640ustar00rootroot00000000000000# Intel® QuickAssist Technology (QAT) QATzip Library ## Table of Contents - [Introduction](#introduction) - [Licensing](#licensing) - [Features](#features) - [Hardware Requirements](#hardware-requirements) - [Software Requirements](#software-requirements) - [Additional Information](#additional-information) - [Limitations](#limitations) - [Installation Instructions](#installation-instructions) - [Install with the in-tree QAT package](#install-with-the-in-tree-QAT-package) - [Install with the out-of-tree QAT package](#install-with-the-out-of-tree-QAT-package) - [Configuration](#configuration) - [Enable qzstd](#enable-qzstd) - [Test QATzip](#test-qatzip) - [Performance Test With QATzip](#performance-test-with-qatzip) - [QATzip API manual](#qatzip-api-manual) - [Intended Audience](#intended-audience) - [Open Issues](#open-issues) - [Legal](#legal) ## Introduction QATzip is a user space library which builds on top of the Intel® QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel® Chipset Series. QATzip produces data using the standard gzip\* format (RFC1952) with extended headers or [lz4\* blocks][7] with [lz4\* frame format][8]. The data can be decompressed with a compliant gzip\* or lz4\* implementation. QATzip is designed to take full advantage of the performance provided by Intel® QuickAssist Technology. The currently supported formats include: |Data Format|Algorithm|QAT device|Description| | :---------------: | :---------------: |:---------------: | :------------------------------------------------------------: | | `QZ_DEFLATE_4B` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* with a 4 byte header| | `QZ_DEFLATE_GZIP` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* wrapped by Gzip\* header and footer| | `QZ_DEFLATE_GZIP_EXT` | deflate\* | QAT 1.x and QAT 2.0|Data is in DEFLATE\* wrapped by Intel® QAT Gzip\* extension header and footer| | `QZ_DEFLATE_RAW` | deflate\* | QAT 1.x and QAT 2.0|Data is in raw DEFLATE\* without any additional header. (Only support compression, decompression will fallback to software) | | `QZ_LZ4` | lz4\* | QAT 2.0|Data is in LZ4\* wrapped by lz4\* frame | | `QZ_LZ4S` | lz4s\* | QAT 2.0|Data is in LZ4S\* blocks | ## Licensing The Licensing of the files within this project is split as follows: Intel® Quickassist Technology (QAT) QATzip - BSD License. Please see the `LICENSE` file contained in the top level folder. Further details can be found in the file headers of the relevant files. Example Intel® Quickassist Technology Driver Configuration Files contained within the folder hierarchy `config_file` - Dual BSD/GPLv2 License. Please see the file headers of the configuration files, and the full GPLv2 license contained in the file `LICENSE.GPL` within the `config_file` folder. ## Features * Acceleration of compression and decompression utilizing Intel® QuickAssist Technology, including a utility to compress and decompress files. * Dynamic memory allocation for zero copy, by exposing qzMalloc() and qzFree() allowing working buffers to be pinned, contiguous buffers that can be used for DMA operations to and from the hardware. * Instance over-subscription, allowing a number of threads in the same process to seamlessly share a smaller number of hardware instances. * Memory allocation backed by huge page and kernel memory to provide access to pinned, contiguous memory. Allocating from huge-page when kernel memory contention. * Configurable accelerator device sharing among processes. * Optional software failover for both compression and decompression services. QATzip may switch to software if there is insufficient system resources including acceleration instances or memory. This feature allows for a common software stack between server platforms that have acceleration devices and non-accelerated platforms. * Provide streaming interface of compression and decompression to achieve better compression ratio and throughput for data sets that are submitted piecemeal. * 'qzip' utility supports compression from regular file, pipeline and block device. * For QATzip GZIP\* format, try hardware decompression first before switching to software decompression. * Enable adaptive polling mechanism to save CPU usage in stress mode. * 'qzip' utility supports compression files and directories into 7z format. * Support QATzip Gzip\* format, it includes 10 bytes header and 8 bytes footer: `| ID1 (1B) | ID2(0x8B) (1B) | Compression Method (8 = DEFLATE*) (1B) | Flags (1B) | Modification Time (4B) | Extra Flags (1B) | OS (1B) | Deflate Block| CRC32(4B)| ISIZE(4B)|` * Support QATzip Gzip\* extended format. This consists of the standard 10 byte Gzip* header and follows RFC 1952 to extend the header by an additional 14 bytes. The extended headers structure is below: `| Length of ext. header (2B) | SI1('Q') (1B) | SI2('Z') (1B) | Length of subheader (2B) | Intel(R) defined field 'Chunksize' (4B) | Intel(R) defined field 'Blocksize' (4B) | ` * Support Intel® QATzip 4 byte header, the header indicates the length of the compressed block followed by the header. `| Intel(R) defined Header (4B)|deflate\* block|` * Support QATzip lz4* format. This format is structured as follows: `| MagicNb(4B) |FLG(1B)|BD(1B)| CS(8B)|HC(1B)| |lz4\* Block | EndMark(4B)|` ## Hardware Requirements This QATzip library supports compression and decompression offload to the following acceleration devices: * [Intel® C62X Series Chipset][1] * [Intel® Communications Chipset 8925 to 8955 Series][2] * [Intel® Communications Chipset 8960 to 8970 Series][3] * [Intel® C3XXX Series Chipset][4] * [Intel® 4XXX Series][5] ## Software Requirements This release was validated on the following: * QATzip has been tested with the latest Intel® QuickAssist Acceleration Driver. Please download the QAT driver from the link [Intel® QuickAssist Technology][6] * QATzip has been tested by Intel® on CentOS\* 7.8.2003 with kernel 3.10.0-1127.19.1.el7.x86\_64 * Zlib\* library of version 1.2.7 or higher * Suggest GCC\* of version 4.8.5 or higher * lz4\* library of version 1.8.3 or higher * zstd\* library of version 1.5.0 or higher ## Additional Information * For QAT 1.x, the compression level in QATzip could be mapped to standard zlib\* as below: * QATzip level 1 - 4, similar to zlib\* level 1 - 4. * QATzip level 5 - 8, we map them to QATzip level 4. * QATzip level 9, we will use software zlib\* to compress as level 9. * For QAT 2.0, the compression level in QATzip could be mapped to standard zlib\* or lz4\* as below: * Will be updated in future releases. * QATzip Compression Level Mapping: | QATzip Level |QAT Level| QAT 2.0(deflate\*, LZ4\*, LZ4s\*) |QAT1.7/1.8(Deflate\*) | | ---- | --- | ---- | ---- | | 1 | CPA_DC_L1 |2(HW_L1) | DEPTH_1 | | 2 | CPA_DC_L2 |2(HW_L1) | DEPTH_4 | | 3 | CPA_DC_L3 |2(HW_L1) | DEPTH_8 | | 4 | CPA_DC_L4 |2(HW_L1) | DEPTH_16 | | 5 | CPA_DC_L5 |2(HW_L1) | DEPTH_16 | | 6 | CPA_DC_L6 |8(HW_L6) | DEPTH_16 | | 7 | CPA_DC_L7 |8(HW_L6) | DEPTH_16 | | 8 | CPA_DC_L8 |8(HW_L6) | DEPTH_16 | | 9 | CPA_DC_L9 |16(HW_L9) | DEPTH_16 | | 10 | CPA_DC_L10 |16(HW_L9) | Unsupported | | 11 | CPA_DC_L11 |16(HW_L9) | Unsupported | | 12 | CPA_DC_L12 |16(HW_L9) | Unsupported | ## Limitations * The partitioned internal chunk size of 16 KB is disabled, this chunk is used for QAT hardware DMA. * For stream object, user should reset the stream object by calling qzEndStream() before reuse it in the other session. * For stream object, user should clear stream object by calling qzEndStream() before clear session object with qzTeardownSession(). Otherwise, memory leak happens. * For stream object, stream length must be smaller than `strm_buff_sz`, or QATzip would generate multiple deflate block in order and has the last block with BFIN set. * For stream object, we will optimize the performance of the pre-allocation process using a thread-local stream buffer list in a future release. * For 7z format, decompression only supports \*.7z archives compressed by qzip. * For 7z format, decompression only supports software. * For 7z format, the header compression is not supported. * For lz4\* (de)compression, QATzip only supports 32KB history buffer. * For zstd format compression, qzstd only supports `hw_buffer_sz` which is less than 128KB. * Stream APIs only support "DEFLATE_GZIP", "DEFLATE_GZIP_EXT", "DEFLATE_RAW" for compression and "DEFLATE_GZIP", "DEFLATE_GZIP_EXT" for decompression now. ## Installation Instructions ### Install with the in-tree QAT package * Please refer to [link][11]. ### Install with the out-of-tree QAT package 1. The Installation of the out-of-tree QAT package refer to [link][12]. > **Note**
> - If you run QAT as **non-root** user, more steps need to be manually applied, please refer to [link][13].
> - If SVM is not enabled, memory passed to QAT hardware must be DMA’able, Intel provides a USDM component > which allocates/frees DMA-able memory. Please refer to [link][14] for USDM setting. 2. Install the package dependencies by running the below command: ``` sudo dnf install -y autoconf automake libtool zlib-devel lz4-devel For Debian-based distros like Ubuntu, use these names for the latter two packages: sudo apt -y install zlib1g-dev liblz4-dev ``` 3. Configure the QATzip library by running the following commands: ``` cd QATzip/ export QZ_ROOT=`pwd` export ICP_ROOT=/QAT/PACKAGE/PATH ./autogen.sh ./configure ``` > **Note**
> For more configure options, please run "./configure -h" for help. 4. Build and install the QATzip library by running the below commands: ``` make clean make sudo make install ``` ### Configuration > **Note**
> This section is only required when you are using out-of-tree QAT package. if you are > using qatlib with in-tree QAT package, please refer to [link][16] for details on configuring qatlib. QAT programmer’s guide which provides information on the architecture of the software and usage guidelines, allows customization of runtime operation. * [Intel® QAT 1.7 linux Programmer's Guide][9] * [Intel® QAT 2.0 linux Programmer's Guide][10] The Intel® QATzip comes with some tuning example conf files to use. you can replace the old conf file(under /etc/) by them. The detailed info about Configurable options, please refer Programmer's Guide manual. The process section name(in configuration file) is the key change for QATzip. There are two way to change: * QAT Driver default conf file does not contain a [SHIM] section which the Intel® QATzip requires by default. You can follow below step to replace them. * The default section name in the QATzip can be modified if required by setting the environment variable "QAT_SECTION_NAME". To update the configuration file, copy the configure file(s) from the directory of `$QZ_ROOT/config_file/$YOUR_PLATFORM/$CONFIG_TYPE/*.conf` to the directory of `/etc` `YOUR_PLATFORM`: the QAT hardware platform, c6xx for Intel® C62X Series Chipset, dh895xcc for Intel® Communications Chipset 8925 to 8955 Series `CONFIG_TYPE`: tuned configure file(s) for different usage, `multiple_process_opt` for multiple process optimization, `multiple_thread_opt` for multiple thread optimization. **Restart QAT driver** ```bash service qat_service restart ``` With current configuration, each PCI-e device in C6XX platform could support 32 processes in maximum. ### Enable qzstd If you want to enable lz4s + postprocessing pipeline, you have to compile qzstd which is a sample app to support ZSTD format compression/decompression. Before enabling qzstd, make sure that you have installed zstd static lib. **Compile qzstd** ```bash cd $QZ_ROOT ./autogen.sh ./configure --enable-lz4s-postprocessing make clean make qzstd ``` **test qzstd** ```bash qzstd $your_input_file ``` ## Test QATzip Run the following command to check if the QATzip is setup correctly for compressing or decompressing files: ```bash qzip -k $your_input_file -O gzipext -A deflate ``` ### File compression in 7z: ```bash qzip -O 7z FILE1 FILE2 FILE3... -o result.7z ``` ### Dir compression in 7z: ```bash qzip -O 7z DIR1 DIR2 DIR3... -o result.7z ``` ### Decompression file in 7z: ```bash qzip -d result.7z ``` ### Dir Decompression with -R: If the DIR contains files that are compressed by qzip and using gzip/gzipext format, then it should be add `-R` option to decompress them: ```bash qzip -d -R DIR ``` ## Performance Test With QATzip Please run the QATzip (de)compression performance test with the following command. Please update the drive configuration and process/thread argument in run_perf_test.sh before running the performance test. Note that when number for threads changed, the argument "max_huge_pages_per_process" in run_perf_test.sh should be changed accordingly, at least 6 times of threads number. ```bash cd $QZ_ROOT/test/performance_tests ./run_perf_test.sh ``` ## QATzip API Manual Please refer to file `QATzip-man.pdf` under the `docs` folder Please refer to the [link][15] for QAT documents ## Open Issues Known issues relating to the QATzip are described in this section. ### QATAPP-26069 | Title | Buffers allocated with qzMalloc() can't be freed after calling qzMemDestory | |----------|:------------- | Reference | QATAPP-26069 | | Description | If the users call qzFree after qzMemDestory, they may encounter free memory error "free(): invalid pointe" | | Implication | User use qzMalloc API to allocate continuous memory | | Resolution | Ensure qzMemDestory is invoked after qzFree, now we use attribute destructor to invoke qzMemDestory| | Affected OS | Linux | ## Intended Audience The target audience is software developers, test and validation engineers, system integrators, end users and consumers for QATzip integrated Intel® Quick Assist Technology ## Legal Intel® disclaims all express and implied warranties, including without limitation, the implied warranties of merchantability, fitness for a particular purpose, and non-infringement, as well as any warranty arising from course of performance, course of dealing, or usage in trade. This document contains information on products, services and/or processes in development. All information provided here is subject to change without notice. Contact your Intel® representative to obtain the latest forecast , schedule, specifications and roadmaps. The products and services described may contain defects or errors known as errata which may cause deviations from published specifications. Current characterized errata are available on request. Copies of documents which have an order number and are referenced in this document may be obtained by calling 1-800-548-4725 or by visiting www.intel.com/design/literature.htm. Intel, the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries. \*Other names and brands may be claimed as the property of others [1]:https://www.intel.com/content/www/us/en/design/products-and-solutions/processors-and-chipsets/purley/intel-xeon-scalable-processors.html [2]:https://www.intel.com/content/www/us/en/ethernet-products/gigabit-server-adapters/quickassist-adapter-8950-brief.html [3]:https://www.intel.com/content/www/us/en/ethernet-products/gigabit-server-adapters/quickassist-adapter-8960-8970-brief.html [4]:https://www.intel.com/content/www/us/en/products/docs/processors/atom/c-series/c3000-family-brief.html [5]:https://www.intel.com/content/www/us/en/products/details/processors/xeon/scalable.html [6]:https://www.intel.com/content/www/us/en/developer/topic-technology/open/quick-assist-technology/overview.html [7]:https://github.com/lz4/lz4/blob/dev/doc/lz4_Block_format.md [8]:https://github.com/lz4/lz4/blob/dev/doc/lz4_Frame_format.md [9]:https://www.intel.com/content/www/us/en/content-details/710060/intel-quickassist-technology-software-for-linux-programmer-s-guide-hw-version-1-7.html [10]:https://intel.github.io/quickassist/PG/configuration_files_index.html [11]:https://intel.github.io/quickassist/qatlib/qatzip.html [12]:https://intel.github.io/quickassist/GSG/2.X/installation.html [13]:https://intel.github.io/quickassist/GSG/2.X/installation.html#running-applications-as-non-root-user [14]:https://intel.github.io/quickassist/PG/infrastructure_memory_management.html#huge-pages [15]:https://intel.github.io/quickassist [16]:https://intel.github.io/quickassist/qatlib/configuration.html# QATzip-1.2.1/SECURITY.md000066400000000000000000000003461465165016500144700ustar00rootroot00000000000000# Security Policy ## Reporting a Security Vulnerability Visit https://intel.com/security for information on how to report security vulnerabilities. Do not report any security vulnerability as a regular issue in this repository. QATzip-1.2.1/autogen.sh000077500000000000000000000034411465165016500146770ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ #!/bin/sh mkdir -p m4 autoreconf -vif QATzip-1.2.1/config_file/000077500000000000000000000000001465165016500151405ustar00rootroot00000000000000QATzip-1.2.1/config_file/4xxx/000077500000000000000000000000001465165016500160535ustar00rootroot00000000000000QATzip-1.2.1/config_file/4xxx/multiple_process_opt/000077500000000000000000000000001465165016500223265ustar00rootroot00000000000000QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev0.conf000066400000000000000000000127141465165016500250330ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev1.conf000066400000000000000000000127151465165016500250350ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev2.conf000066400000000000000000000127151465165016500250360ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev3.conf000066400000000000000000000127151465165016500250370ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev4.conf000066400000000000000000000127151465165016500250400ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev5.conf000066400000000000000000000127151465165016500250410ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev6.conf000066400000000000000000000127151465165016500250420ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_process_opt/4xxx_dev7.conf000066400000000000000000000127151465165016500250430ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 64 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/000077500000000000000000000000001465165016500221175ustar00rootroot00000000000000QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev0.conf000066400000000000000000000127141465165016500246240ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev1.conf000066400000000000000000000127141465165016500246250ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev2.conf000066400000000000000000000127141465165016500246260ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev3.conf000066400000000000000000000127141465165016500246270ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev4.conf000066400000000000000000000127141465165016500246300ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev5.conf000066400000000000000000000127141465165016500246310ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev6.conf000066400000000000000000000127141465165016500246320ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/4xxx/multiple_thread_opt/4xxx_dev7.conf000066400000000000000000000127141465165016500246330ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 8 NumProcesses = 4 LimitDevAccess = 0 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/config_file/LICENSE.BSD000066400000000000000000000033731465165016500165620ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QATzip-1.2.1/config_file/LICENSE.GPL000066400000000000000000000431031465165016500165670ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. QATzip-1.2.1/config_file/c3xxx/000077500000000000000000000000001465165016500162155ustar00rootroot00000000000000QATzip-1.2.1/config_file/c3xxx/multiple_process_opt/000077500000000000000000000000001465165016500224705ustar00rootroot00000000000000QATzip-1.2.1/config_file/c3xxx/multiple_process_opt/c3xxx_dev0.conf000066400000000000000000000114271465165016500253370ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * # Rate Limiting * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.2.1/config_file/c3xxx/multiple_thread_opt/000077500000000000000000000000001465165016500222615ustar00rootroot00000000000000QATzip-1.2.1/config_file/c3xxx/multiple_thread_opt/c3xxx_dev0.conf000066400000000000000000000122011465165016500251170ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * # Rate Limiting * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # # List of core affinities Dc1CoreAffinity = 2 # # # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # # List of core affinities Dc2CoreAffinity = 3 # # # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # # List of core affinities Dc3CoreAffinity = 4 QATzip-1.2.1/config_file/c6xx/000077500000000000000000000000001465165016500160305ustar00rootroot00000000000000QATzip-1.2.1/config_file/c6xx/multiple_process_opt/000077500000000000000000000000001465165016500223035ustar00rootroot00000000000000QATzip-1.2.1/config_file/c6xx/multiple_process_opt/c6xx_dev0.conf000066400000000000000000000103421465165016500247600ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.2.1/config_file/c6xx/multiple_process_opt/c6xx_dev1.conf000066400000000000000000000103421465165016500247610ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.2.1/config_file/c6xx/multiple_process_opt/c6xx_dev2.conf000066400000000000000000000103421465165016500247620ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.2.1/config_file/c6xx/multiple_thread_opt/000077500000000000000000000000001465165016500220745ustar00rootroot00000000000000QATzip-1.2.1/config_file/c6xx/multiple_thread_opt/c6xx_dev0.conf000066400000000000000000000111001465165016500245420ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.2.1/config_file/c6xx/multiple_thread_opt/c6xx_dev1.conf000066400000000000000000000111001465165016500245430ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.2.1/config_file/c6xx/multiple_thread_opt/c6xx_dev2.conf000066400000000000000000000111001465165016500245440ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 4 QATzip-1.2.1/config_file/dh895xcc/000077500000000000000000000000001465165016500164775ustar00rootroot00000000000000QATzip-1.2.1/config_file/dh895xcc/multiple_process_opt/000077500000000000000000000000001465165016500227525ustar00rootroot00000000000000QATzip-1.2.1/config_file/dh895xcc/multiple_process_opt/dh895xcc_dev0.conf000066400000000000000000000100511465165016500260730ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (MCA and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 32 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 QATzip-1.2.1/config_file/dh895xcc/multiple_thread_opt/000077500000000000000000000000001465165016500225435ustar00rootroot00000000000000QATzip-1.2.1/config_file/dh895xcc/multiple_thread_opt/dh895xcc_dev0.conf000066400000000000000000000106121465165016500256670ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features (MCA and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 1 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 2 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 3 QATzip-1.2.1/configure.ac000066400000000000000000000224551465165016500151720ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([qatzip], [1.2.0], []) AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability foreign subdir-objects tar-pax]) AM_SILENT_RULES([yes]) AC_USE_SYSTEM_EXTENSIONS AC_CONFIG_MACRO_DIRS([m4]) AC_SUBST([LIBQATZIP_VERSION], [3:3:0]) # Checks for programs. AC_PROG_AWK AC_PROG_CC AC_PROG_LN_S AC_PROG_MAKE_SET AM_PROG_AR AC_PATH_TOOL(PKGCONFIG, pkg-config) LT_PREREQ([2.4]) LT_INIT # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_TYPE_INT64_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T # Checks for system header files. AC_CHECK_HEADERS([stdio.h stdarg.h fcntl.h limits.h memory.h \ unistd.h stdint.h stdlib.h string.h sys/ioctl.h \ sys/time.h sys/types.h sys/stat.h unistd.h utime.h \ pthread.h]) # Checks for library functions. AC_CHECK_FUNCS([atexit getcwd gettimeofday \ memmove memset mkdir munmap \ realpath strdup strerror strrchr \ strtol strtoul utime fork malloc mmap]) # Checks for pthread. AC_CHECK_LIB([pthread], [pthread_create], , [AC_MSG_ERROR([not found pthread_create in -lpthread])]) #check for zlib. AC_CHECK_HEADER([zlib.h], , [AC_MSG_ERROR([zlib.h not found])]) AC_MSG_CHECKING(zlib version) AC_TRY_COMPILE( [#include ], [#if ZLIB_VERNUM < 0x1270 #error zlib version is too old ... #endif], [AC_MSG_RESULT([ok])], [AC_MSG_ERROR([zlib version must be 1.2.7 or higher.]) ]) AC_CHECK_LIB([z], [deflate], , AC_MSG_ERROR([deflate not found])) #check for lz4 lib AC_CHECK_HEADER([lz4.h], , [AC_MSG_ERROR([lz4.h not found])]) AC_CHECK_HEADER([lz4frame.h], , [AC_MSG_ERROR([lz4frame.h not found])]) AC_CHECK_LIB([lz4], [LZ4F_compressFrame], , AC_MSG_ERROR([LZ4F_compressFrame not found])) ##check for xxhash lib #AC_CHECK_HEADER([xxhash.h],,[AC_MSG_ERROR([not found xxhash.h])]) #AC_CHECK_LIB([xxhash], [XXH32_update], ,AC_MSG_ERROR([not found XXH32_update in -lxxhash])) AC_DEFINE(XXH_NAMESPACE, QATZIP_, "Prefix xxhash API with QATZIP_") #with ICP_ROOT AC_ARG_WITH([ICP_ROOT], AS_HELP_STRING([--with-ICP_ROOT=PATH],[Used to link Cpa library]), AS_IF( [test "$withval" = "yes"], AC_MSG_ERROR([--with-ICP_ROOT=PATH requires a PATH]), [ICP_ROOT="$withval"] ) ) #check for qat header file. ICP_INCLUDE_CFLAGS= AS_IF([test ! -z "${ICP_ROOT}"], [ #check for OOT relative header and lib AC_MSG_CHECKING([qat header files from ${ICP_ROOT}]) AS_IF([test ! -e ${ICP_ROOT}/quickassist/include/cpa.h || test ! -e ${ICP_ROOT}/quickassist/include/dc/cpa_dc.h || test ! -e ${ICP_ROOT}/quickassist/utilities/libusdm_drv/qae_mem.h || test ! -e ${ICP_ROOT}/quickassist/lookaside/access_layer/include/icp_sal_poll.h || test ! -e ${ICP_ROOT}/quickassist/lookaside/access_layer/include/icp_sal_user.h], [ AC_MSG_RESULT([no]) AC_MSG_ERROR([QAT header files not found in $ICP_ROOT, please check \$ICP_ROOT]) ], [ AC_MSG_RESULT([yes]) ICP_INCLUDE_CFLAGS=" -I${ICP_ROOT}/quickassist/include \ -I${ICP_ROOT}/quickassist/include/dc/ \ -I${ICP_ROOT}/quickassist/utilities/libusdm_drv/ \ -I${ICP_ROOT}/quickassist/lookaside/access_layer/include/ " LDFLAGS+=" -Wl,-rpath,${ICP_ROOT}/build/ -L${ICP_ROOT}/build/ " ] ) AC_SUBST(ICP_INCLUDE_CFLAGS) AC_CHECK_LIB(qat_s, cpaDcCompressData2, , [ AC_MSG_ERROR([cpaDcCompressData2 not found cpaDcCompressData2]) ] ) #check for icp_adf_get_numDevices/icp_sal_userIsQatAvailable AC_CHECK_LIB(qat_s, icp_adf_get_numDevices, [ADF_CFLAGS="-DADF_PCI_API" AC_SUBST(ADF_CFLAGS)], [ AC_CHECK_LIB(qat_s, icp_sal_userIsQatAvailable, [SAL_CFLAGS="-DSAL_DEV_API" AC_SUBST(SAL_CFLAGS)], [AC_MSG_ERROR([icp_sal_userIsQatAvailable/icp_adf_get_numDevices not found])] ) ] ) #check for usdm lib AC_CHECK_LIB(usdm_drv_s, qaeMemAllocNUMA, , [AC_MSG_ERROR([qaeMemAllocNUMA not found])]) ], [ #check for qat lib. AC_MSG_CHECKING([qat header files from sys usr]) AC_CHECK_HEADERS( [qat/cpa.h qat/cpa_dc.h qat/qae_mem.h qat/icp_sal_poll.h qat/icp_sal_user.h], [ AC_DEFINE([HAVE_QAT_HEADERS], [], [QAT header files in include/qat subdirectory]) ], [AC_MSG_ERROR([qat header files not found])], [#ifdef HAVE_QAT_CPA_H # include #endif ] ) AC_CHECK_LIB(qat, cpaDcCompressData2, , [ AC_MSG_ERROR([cpaDcCompressData2 not found])], [-lusdm -lcrypto]) #check for icp_adf_get_numDevices/icp_sal_userIsQatAvailable AC_CHECK_LIB(qat, icp_adf_get_numDevices, [ADF_CFLAGS="-DADF_PCI_API" AC_SUBST(ADF_CFLAGS)], [ AC_CHECK_LIB(qat, icp_sal_userIsQatAvailable, [SAL_CFLAGS="-DSAL_DEV_API" AC_SUBST(SAL_CFLAGS)], [AC_MSG_ERROR([icp_sal_userIsQatAvailable/icp_adf_get_numDevices not found])], [-lusdm -lcrypto] ) ] ) #check for usdm lib AC_CHECK_LIB(usdm, qaeMemAllocNUMA,, [AC_MSG_ERROR([qaeMemAllocNUMA not found])]) ]) #check for compile flags AC_MSG_CHECKING([cflags]) CFLAGS+=' -Wall -Werror -std=gnu99 -pedantic \ -fstack-protector-strong -fPIE -fPIC \ -fno-delete-null-pointer-checks -fwrapv' AS_IF([test "x${CC}" = "xgcc"], [CFLAGS+=' -fno-strict-overflow'], []) AC_MSG_RESULT([yes]) #check for compile flags AC_MSG_CHECKING([ldflags]) LDFLAGS+=' -fstack-protector-strong -fPIC -pie -z relro -z now -Wl,-z,noexecstack' AC_MSG_RESULT([yes]) #Enable debug mode AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable debug mode]), [ debug=true CFLAGS+=' -g -DQATZIP_DEBUG -O0' ] , [ debug=false CFLAGS+=' -O2' AS_IF([test "x${CC}" = "xgcc"], [CFLAGS+=' -D_FORTIFY_SOURCE=2'], []) ] ) AM_CONDITIONAL([QATZIP_DEBUG_AC], [test x$debug = xtrue]) #Enable qatzip symbol AC_ARG_ENABLE(symbol, AS_HELP_STRING([--enable-symbol], [Enable qatzip symbol]), [ symbol=true CFLAGS+=' -g' ], [ symbol=false ] ) AM_CONDITIONAL([QATZIP_SYMBOL_AC], [test x$symbol = xtrue]) #Enable qatzip pthread_barrier AC_ARG_ENABLE(pthread_barrier, AS_HELP_STRING([--enable-pthread-barrier], [Enable pthread_barrier]), [ pthread_barrier=true CFLAGS+=' -DENABLE_THREAD_BARRIER' ], [ pthread_barrier=false ] ) AM_CONDITIONAL([QATZIP_PTHREAD_BARRIER_AC], [test x$pthread_barrier = xtrue]) #Enable lz4s-postprocessing AC_ARG_ENABLE(lz4s_postprocessing, AS_HELP_STRING([--enable-lz4s-postprocessing], [Enable lz4s and zstd post processing]), [ lz4s_postprocessing=true #check for zstd lib SAVE_CFLAGS=${CFLAGS} CFLAGS= AC_CHECK_HEADER([zstd.h]) AC_CHECK_LIB([zstd], [ZSTD_compressCCtx]) CFLAGS=${SAVE_CFLAGS} ZSTD_LIBADD='-lpthread -Bstatic -lzstd' AC_SUBST(ZSTD_LIBADD) ], [ lz4s_postprocessing=false ] ) AM_CONDITIONAL([QATZIP_LZ4S_POSTPROCESS_AC], [test x$lz4s_postprocessing = xtrue]) AC_CONFIG_FILES([Makefile qatzip.spec src/Makefile test/Makefile utils/Makefile] qatzip.pc) AC_OUTPUT QATzip-1.2.1/docs/000077500000000000000000000000001465165016500136245ustar00rootroot00000000000000QATzip-1.2.1/docs/QATzip-man.pdf000066400000000000000000012566361465165016500162630ustar00rootroot00000000000000%PDF-1.7 % 2 0 obj << /Type /ObjStm /N 100 /First 827 /Length 1453 /Filter /FlateDecode >> stream x͙[SG+Ѽ\z.[rACL) ¦bPqsz+ݕVbFWٳj;}fgaV^92&JI8e R V95b5VyʧlP!bl4Y r*J9RUKDtC\"z@LV+bO 4< ;\}Rq +k18\S x +L9Bc3(sֺA=ZE J%H(p*BxU j$N{70"MtxErփ"PD3 !H.3fQ$~ȬACd6X~[89xZL]m-RJ*|o" |I>Q!嫀Qi3XQy8 i0m 7{``Vp`c n""E#ð50^N:óh=7Ic.,1ػtĦu1 bH_5F*9N/{0`>,,8|֑z=>zva44ŋ33L>7cn.y 7vJ3ޏ.Ƿfs)l;D:#I('zr=n|nvR׎J"lS.6_Gs(.׍?WKc؍>uͤYҴ_rsP<}E2|"2syvfmwWs+w RSzs" 㘛SyurSsj.7IZp"DI鶥폦t(Juݧ~|$9첾nړL4Ճ䉡R1XLwysҹ댽d ۟H3CNpC)n~-;"d3 w_#Oh,Kj'}st?y e7/9Fb껞*.TSt}aig8ŖnZ@;ݳ9?-AJi]m($R2'P_I 'bsӥԗ"bnVJC?yiw+].EF!h,$ꎀ~c]VGƓJySb{~YB>WU?P4l6O=. ֮2~,[1KZM=K!].P?y_ 45%--P9U<.m-FO5>-dZ\P]m̭힪'[I$R@RrIIJܺKLP*5dѯ$ 6 gr3x`)_vRݰJJ3SbK~%;]ɕ"H)'RBZp,~5'bPVSw."6~X*vyMބTʚź;QWB/y;7&* endstream endobj 203 0 obj << /Type /ObjStm /N 100 /First 885 /Length 1523 /Filter /FlateDecode >> stream x՚n7Ln @@u%Xm?+JN%8jC FQa\"FStjeHFqzkPN;RDBc'DT Wp4FE+mX*^K%b1*GC@Őґ lH $4h@%FAT0Y`TpcpZ|b@c8a|r^BAbWp*v vbO'*6L(0rQ˄^&  Pp0;iX9TĦ$t `*0jv1L ΊV`b,+:hp-C<6GxsЏauvCh)@ic!k<0a@(Nq1)tㄡNsg(t#jֺf]BAD&iATf(Y󄡠7 ;CA(h>)p^:Gİ 3  ``(P0x `A C0yT=9QO^,^/ԓch9|q=5S=SHq#2}J)Rx/ԯm;2պ_Ne*u-u=I`g!TKsY%W1q9Si,T*v"ۄ*uYUb*l[}ҳBi%}DjKަ{U u.gOR48KuyQa2?Lm˻BԶkBkBky~g*kr[> l/RH顂NWY w>S]*l:=#?r\VUF72Mҧ ʃ *O͟l-~H?*C]\ػ_+yV"m_ǔd`*2e<9v6j/ޟݬgiOPg{Ynm> stream xՙMo7<&_Cr ( @[=8,Œ65nVm]ǀMQgWV!^X RB50|]0SpZ`0^YmE4V`D0hCB1 iXJ:X[9'gZXBr@c-$7rYL'-d:ANhpHvRhK$:+YΣaD+txd+b0l!hn+ +^N+5Jؐܰu-_ql#Hf;G$+*KVHZPB+`6bYp:Qdqh>"53 R<+P(q|ayAt'8h9#x!÷<: y`tpv̂ƒ^)@^ƒHzX~F'A3&!x{6,dxG`B`f-1 `0* [=&< *<<[ ! ۷͙x׭xA?jqinzkչ\JI̹SO\Zɟ{ne\pn^QITMu9"Mrrm+~rf٣@B!jjnθY xJܦ& ~oR>v^,){vR:=Ew G9%7Eo6QhC﹌zO6<^co$ ^h@8Snʒs/SGX"W|Nu_GdDm#R5}(C& j3÷iGʊ%JL}净Nzo}dGϘÔY6ϵڡNƲ>3lզ#ì(~7+*J=EײǰI,fMtR ؕ I ˓U."_oEe*_D\K#uC~uzMtC(ԩR$ xRD+&KUq>ZRD*EDzГ0t!7L2*׳ֳ?v} hAQ l9Em$a8HVЯaFCp Z' endstream endobj 776 0 obj << /Length 161 /Filter /FlateDecode >> stream xڅ0 D~d$NFP )b5T,!C=la ]cUn['@CKxA헚ت1*cQ| 3QCC+ dsq\2&NkYo5 eaB4 endstream endobj 782 0 obj << /Length 19 /Filter /FlateDecode >> stream x3PHW0Pp2Ac( endstream endobj 826 0 obj << /Length 1154 /Filter /FlateDecode >> stream x]s: ل|.ֶZ[螝vw8G8ߠAt3{*Z >yo` YOJW 0ƀjH5tCS<է7ֶjkH| trƀι5^#*68OUJx>fW ' .&m!z/-fy LpR.mSm6s@Le&Vڝo`UAi@r_>52!rSLjGfigb"tPA7sN+^f&3G?-t't?OK[62#'Z } b5u4*6-8%l~ ]l 駼Gnռj1H`4wk1o$nѰK+{ykO2dV)=+$-מr 䮲BҜUN&7bNʊT/4#Q0nAT%τ}&L<,{Љ_s> i9絟q t4d endstream endobj 605 0 obj << /Type /ObjStm /N 100 /First 887 /Length 1941 /Filter /FlateDecode >> stream x]o7+xň߇'Fص W6ƦkE_iJ.MR9nj4^Z!AX, Qiq+# .y共 9 gPpsk+HN(aH% F@#ʱCPR(AA  , :Iر`F";# r^h= $h 4G^ xP|t\P& k @DŽD°+>HP:"!>rdԕP* Qb4V(XCֲ>$ 1h@ (qܠ Q8 0B蜄Sk< k8z& %`Qpa@&rD5a<! "#D'˖#ͽx8eS<`QADv8x#NJ`^J Tv@B-BK iLvy2L C)b&@cbsϠK`HB!A0p2W0"$(7^nQ9XEm̌pG "dŀR@9􂷑Ɠ'b8\ 7wt*W)U*~+n[CqRqJ>RVr~ɔ'9*MM,9srv|JLurPޖR||iIƜ||Y9."%ŪHU3rh7Yvɭ; K4mz8pyT_,N oE1zWe&^ƫBv~{]U~(~ea}L ]'Үh ExZɤ 3R/2{-UBWe?:.Pg7=+/Muw-N.O7M@We9,%,nrZ_-M/-Q=o d{m9fp\;iIz^|/-Gcy۳Vt-gnz|~Y0j^ta BWjNۥ'eIc#Hv5^zA/;~-KS]m`"7ɿl3ж%(ۥ=7ߋ'UQ~/[:h%_-=^>ǍK-C/-iV]N,.{kEt.MBr~MoDcHsc_Ѻ;N2TF6D?_kρɉO bxxxF< ^O`?-ŭ r0clOe{*SٞT=lOe{*ٞ"t Gw,çӛnbx4ܿPrXK(.VK3mcܟ;A J58 V 3H{%FVBzcȓvqzRhEYYy~+J\(޽Ler_U 0;W!&`RhL xCJWo%P\ *#UUƓF%.P*R1jV[[rlW;< endstream endobj 873 0 obj << /Length 1165 /Filter /FlateDecode >> stream xr8~ -5"L;I$vM/])456<<sJTT& :=@ba63 y@Pz> xuip6`o0)$ W"' %x\S5tp5@奋d 01$a0!U8M4\-T|յ#Άp4+~ΝfpjbY2isC)(czoP d>O@K(đmoGuE%KɒT,'tl]P+jli:]ķ!e;BkD@P v-oCL ;WI^X2ٓ!%^Iyu=7r'mDI"IxzN"y (D6#h!I'%3Rt5?#Ƈ; z"7 6}]`9MµPTݍ(K]U+qS+ ;59)NS,yl&_":ƭHo[zGL'MT'*!r6XC>=^Za1Ɏsܤ3!g`&ڰ|Lbm^.:Jܐ\r'POy;";T8N(Ƭs8ݖ*gQ04Z59asS+ϙ9%j7$s[ řfq|:6[NY;Vo$g_=C<:lUA%zL|"5ZH}<>wib5VW9 we@̃rocrw]Xh`3"G[Uu_Ug3SNS]+P;2j r&F}~x 8!G~[㹊eXz6E})Wz7VJ0|sd:dx+aI`~a0_mj*Ljr)t zB|׉ff3e!Uuڜӕv[A$貸J]e qO ;-pmR>@x!/^ߨkӾ]q.oU/yHaz;yIUO{3J3}$$- endstream endobj 918 0 obj << /Length 976 /Filter /FlateDecode >> stream x[s8+t JnlgW0d)pׯlDu 3G711<< vtߌ }  `['Innf::` !%Q6C //3@}/oS?P5$1Dx$sǞ{}Ves|֡9*U:" Np;@wyax\SDP sʶBܠ\*14}>Rgc NFWaSr<;}Iû^;eYUmQiOkp6bu`0!IJz(ۗۈ礙>9ab3IszR%Q#uPc8m<#p67T*j'w|N.v!=9*e\/.^y'nlƈI;c]Yvvٶ<>#NJu\#LZvzͲ0qQ>%&{YҢϮ 8~m`= 񎼢MZ EY-4Tqh~6 8Ӥ}z^dkڥDyK{-SŨZMDZg82Z=ggglt.aR/u8ӂw "ˊ|XPU6ұdft ΁uk3 Aї ń6n菘ҙٸ@w5YRʫNz٦,_`K†7/讉ʖE&SYK6;66Sbq>~4Q!DZ KƄ_WCddǀ>s3ʰ8Z|kdS|'CC_ٝA_i'Ax]{H>[H}zFQs)˷~ܪ*W̶:G{֚1׃ԺC endstream endobj 829 0 obj << /Type /ObjStm /N 100 /First 923 /Length 2705 /Filter /FlateDecode >> stream xڵ[Mϯ1pXEVl J$`DAcאV^B$q! tW.'M%Q4-itZm=YFSG%E)I~e g q:JK,$ :'-MqГ"i3)$G$=N!t((^RU#TMxWOՍG2R w+xM[=*^04Rw-Z&Fd㫪p  Ւ @KW= 3&Ƀ|`rAį{S&K@=JBvhlBx^. ҝS9=^iRiTF% ʐ4: @XAEN)EaEaRW0)#=pDuaX qVgDcѦ0"P / P; D &. `J=tJ=Q!gԋ<uxF;wQXrhGĠTpF+Isx CZ?ߤ׷w~?>Noxy?tNn^ݧe0{;6rYD]pѣt>p.߽}[6,Yꄿ+`#t`1UG09뚫'|(HsaОif=t-Q;82mpԾ n$;Yd7].#jG .|ΊeeHR䎐bdeDi\ SacQ"2g5YH+hU78UH(𶨟#5@GD2 ˍE Ӑ4!m {N-̍-keHQ FH"Q .C*Rh  u[n[! ~ʬ\PU1^5"6%bObR\PkCEU k46@*Ij k=T 悚ZQ2˱HY!~+SO~ -ʔuH"uKRo!/û"ꦅPY)Ү_;@3r4ِNƵ^&:gmGe5רG0 -dQifG~Sqb,P2 v-𵁂>am$i+!(T2 mѱPhC]omGye<)J硆|S/]K.~z'wpM'R^p電Wl:?}$r^-޿Mpo޽yuXJ;N/%z1̅r+?}"`\.?4(!q 2uos9c2)MymkS^ڔצ6)My6ٔgSMy6ٔgSMy6ٔSOy>SOy>S_佸n6؍3=rk68vqU8ͥv#muEo4 S 2 i@$nG)32 yqiL\oː6--fwؒct,C`h se{Qĝ-#ڐζgEs8OۆvՐH 4v +2 43ٺ*Xt>$Pnhc)+ |'q'r]Ǵ1zDa$"1F+i`6x $)W&l#Mnzp 9VqL =`wUdCovakj>#l n7}K= ke=A aRܮtCoJMzjQA!aF+wqZ ~WQ27U]zjsʹ1 shVv[;ưwVS`ѱ tbzܮw+FE^vQfNcNdd d d d &yy_L!&y)/bʋ)/1)oLycSޘƔ71卋Qe::6Gϱ18ɔ'SLy2Iʠ H؞v{~H஍n0"KaIA]R. V8ӗ!mP af.CB EAeέːP(\c' )պ ) `=8A,ʆ>x# qi}ێ عFC!c_=\:W .~ɕx%i~1-u?e8&a$N\ Xr KE!XG#E|GrAd{(l@\ {DI(y=ˈv,#y.u }-v#&!X`Gf,-ؑmHkk ^F>o/Lz꣡h䏓2jbgF>`g:*vC:_I  endstream endobj 963 0 obj << /Length 1248 /Filter /FlateDecode >> stream x{:+ $$!\Njwᡘ*Qڿ_RA?  >|͗^1Si1Ͳ1`Hf|kzA ͋q8&7n|Z_n{A`\{HK5BM@)GZqՀ㄃2zVD kCաGO$r~;c7iE3h7Mn#MJYCw\s_{hI,o1}g8N 4mfI~?b # cʭTQ:)Z`q\ծAzNQ GC]? ]xtXf^iU&4_3lc"8, eW&ڟ c`C*r]$Zei,^ +~ދߦ9n4fcȶ e)%Rƅ` jy^V|SQk9:gk9gu'Qq8QC8b%ıOdb}tdCA LvE+O0?I04 ӑ不aލA4'j#?F8zeXa[1Y9녓BaU>~mndUg` WP}i_:Ǘ%qF%-ܩ ]cm_|=D+Đ>sZN2#SW kɜ@=c},V:;ϱj>BT^YoJvZqu}Y0grܐ?;Oޒn B5__OW3CmYlŲ7(DۼW{I3DgP![V"tmҕ<9y@RHj| endstream endobj 993 0 obj << /Length 894 /Filter /FlateDecode >> stream xR0y\ bKb):N pW}M]uESiKK@rVZM ^MHtC;g_ڹ{\n宂՟!GP0P91@0Cg_9Q9qN\SA* C X}LsQ=I~x"rEպ#úfjˠV}LpVTVE&woZXxNϣRffѫPlDSV{l ܎mT|6Lq&TC;'Fޫ㣹8NC5s%m5˕> stream x3PHW0Pp2Ac( endstream endobj 1002 0 obj << /Length 383 /Filter /FlateDecode >> stream xTMO0W9d84mc+e74YTMfE%$ĩ=؞f4z+ 8-(OMqY]'&+ʿ(AI}f %]ԤWϴ RV^TsS*8gq0vz:Bj/܀u5S`Vڋ}UvvpqXb>w> stream xڽ[ێ}c"  HCCH)ei saW.tTRH=+T)y)#&GN3&D|b!4{f(D9E/(1> N,5$Mld k::$\59$Tŵ,$] 5չ&%@p\![Rq?8Uc ۠ǙzW©W*j\bK\VQ+OFӵ$cЯ)޹rehZ(X\S+-5걸a'w۴bOB-pWVŸ^8pZhkM] ab[k&{, nlSf|a;n@b+ c!tM@nB= hP1ޱTZXQc Ç VW1Hu7Q8 i86S9x5(nqVq fuj:;d=nNgB%Xyv\C p> I q%0qqv~Iooo~??/^p.Ϗ8w4_߼Oߑx@%f*fcƺӓ'M:ۻt|~_"s7rܱb=c3!H*R,,C 2KIZveHRY B%E!CB8EYkFDl2$a" C]6@ Cbܩ!zuD}"L,=sN.C pb#jX.l"GŔQPc% zp*d+%fx[QP}*T>`WG>`u$]$sO=yD"DelOG5ܞUdLl-xnNQ=@i׆r=_~q}ES|Íqn _EǁF&Fw/ӯۛ_γ97h%$No޾~yf'?w?qQQ(Tz^7x4)ӑQQz6}t)O)1]P "j%8¥jt-YhLfÒKCڡ%@tcp*ӺipPhP/#0 HpEc: X6rFl": NIcvhmӆDeFxJ6'*n-|S$1]=)rDLk Mir@!?+9v4EJNό$͆XApA-~֬$4a:n%jäZ:Z ,hP7嫑d4K .-3c1oo4p7ӆ&7a`闐7`ob^bcٽ^ Lm}(ˠouL}cr[v ]E%h/oN!\;>7#Ӟoރbq-jFU=3v"- k< jgn;|;TZ{B!x0=Sk)AX*_O-_%~[#Mv&;`dl m&&&Ц6)MySަ>)Oy}S^ק>)NCu<`1blh-3q4Fm<.O. 1&\;C57<0?H| ПӽCj6$TCN'1MpGق[90/:sD (c$ϡnFx"^*jHh !;!m8>Ȏji33*ld_1v-y>)fm=0:hb+p!\]1yEQׁjӆ(v49c6qEǐ_'aXxC Ũ 8nY6R h(doY,w @h4l%7d A] Q\cd/܎/i$a AgkEȄE߯Yy ahp ֣?|ѡb޳< \J񛵊:~̆9L7sy0:EZs ӟQyh 6͚v'3J2Q\a]@Z<_xӠ0iLu_^3B?}? *2 endstream endobj 1007 0 obj << /Length 212 /Filter /FlateDecode >> stream xڕ1O1 P$/"j%K{DI\&&?O#fs { :¤ ]P=+:/ 1q{OndR{<}67ƥ)0jMPmO=:Q86y6[q2EOD:3- ju/\6.=]E<:SKk endstream endobj 1035 0 obj << /Length 618 /Filter /FlateDecode >> stream xKo0>&1~?8U8T(zR$:kl)c38A`ȷ[VkA2A%B&H&`Mc(&R$LVZ@iBjpֵ~ZLLyxVjWL95qcЦE8]&ZU)yߙʸw{!k]fXlZL(ҧEav̝t -'MZ{-Tm> Ē0vHd^te ǚF15|/{NnAǘi2'ic9 LAY|F̶qbtD72umCyRT>b0"ly݁^ày/0tNѴ149?$~&$%Oyĕ5:TO/*mJcPhim^\>v&v֤Ͳ:geҼ#& rLռ_ׯI@$$`9D,ƗL3 ܮ&q 9Vb]|H6jόC!?9/^EN>)Oxu와 endstream endobj 1051 0 obj << /Length 209 /Filter /FlateDecode >> stream xڕ1o1 ɀq;[KȆh/eC$K'&?O#T}$5C:*T`!5liL#sy떣t2WE=klçI*[l/-F{Vk@ι¾,Bѫa?e yNdU,R6,Jd6m>nιy}GԟI_o[3s J endstream endobj 1059 0 obj << /Length 437 /Filter /FlateDecode >> stream xݔMo09oIҖ68YK,KV6VӼ<w@pPduua8` scX(X7>͙̈́L˫#%JLdFE.|Bq)qsi;@IiƉ1B12R{~ mD[׍ W"Ѻ?qt"߸\!20ӄES$r endstream endobj 1066 0 obj << /Length 210 /Filter /FlateDecode >> stream xڕ1O1 P$[j7DpBjQUjI l`a CN5ByDU!uCamm >q9U7 )WŞ6X̗Erf!mp{`(y2Sp2EOĪ򕕅QچE\:˱7W^nE<:S lJz endstream endobj 1123 0 obj << /Length 1076 /Filter /FlateDecode >> stream xXmsJؙf*vFMbR $0Թm_zb"/s]b0:ii}<:"B-F3AVL3JcSߜMU0j3`K+$\KY˧IUs dVW&c^iD)2a3,Li ,Xpn,S @mDh SUAmJBWcDP*ֈWB.eK^*xebxA!}+xGB8>vS$X}ט=:r/r8K3bUCOeK?!+;2^f0v?]ajݼaUx!n{7m|;~v{ԑ5,uϯ"6G_t`a}PԽRMrw3|umJщ?:qN0r>Hz}SC7kj֨#3,==O䥽XYZ;wfIŧA2f篲SX& y\_ӔU>@O;)-""/o |72%RW~ewa R) ]F@ “IKKF\_/,Uƹge0 L$_ 0`i cmC֒0}F^{h=4IE)-%?exliP`,}]X0Ukxb/ 'q8><4#N Bd&K}*KjtlF<^\j**fp,bѪ!|&#|3UC`&'m4Ka&b[ap|ĖQ?PLMq15wC-rbWn׼ c_̐g MߥVv<@u& UvbɹirTNGTNRkQFuY&U,N5n].7!ӗ7u0x+Bqcz<ߋ4,ӃmͲT endstream endobj 1254 0 obj << /Length 2588 /Filter /FlateDecode >> stream x\KsHWMMU:ͬ1;=Ѐl1= Q$vb(efeU-l_t-#%Ҳ$CKEUl1' . ?lφ˱_Q[UrO/ͦzErA`,FRHQn &_~ˆ9X\0$1z ٜV %АEhI,kn\O$m(GT$Ԅ?}4 Gi'ܯ>,&p6rmWuDn/V Q]W ŕo?[_U#\Lh'&cNWIݾui6Yt1uwN#3Fd\U9և.egrxU+9LZT&^ӹ  6IOy}zW_[NqAT*psT{.nۏD ‰F*j6Av l<MI.T"fiv[wVܴnߟ#4>~9$\uW}^w댞#f@6|!oU"*ܯ&3p).MX~tEV*{whFFpKD'Tٽm޸n:i]B!aZt$gF{LX96SL,cn9FɝQ E15Q;p'(a&h}]x/;-cHQ DJu?V!tQj"9eJ  Z$ADA>UpѠz̎MÐ{ZQ`+8rVФ#ÖsT L̔9'/@.En9]pnׯ|s:\>$ ,b9wqϑs K&>Vt4@5&#hX0ǜhC,GuXrb%']ifLAĈR/\NP -BG J vᤴv&DNL)6*S;a,P:lI{bbN"0RdyG34_E`*lkCK*l8R` @zMNȣuhYCڦ/û,D`0AVb ֱA` )DGgGS4%0^+?9% [}Om?^38D40/1 lَS Zᮖ1y79qHXU,= 2VlF%ዱ鵵>5@8F_?7]vUxጭ1 e"h'|u X><;VQaIoFCwݒxui6:"T\㇋j z?bqm6gbNĞpҒao9uD[iO3䕉c.D" U9O8 Gmyjv2QCpYl9&dRy]c#SհѳY@]:gOzNJ/8:pM;DK K ]m'e#)IV669 eR%sR+A5dݝF6W\d9'23 JPja0WlC8~j}7oӲ7)+XS.ra}<[H6'z_)ś{?^\3X;:v%4~yR{enTSЗDJ qj# cDEs9Rx>4HhVaOBJjI=6~ŵ+ʼn`adqeO?S}ǽhrI9T~L )0>VNV +XSB H_Cx_!8 Hʨھ;bZ=,G@l7Nb` endstream endobj 1004 0 obj << /Type /ObjStm /N 100 /First 999 /Length 3385 /Filter /FlateDecode >> stream x[]o\}ׯg! q6@ Q1~:Fm+d4Fr"[}wÙ tB(ZC;b 831uqv9U4(tگYǒNЂsRGQL&aɱJҎjl֎C6y:f2u}ܱc |;$:`3&sCM*]hXXKW( CXj{]Q0F] ϨKdsWFR,HrQ3 r!K%|ڐK$4䘦qR;6qmIlUZo-Ovrrq|Z.vn=2:{@ D1p!]łZqv7˵ML:bx.Qn+rgtb UsW {#z#yCQp%Kf.]2dv%G]rIm'ߌ/^y9oOzç>GSo- R>RD/>Nr䬃ntO0?{϶}jh/`ۧC|?^zSSў"}ϧ&g`nps#7WBw{1ܩ2o/sZ$qM Pݧ2q{ZmJ5\|z/paë㰓GrPqڧ4i{vf=cwOp7yxձ(b6d{jU+X-%C^֗r9G#!)oORZʇ8+ !k6-r>ɽz|bM;{;!Ðnϐro! EQ?4S߼^ώpE abOhp8Fu >㢰=/[>Ń]nq\"\~u^wpDd/H{읍冻eD|8̤۩53ό7rˆc:,LzoA?;Տ=@9ޞ̅B['9x/K2gAv0v\틟OI%et WMΎHyyٛ//o;I,c$r(p(vPS;oaNߝYQG{}?+~Xw?O#G%.Y]du%KV.Y]ru%W\]ru%W\]ruJU FFl郉pJR/UzYBOrQW_R铟];'$enO!\oJ~kLs*V|d8#ELPkyVleC߯>`<0Tyik㠓q]JoX,qiK%y^W*a:Z$lmaK zZx(fVjrKL:Ӹ2E z8Te$T풗Biߟe fR,K| #B1[SQBE Êj20 J }8^B[K4`u!mMaCY|!1aCǣ5zYgf-u,P؅ay(sRǂS:V6ac7,wbmqX09,ƀ:ʚs$Yь . xڜ!MS"zƵ<,e6WC)5TkWJ3,ąe["07Dp 84)YH](.%NZi(i@İn@W <i}B E$%`"k:!"N, ~U^ <0G+,iʘW0 P{{e-r=Bز`iqeJq)EĸQ#p6Uh@}{ǰ =,)eȫ& \4Oa qKGk' l 4gł'ȃd c98c0ڷ6rNJ!${8wq-&LPRuFj4nͰ  (W7QL7І UN-󜗐?3"RTTu83m{-M'C|OD-9KI!͚"@D5 K:{ɪ'gc6tFB81B0COYcw\&D#۞j1=ZňDsczwu5𒤦<˨JqadːH%y ?:W%Hv~ݚ<|sĮ2Ȑbe6Bik_O~6jGJz4e9y5 ;8W*鼯Rl>oLꁝA:'8 ΏMܷhy( ~,VՏ?GW*ڥz+_~I%K /)_R @~I%J_e4>hA}P/k5˚eM&yYI^$/k5˚eM&yYI^$/k5˚eM&yYI^$/k5˚eM&yYI^d/k5˚eM&_5]mՆ]mՆ]mՆ]mՆ]mՆ]mՆ]mՆ]mﶰma~n -w[ﶰma%G]rt%G]rt%'\rr%'\rr%',.yԖE猕/AK¾Xx#4Fʈ>hQ#q4JVQeP7<.|" ?|ĊNØ8/<DT]! .e endstream endobj 1262 0 obj << /Type /ObjStm /N 100 /First 1036 /Length 3378 /Filter /FlateDecode >> stream x\]ɕ}ׯKt ۰/1ii,kX_fjTѝ8qĽDFvl~ !Gb;`iv[dX@#%;[lRG8-]ojވ]I}iJi dEjQ6hF8%k#ƍN| ;&&o${k7&e@jP DM9Jh#MkEŎY,jT~ȴX컙˲%].h#-qx Ÿ-[(~>Z%l#2nGev"[N{nŪĭ#mv,8-"Z)^1o%h[)n%;"ϸ C`Q qcm( hrN&ݯ0d q3Ba;C?5A!7C26.~%#fc Zc|xBָZ|$>YkքoZ&ZC]IqLJ֤݁њYG*{F_sM#Fִ~-):_3lR.f2 ZCDZt]Ioܞ~o}wyG|~]O<EP"9o!@ vpʸ7lOnOyӯӇ?_Qfށ8gRL\x%uo)8`EМ8^pklX-$o??c?ɻIqlU)bf싮T?~rĂ~)1}B?}WMހ4я>KX=Pg}eЁKG1>QP]+֖Z*y![b#6c_8u\JF}YJemeZ\Zgmq8RUL08cr7:JiH%r=TzQ1Fݗ3p;u=# DHixt^rQj5\ %Sj4S>?^ ئs6s`M]`9"0pΆGiq@zMƕZVhV|Um yS`F)XP?vŋ,(תAZѲ.$=r=EP l\f';Jj kWCPLQ[]/"):r3r!jKLTŘJcMѪ 8&IL61)3? ë!pUbK/ Y?8mU)>˘3jBޗ2@d6JIwqػg,1O/]GJX) p/2"Zd S<6aOQ ]oo{$p<Eh:JjUMYvFՠ )5֑5 C%@ބn (*~uS'ºri>,arJ3HByj4Y>Ρ4(#LBTĽ֟Q򃥁 *N\X(!UB()ȇւ]JPBUCi.U)91N:jgNt&|![8"v A-TG1(CIPGf,d-?a,L8Fl5/JE a=#n%3UB{p s y@H_\[o t +RͥQ-PCgf|z Z)d#AXd|l>)Xu8Gt=z4?] *;eh`@E@ -W4qТ=8i=2܄+Ķ[L(ry@Ba[.} 5oa¼osGm4q,Jɧώ,ހHsѢlXI$qpz{N(uXHQHFe0gl;R"\Ao?/ѹN,V 1OH;PQU}B蜻jl" zt,aM! ,)5 VێOh/E 3TKʥ$U?H{&ږ5[[^A8vk+l蕛KX #u)KR(^##-̃STN՟~^ATSBtgy@ 컜=*(=uzޥ.]I8AB~Vg0YKװ콽K@_UB2Cs,%/iJxpŲ^&w\s3v | dcD=.VmY cm+xfx C CwQE9PDUki 9rEOaZ{ ;3j<-Zn{°d>?ӲW+z0_"VK§2c^ݐjԞ܀5fJ9eM޼ {UYiŏn4<co_eLUJE4e@ }])YcɅ} fhÏ߾wo=~fJɖþWU) ]v7X-VQlx@ eE{yW{NvߥI\Uqr`޷ur+`[zc޷)0Non܀vƵ> stream xWKs6Wp`|nrkGSˎdR' EBTDrkei/bXkk5}׈VF@`XmD,{xyW~ʳ]ʒB)oѕyEi* :b HHa ; iu- o􂶉Бߎڷ-  !be΃IwFz qzmXɔE;գTv( 5HMwČkޒl@,(HrVQK]Z>Ts_EGW:B8}SO8r'uDJKK+}{|8"ft?]@/ӛbzq}~usQ@?)[q$->J@l;gnB%~cdjlI@Q0Cvv %3" y[oJZ2eER3IXԶՙb&6L%_ NbQd5+ՠ? dIRK!@H;̳% 9G8ݗX(ѵ>X&jq 3Peuvy]@C! 9'lOߧplN 1}/BHO{BJՇ B8 =pDK c.P"T 6TEI^D¸ #9_6DsbMg/I?AމhW|0x8eP^'U FmǨ \+B}>T- Fa(%@hW*G*%@!v/%!%`Ux|Xp)1AmapB``ysra#paKϳ9|Gas@+e⢡P |)4E^Ϭl13QvVe+R>s=ϜI>_Wzbq "b~rV> stream xڭX[s8~`f_`fm:]w8d{l3˥i{$lln}Bwl, l?.f(p]jsw] rm#L: 1¹vHN盯yYGpudûذ;LG>aFr?)<{c`Dxh߼7CÄ1a'FKqQZ{CZ6R"̌׼l۬Z4䠆 1: g a1< a.q\B\"B QQOz$mDrHo+ 6CЪLǀ`  f=AOuSL:REXJVRDB78Ou^Y.ݨ y-׆kD |*0{=g$@x!~u2fnJ,1U[7Kj\/u]<=*" ~|B#(]R^S;VpBӤ_<%T ʘy*bī>~TB)O4 (Ͱ-a x"S.D-1DBLbu:mTFXT!'Y۬,Jm$jIJ9n2Un;\1mM~Fקgh6,v afPK"_dsr`Z/ǫvPPaz}iِ?w2Ӕ.tkW! \S 3:M>ɟ>Bv$skzkY.\nwCd4Yaxd\;炙y%&M& 5t 'жgi݇P6﵋3D+u2e>+sF^|φמu]l}u/2ӭiu`;蹉ۢV,v"#lf?5)zĭ‚ӧKƶp.*DM2xR{*aS&%e>8S9?x(e%+rU5y SDž(:&wu  endstream endobj 1333 0 obj << /Length 1079 /Filter /FlateDecode >> stream xڵWQs8~#Ċ$sMtN0gbr$!4!}bYVow]!F:dEaxG"FWaHGCN;rwE+c#mX˦ɫ(6_tş> "륜vq/[pP2V+I7F20WI[DL[.5g4 9Sv3Ɯ |X-d1QY@wy޾gY|ͺ( ]G :2Y·IDz :V&ܷ嵈qxmܵcUK%3B!?F]nML6)ɏ}7F˙y[F) ?yyu{-6p\7ݸNQ'gxc[4۪DTW*&ڨMe}|n^ufyӮ_0bjlm*BL[AY} zp#vTI^6<3Z`roTeC3Oh6fX6Dwm䐫gzggs: KڃC(lū͒<r "9Eôl"c"vs4|{h>{0375bGbx6oy}r f 40F3? aFFzت˪U0-uCh*X4.ϲ*1DO <si~6}ƐfQ [,QjX]PcuG/&zK/Fff3oadn |\P+ zS3O`D0!& 4CeztQ86ՓxAv6F[ңL24T >[F+g41dyPX7D9WSGo';uhntoi/x׎ M#mG#hL;t\uZ" \07/> stream xڽM۶_SG}Pzi^Mvi'Õh[SYr$__em.6H7w]wzq 'vI94I.7׿wXx"λR76u_YwV+$^ٯ>3M4Nv^}wr}^KCyvDy@sz?+gxTxyz;β.o>Q7z/kixQ:7 VUw6͑UەPLô$?;yq##@PXhכ(ݗ?"^G+F,S-ú&U򱨎Rt8tUEE߿\I6?oDS3r1h̨8_J1Jcv&LcW&hg&SE#h2E;lȲ$>XLѨO]ѨQ5ݪfcTW%߄N@uZ 0Urkv7s*!=ӧFܨ +yE&) ё!d7ztSȊT2;To _ jZֿ#S/K\aEڀTjj:qAKDp[ "+5FG.dY<>=)e(]t(KK(L 0(Q#גNSLbD{{LXb%0YLɁ$T ={ *FOضpAPhj :HQQ#>Y Ph 8pp+1OcThި>gLJLE ԅB vdl) ˧5%6]R X\fT֋ڐbx&*M}X'wL@{ij%%5J/NbK6lֱof$-`9zBW?j-^f(o©;L;.M@'gۓ4EԌOGS}k \plkP+w;vyé>Ǐ@ A+bxh !/-bioS:}QbL L"8=挊1 m a7?I I+碂 %*Դ4-C۫dCMr(3Lkڛ1v鲑,Z$Ԣ囇٠5ղYV*0P`=զU8.aFں!n6Dk9!B z{f"8aQ7VdbAYs9(C3lU(q^],BM. ;Dᐌ}UD ,?ݻR oԪkOk>҃%|-.5-L,}ϴ(i`[!o- BOԁ|qE+h:Owvvۅ8\V=rl;}%3bEZlR2Ykfk \_J, uׁHǙVǧb?kHeo6=qk,5t6Bhw `[%/ {:n\]~qƤygS6.`ԃs:,cSG\&ntpIm=:=? lx6]W‹aG^pBF.6ߴd3$qn endstream endobj 1346 0 obj << /Length 2447 /Filter /FlateDecode >> stream xڭZ[w8~ϯУ}NUd;IIg99:H.M_?Iɒ-۱OH  @:u>+%+ǣw] 8qstH¦3_24:"Rqqq(Oq){vywA'uXϥx:o,awγH$K3zTjMgR:鋜[r:Ur)#GL0qM|YGa:sD_+RRC: 8 f 6IyGH…D?(O䝡Ң4*-4ZځU1kJ±8z."{3 s% -BҚI.Q~YHG83H\33w'(-, kjl3, 'Y˰ ^=Yz-qGSonN2D!u-0}O>MF`otԗu?]7|{g@L#gjmoGP$xOKCBq3<מ/ N" 3.`GM`;3Ev]x*)~EhOƾv"(͌UX! vu|-wק`lZ}h3 lh]m/xP;7L1PEQ=0yQA4;n:30M$)yGaO69iQXQj.?aB dNan>u(;P7i`=pu""֎dԭ-[03$U@mOaPJty="x(BY s)$xDho:C*l7n}:h^tCKk>@ (a$T0zU~h e 6c,o\Nz/ϢFbtcǞcA(bݕ0g|_)8%}gH$ƁۓD Yc͑wQo("TH@ws/9c4^UYxOP%ˮBzq@@l<14H쵰 8Pu7tr;o6ﮕ59U-WW4=Q]S)6ʴcHX*\9EPpBA7 ao6ȜQsB$>d۵ tyǐLoOc> stream xڵo0Wŵyۺ*mJ޺jr ,K!YRO>-Awhpu<(Q0rOQGzSt\aWTC'/l23e< V3 qxh<>÷{D; Ѧ\!y*F&1yW0u.&X>:щPY:*^z`HaHCL<5Pb )#jSSRBMHsɯ|+"C*.!3r[X$.솬!׬KU\P+aBXjdBɦ]PI&EdyצMV&5ecQ2+)>}8:<`tf4jmXy&Z\Id+cm1ozmxI@bNEC}`YRMj-S,PP8 aRYmJ,\DIVI6%ֺijNmGvr`]BT8r6eJZQUV\7sv93"{Dm}WI(, GˤjW(4=OĮ䯋l4_=$ #}cۅ|U/챎q)^j, O#XpM(!kx&v:;\nx)>ƙlX@$ai}ME:{nw?J@m2 TdX^ !MI]};z̍ArɍNq*.Kn*b)DZ#ccs@UW x YWNdܭ'mj?ۅj> stream xڵXMs8WpUkE_HpLfjfR &j7뷅cgO!n'k[ [ף/ٕ-yB0kjI\!,Q$5[6Gd<ҵ/oiZY8:1fqΐ#KFGAl:"r+G?5o,Z3c;z=`ւ H1DxB0ïϋeR:%'1Q5aY.W<|O,u> \Ω@ωVy--ڍPiQbfkϣdS| YeoF%+|3luiZ2Î8( C?U9A7 )G` M~G9s. ~(UsR7J;puŔvpD--p7 lJ|$ ;OFlQr/c&EXTV21c5d{;Zj k4Ue-qwiתHS96D (.C! aj84ieLD J"6R9 alxtֹ ۗM) p&m?_.i2Q Zit@.#ȯ+@~aO02C" v^]@0. ̟-$>:< bX16e-àu'qV%/L;ޡ`Y q@WVě~}0ƌ}0FwڇCC)6)('խB,-rx_˶7̺x`jDehzG6E#6EF]pQ)C/_@PI{3}Gb 80qJڑuV*eWGWG$ #%0)~0$L{<9n-d3pr&it5?O$ #LJw(&hfv#glMQ,4Ǩ}qf[U-"nZGI5~r]}_D9Y[ endstream endobj 1303 0 obj << /Type /ObjStm /N 100 /First 953 /Length 2396 /Filter /FlateDecode >> stream xZ]o}ׯc»;;3; n aXFS)d ͯRk_^AؾKr<;gבXDD>&|41@| $b(,i x25 orM5 &|K ̯&|B 8$-5k9@0#1ˡq%+  #7Qh`BtJ|M›e^q7IdJЭ&hTusk?-(C98v= )<~ Iv3'(A# e-l*%_PM,vEJo`D^/i?֤ZRm%(45u$epɽ;Ag9;_2ςˬ6&,@>Zcf슑WFpj:Yj-,쫆oMI~K0P&pQSdHxtOB,Ɛٳgg76o/..ov?7?\lXwxOo|q7mvi=sRԷͳgufݿ_>tn8B%0Oj'+P~|<fTm-jAȵ|uspw Sq(=$X}Av`Mmr7+/)STSZ,ȝt~ST&+v``\_Bˑ~[ϰ.mA^rChPCoT";4 #u'^n}ϫS!|-!YmA>+,sj*aRᗗ7^zBzĝ/hGsZy+L{uu9Pf{e{Si=ϫ}==Ǘ͵y67ǫ^ߖ_f8V`W&.&tj>n$NX3rEX92)m)uWMͤ-1H7O`F;zkeaV1zJp{&h Ű\yiQDE|zTS"a_Nz:!’0Sj l\VLcgjHCxC$,?k|?kf?/hyD#{ /uۨ@+EDsސCj*ʵab:4?j%MYƮiî,fH8‚=K:-h\SDqʔi_-C;Z1뛫_y~5(;_o bT)0}_қГ=Z!eXQ~=FAZb6dɼm0pF: 4c2uqCV梼%!ZW:n~c&8iu-zAԅP7fuֱj0 GE enCEgtGwh2SI =e ̜ri6jlwԊ ZuɴF@nj,wCV´!bm=VB};e5VZE\vM4T$dDS!VUM aw&(h}r *zLh[M@IVj.)ÁPj?ƜMMf?jnTǪ\Kܤ/<@>/ܳyWѴd`u2ZKCG.,9>YCUS(:eI)3),B6d\( lrgobq1U_( V/|zpp#m~Nk6Q|İq6&TyrOiYH,Y, i41TmmQw(k> 36ޝ" ױi6Jcr_JC5L][ka*B;+:bc4ڈH|FS~uM8~翮./6KG!׷Eۈ}uה>>hط=OOOOz5/fH endstream endobj 1382 0 obj << /Length 1928 /Filter /FlateDecode >> stream xڭY_s6 У|7HOnMrE'ɒ'O? eɖ8 ?x^]>Fb2" HE$,45cN3:WI(ch&+ <Q <ʌcܛ/G ~¦d8Ƚ(xQψ) %A|H䪬Iswzw%'TT $f*K;*]=X\ohPb+.;ځ萃VۦR2+pDV I"Qq1f_V!|ӸF?~2?aԟ=f5RT?iTyV7He)x.3Be4 Ej[XW+{?1ߏ)4̾g+;fXDuPJ"E@O&*0hs&m 6=1<#}՘ԣJRXf#tnD{:D)zė讌ֳר6ИrZ@ג I(4[$X% C @2t^K%2VCNiH(FQ7_..~ؿv" dz%P0h2av{E7tp8vLS<"XXEHd]d lvNXO,j8t-BHc\|Mً-F$'A$1OrJ$Ӣ$ ]1;3h@SܠiOFGۼyNaaD aqN OHwYPtEcUu$H% e-ptJ )Ju]pGT@}/@(rTm}ZV΅^{F*/s8uePe%2ZOkȁ6S0DT3}V1 Ov\r x_6 B\łp7*a+~&cBtpM!sIAnbߧ/w?/1N9YSF$`fynk#ۺVv %ӷ,ڮ8'ɰeR|Ls oK|]bd̝0 )>|v%95ݔȵ.L-3^Bga.T>[*}S&ps+Y7rى*WKULg$\> amXjs\aKzElg I\-GYCnb3LT9~QZL$4 ֨G׍7l-:ήCvwB> stream xڽYISHW蔒BOf.C$!19d+Jm,)4~׋,25Ժfrk[!|ߵ.gV@IV9gfsNqQ("W,].[YѯAj0$íd1ZS{gQFu+W.,02k28]<@3B _yZ}Q1סv5v}{u'clJX¹vMDݔu/x9fԎUoˤ+Wuw*`[M6uQΘ{/ Јx9-Pm꣬ڔp Y2ID;i{CvdzTJ,keX05k|;LLzWDVE gxvbV\c#s9M߷/iMI] 5TFh]I:b MϺ xy,D^(5!=>dlqgتZr6ƃ#x\[|G`VG(oU?:FSYDEݩU@CwMUخT0ЅcWs׸)97\aرsXέܷbsW{T }՟ tXSDt>j6窅QWTUFP}L%~c31(v*C{v*VS軰LXfPHDK-W"S.6-,n(=H@x"Z›M:9싗e4Utk5.E\J E)YV,)u17tU+,9[<<^ :K2 b~۪H{h.x`=_x6T q >T!V*6kbs].] +LCZ%, Wu*~@D~|8 >rF|]|q1&{K]q h5U}A S ɦ\#s5& "]L-vy>(LW\3{k >"&.~'EWƪ*qwSoK+y54DfBQՈ?ՙhG1GpBz xHuԬ`}lx]567g]l׫ʕcE:8NQ`tUQߕfq5p!m8P&j(yΠXƨjH<ǁ@\9]>N 5?v`" 3Dzg9AD>$Vs'd[QHTO( JGS'Mr@@<߽El|ЀxA~#z)PȂT\Z yV:LG6%"o:!FI*_]F5Pf){j- e__9v. M,F`_c̵$oLRo SeޖI>&D ~Iu('.sޓDRB3H:v!rqŇ7~L3@ N7rn,xO>\c), dWv'_v 4]7 2@Qs&rl> stream xY[s8~Ԫ.H[mna{)Kɯߣ lvgc;G|:$s`rfr>& ;#FPV4LC~gr|P`].C@1lm :潳,9㕎=^ąK3ӞąE.VrǘJJ-*۾[noeޙ˖srL!#V6qU:]i[DHBB?'I6e4;~dGjwp';)|UDUӮl#BPؘ{d kOh ie&V"Lb %]wINXƴWaNT^`۷\A,j>O=*oL?एYX0n)A0 sUyj†^6+`-xuׁg[Û5xaߚ7BݕO⡚aWT`5{U+̞8=tUVA@8yW"(ÙnP ;v,z1|XӅ W<<!~.j`.BՎ C! *2 %1A UU'(V4G}ry_Af}<`g,_U59+5ǭ̪bifAB8ũiaWJmEEQ-55 5Y;KiQ_x,@Az]rhv낇(W5OQ)C1Kù!K ٧JX(T}yP\Zf `Є07C-EPCՋj$HWYUnk2B9m]T Tz>(-xN='].53ŠKlWgvpo!C<ϭ0,~n( 8y[>6pk4˫Z^4rg\m7PÛ5 ʹ}fP4ay翅g Ӽ%<;d/Fִ)zsюshmjեw_.u%٧ẼǶ*4b ѕ &= 7 MȲʕ&|z{wy6lN|@=ɧz|$G6y\c{`TQUsQT)x^%㶋a ;ŭ )*Ni6˾@>JL28*O[ =>vƻ6fS'lvPǶS$ ^:C2BIޕ_Gԣ%Pv _?Iqn-M:|P>Rˊ/zv\ | ^vCσ-;1u) ^j| @4cqJ]gD={O:;YoNfEyj-wH7j1.,*K_.zESDMI| wlݺ353@9®vW$NQRd+}s;RH ў;CZ<ХLeLcB;QA}X? a` endstream endobj 1414 0 obj << /Length 1414 /Filter /FlateDecode >> stream xڽXKs6WHT0qęz`STH*i @N6EX<8x;}489` 1۝ ip3 =H  8jZH @V@"%11dq0d%xu6}wyd] 1pȋ&j8V0, AJĎӍcrr2!KDO3\&0=5{<)C!s.{ALd0f"Bq+p"mtm9YcB<8 vNǺ΀a>on5âVQL[,B6}ϛ<=mtpoc!gaөPnm2v-/ZZtyhȘOӺ^ZEY8u>osy3lKX1*p4xZi]4UD Ʈ][3t:I-g[ET'56ia(*iFD@oB)Dܕ'QHx'g&@$.2EvCđhmh#a(+8L! & z0~,gglEK%sIZΝLmvWӯ )/&-2Ҿ@-'S ܺ3XzC \ n Mot/9#.tjW BR$r-ihA. ]cSH׏hL{=M6/9" ~ 1 N?u ih8#c- Co(FW?l>sܙ6 [ͻ/u{ k]8R")2Xήn3ܫڝ=sTB/W\ٗ9Om/6{vz[DM"ϷBސ89FW^X8;\44qW3.!IΨm3AѰ#Pt}>Pz7GM([ժ\raVUiopvxli]igㄎS'8@(}' ۞C m* P⣀@ l %s8r 6!mp| Fbr/TTa@M$ =/hSqx0^0<>iZ7fZ?iq%?ZEY/cT?< gٍ3cDe  v~VJKү"P!y w endstream endobj 1422 0 obj << /Length 2316 /Filter /FlateDecode >> stream xZ[~_#S!;q$ ݡc.vֿ>#ff\'@VV <9y}ou"/<<:! pȋDJ vzjM(r̡[Vز uZ?rxj*yQrZѡY&ßU(F5U&Q-AN FaDB/iHQ^fL*4sΡ3'm˷VjqM0@CeBt[31Fy'])I{v{53)l هBh{z\RRj3KZ-^dQ["۪-O_F;F=w\~z140ywEZ"52Emk6u5ar[MKM{6@|fF^M~(8X{MC.-:=G]}Jt!&WenVQ{嚼Pxr̿oJkܼ0HgT7vu]h|/7i58)i)swI-4lj̄՗% .En_"dOCl\ʥƅ+`Z`YJuø< 4Xhٚ!bc>{}|6_ue)WzC :%]<ݨJӮVCXEԆlL y V3U-ϠavB"F'&4i IcTYe^D41ovmթh3G.-d8K^ ڛ :JB-jA[RoТ^]J2:i22iԼ;MWz%i; C>kHZ KW݀1D=.AL$rN8 Q[2!1SЉT^ے(s=?Oр k2 E}>i3`fi'W`xT&YcRl9!ؐ7+OЮ2n E.q!q-MGA&1 \1 q GļvQQ8d9 Gp84mD(Bڀ t"$P~V4<VA~ZsNAkXg5$ ӕR$T^r8)dig6Q렠T:;W  3} G^P]U&Rq؉+ fH86`lFp|1̋0Ƈt]EȽ{sγXO=rgQBZx2a{XcBe]BB[V!2wf`w+ 7oOw}mN~e#q> "?=6=e蹘G/ s~ 75O2zZy`'<2<թ<L=uH~"[5& ?2UYuGzdpŴӳ9&)[yƕyK4at B@[5/y/2)x~Z P2= endstream endobj 1428 0 obj << /Length 2638 /Filter /FlateDecode >> stream xڽZݓ8G*V2ͤf/fn[S3clp $RK c;u.>[ݿ=yW/o"KɼG/I$Ի_zf"/IreU6\u9#"d@\O jzsBіC(^-W',ozqEl]~ZR;bA|A}ߟ}ae~,>P@ldD IT1$~x0n>-$ʋz\)6)Xz = JI,pc& DHX$}F3(&>vLd_JR(iYTfMMQOEķtHOX3 [qv4D/N_2 T'id>bT))h1YU %T!'q英N X,~Spʡ4&4p`xyC',D[Ύ!ф*4sϲ*F*3k|HWYHj6: sX)Рbok ҟݯr%gMvNZhOo - /A]7os`2C Tg&h/DŽv(9AqINL#VΊRKWs&W+C؇C2O߱ (묨͌|^,"0Nbrb\;ОujTI :}e%Bj|h=WnoO?~q[@ªZYdwo1kuK2[:.T>D:#SD쌲0ݥM3-O?JY7=i,2#5L:`Dgufبd^g-ڕW/nMbMmjgІ&vɻIr#yp%\s}r+ߏrMeݕJ_eDR<ÑXꊀ!0Y@gi^+fNA U|fȠ^L!AcZ7f"A=}BX:X>̐W`QywVclg*d+5;(ke#X+m]kMU6ERb2)qLSj+HaQK%`)޵rU'5.T:bJonWH!^[e٘[PNJ'ς̥&wU.iGdƒ"rpgck [d{bAzG@@r )ކ=T'Mic}@)Lybz*#XSv-mK^jBAGQZ`hБemZ$}5b%lk3c5*f L+ F |1KIa/,f)QQJ5:aao&W`]|M+ ڷ?vJόPPCUh\:{ޱ8- G ?:vwa  Ԑ'ZH%6N(4Y2J8Lu9d +~t.^b!賽sK䊵:7ٖ68&_:9Ee^BB{[wo?}mC0q(v! /aD$ё0'>HgLtVY?A2!)lXdƗ"V~uzC H[T:,'uqp9eS,‚q>{_.svdQ.Q )BaHIE4 T}H6HgũT8&Pzqlc:Y!0/E4\:,V> b ólcnL֣ v< GT9Gx O~ndWA~U$iGA~ rI OR?GsYe.&}qplyw̡3,({U3?@d A$@-"LCãx q7t.Ӷ߄ۋ~^$_aR+!puE4 |JXc ,$3LrEלH>Lb< txywG]WpΥb5Ъ{g.eǰM.Qe+PM(lfE{5O˥ݞt;Y]vjN^"Y#uީs%諪(IΩ>Qֽ#ɀzFiF^2PQYPi,f_κɎSH<5TT+;u>ЂHU w<#Q"q&~L{]xkT݊>6l >WgH84P^dh#3F'Ah>7ȟ]߾0Y2y/ٙ5r -bY"ƺ4""0P@ּ&,|'"ĮPjnȫ.}A Zfv`mOEm$Xx!~NaҀ]'% Bɝ ,cŷY풺)~)ux,'kP endstream endobj 1377 0 obj << /Type /ObjStm /N 100 /First 976 /Length 1982 /Filter /FlateDecode >> stream xZ]o\}_!g$`Hb8-n$!OH* H{r$kVh X{ eJ\pq2!DلX'v؄J]ЉbtD ?DiEv)UJ&Ujk&DLm"Ffu$懚h\A$;|UiC1ֶlc vjiIl\]L\ (LCaHE: PS Q1]̶`m!Jf7UXC&q1I!U\ fL#Q a- I]JPUIdIKEeHl[0lblbB[ pp S8 =L!qYvKf-X b+vZ]b QdH0P@dsN"X^wa@/,?EgOTwDNi,"8QSj(ԲSvBƱS1Fj44vlbH:\k#u{1]=be[_! MPV NR15Fŋ>Nnf>7o~^9/뿮}Ka~6- r̞@T.'+v/^[wܭ_?]n.?~;tӓ?Z̩#N׵98d>yq~OwC)8KiҩH݁A|;{;G@b,]s C|֒T5i+ :'pMc>5y2K.5xSà”5YnplS-|F0t.Z"[c/% s ӢLpqDu/ {ǟ @ή~ݽ94 xeH9yNl.b-ֲ~/9q2# K@1Vg$e6<+}WgMP$6hOVPhOd|8n+~3qnZxaVcߧCQT8_XY+[2XUfV+@wBm»cӧ Zd98LA~B<1vG*2p'Td/5/ SQ3) %wC@eJa~W+Awݗ,5 :4wbʣzB;t_tS QVNe ?xk`֮[tHyG-Atpf teVV/SkR|p80nepXޡrHlyGB,X庇h;ѷ{^PPb2Ԙ0 9Lc]wɢ<,#6-T38;CDJH(]'M\LUXOVޫgPfTnL99/yD'X+*{@$4"K\J\vg㫸vhGd-/|wP?Lv7.1|9^ n'+˔V}ʏL> stream xXK۸ϯQh>n쮷U;$ޭ)XH ;9rPhݍ_RcoyVAY}Ȳ /0._Da%vѬ7q^~dZ[٦kqOۛO7UA4,Ӡ>|C;%PaRy R:EÍ?oklGϗ"aG]3v4݂C%Zhi[2PW֍'nC`%B@D,AIf/YC4\{kAH0PѢxqa"&0j֚ٲvƳrr<?=kYB'*;8"' Zy.9vQzX$ R\ |&W;{t\7%:L}*cf?tw\&s^g3qhk&WsnU}ʾWți3N*LLK)d$hjlh9nbqeCJF7 r0GĿă7t7j`aP—oĢ 6W-*4W!]\عE,ZrcDS %i圵f " ÁK4M-G<hhCDW< > stream xYs8ݿGuh>[1}0rzo-0WK1L} ]ՐvXs!E1$.kz(a9<'@]06hBYr%AZhs<-$ QNF鵴@\'"-hz2ь^mTgaB /$S6Qo\"|̥$+eE?x?6\Mu%GiKx 9OaQ ~9iJ0Zdo)=nGa6[Yp1ʭs( I0G9zC. cQNirlXdv^-q>`B&_3ָ}gN"E^=VxTl ӧ!av`>zKT4A#BPR: LܽL"/TpoX[I8WHJu2\] %YH>_b.2J;p1$;oVGU$N}XZgBƃ]#woxS`az\O=oǡPQupyErY\>?UR4GEr*M7Itn*@PvOaL)H?[u0(~o9]|cE_m]=ljQm˖A[{(]l7= .I.y E~@꽪 d615spQM"M'b:5]J>"V|5$OqHU OvLo{(N3A8`y&]"ʳ8ݮuMQ`ې\GG5ɧ<ݧ:ֈ~3p# ő?gwtKls͊<+cb%7v+gN;]uE"F3ri.k´Oڨl$n~xie_92T%u ,?3+n~G9& ƪ ׋-8L2|r}H؂rNA~b(qsher|U %5 J_p=Pg 0PeerjH @:@Ƈ7Q/5C !K& $""%%]TlH3pCȈE)i`yRD$KjO_ܝ1;WclcQنO6n&v;A181vtHlJǡ>w3{U|䏢( "1Cf9+Y=BGl0"`e.| tM`;UsWuV `2Z"ESiٚ,@F30yJX/%uM=*}2,jF/5w?"Cf,hlJTG+~ dz\#]C' j΍Vd!|*e߼)\UIjI5fjmZ<ԻwB-\JR43}I派6eRdҼN@̡2{pđFsbik bP&AwMMQoWn*^>\d\s(VE%{a12k~PkvܸPp#"E(;oz|JS[d$C endstream endobj 1452 0 obj << /Length 3164 /Filter /FlateDecode >> stream xڭ[YsF~ׯ#YeMYe(Xv "!``ί90E/$1t8">BJ 1'ݮf͹=1dbUo%bYoӼJȱۋ?/3Ќ"qo^;O3JD;ʞۙ {c3rzC΀j]<2lҽ]0:JY?ceFԻUR+Pw4'K/@5+Uܟ'Zm6}!K{#Dy |QoUɃwtj[Gi :dľfJYboa )6TUݾXe*-,WF RiT-W Xeϟ=$٦ 4!7TzLh)J@!.S#)$E00%4}P?< < {yYwOR/9Q Fj:3){q9S8pϡLWܷ!D/B1ld1LUGvJ5CkKkU}+C\LK,/GRSX*Zt~PIp\S,*`-_oa-knԳ L%ڷSka։$ZZg CLX рa>$> ͲU F<b $g \ol\CN7,_OwYY c*qU/NEPD11֟Qs H@i4 hh@za|b*P ȑ,j8quza]Y{#o7Ζ 'Q4 ZSHhd`B)dz1gPk$['lzsa8fs~պs ^p PZشm~*XϞri@'u WJ9!,#Y:j3mcƩH$Nh(( ZN FDzufܜOEHn٬]I0 ՁͩuVzkV>6(qyz+R$ApҧH#;r|A{:eBy&#:b{_͊z[." {8R#tߟO(I@<G O  "ӧl`}HnH̯tHU;^;ݻg%:r?  n54_Xm^mI#[)a[w,K'lO:T9qbAg)Kڇ"ȹu3ȳ Hh""'Pq@"]Ia?cY:i3m_9 г(䱡s\&4gsh+^'Dn>^D(6I44,<_sg-DzmCSb'*Gu\WݗzW^jxg 7b'&@drԾALX :Մ5~ջ3`ͺmU,q۞'U(0>la'PeeÉY@8$ycӋ7;RAX q7#T\[7}ח~Psl:ܜO63tETS noY ӡhh8GJi;Q OiX36{o_-butpsF7Iཪ;pfKik_{KΞe @BЈ |#r#(r( R>"nn>__ȹ}j;Dqce㡕&w;DL3ramfVB@bb@Aʇճ?dY2/p U7ݏCah{7l*-Y[5NxPwbW7:SӾa{lEwipBBI$`lJ==]*k]߽]P"B=?OON>ʼnp(,}XACMtToryW"d endstream endobj 1461 0 obj << /Length 2086 /Filter /FlateDecode >> stream xڽZ[s~Q&s[ޓ:얋E @:~{ uO`=y[R2o|)=?Ho{&MTFlUQ$YjMqΐR^_}"{AP-6W^ ~0ba}Fn<.@Շ+ln }/~$+EI J~}}GԘa.YS[h28fA-TO6sXY 딊ʖZ;dKe~ͳ)Ib4@(Z>(2)(.n>`i '0”54EO|bX4 'Ə)Qceco GKFuLL3O4DOtF &-׷u>bOOȝA!Dc  j:qmiyQXvi<*6(7BZINPȏA[]$EDy$_=%z<niƥʽ.*R>+T+%)VZzfֿETҸټǘ(J %"PR GBv)b Ga@rh$5\ZZ7c,fEe6.p]}۶JmIdn|K;%J*w[[QeWnwvzE;_g }{9ʒYW{1Y#Ds&퓧ɶLze-yegܐPж6+4YQ#n#$$ڱ1`LFpyR&wU=($cbrnS{o| WD_-ZhISAuuYUSյ}o)v]r=^z&gk:SʡDޘpg  ?XA*qRM+4)$CZIw@@TnY"qXZUy‚Ca[Ր>h>eihmmVHeˮ)>PӅ:(_ZKM%p!r CHIMaU't\ P>B@Y=ǁ|lOlfIzfY*v(EZai%} p^U[̐ArA!SE~ҧrjN x;'eq&[<[8-aK]+矤q_.Ka2GɰL# a@^z{`iZ$:^g S5J% *Y?r}*ە'6`.{rdàIBҗ6XrOE=^.EAvEd#iSXc_90;Ca{i~t x?]p|e}~y;Usw}Ξ|8ڛ[-Iv}bE4StY\#l"=}L_[*WlWz4+UC*d]D,;IɮI-&M|0\"(d Yя:*:0^ķOnޝ 88I|NT1 zu#[Q%D7 ;tTL9C=Mt̛7=0&.v+\6G 9̆ln'6w$ǝE RGЖ]tPDԗY*> stream xZn8}WQjwIonxv"Pd:H.MӯߡH٢`5g8j4AɓNeU\y;ݟ=(Kξ~}0bQ=4=<.\c,g"*X!%2e<+6|ǃ Jx0&!\L:~l818Q?/Bտţ\,yץi9WE43s2Z=o[E>"N1@(!R\aHN` G c~l[,_#uE'Dqk3K3"( 03Ba~53XZUƅML~ԓq"aSs=q^ iC VaL"!Ldۧ/L'gc)[ ȐҎ6SS+Dž1 $9Ý`N zC0GRi:>]"^lЍ 27({E7}y͇犄vP,YB@= "cd~HgdhMg Q657j&M¾$sh?Y5LK+#pב_.nu~sҙ+@#}(5zmi4|V=u .~ =8`m֠8]čP=l 13\_82i\-‚ĕy*Mͣf hZQiؐa`$$buQv<.kۈ[j[oXֆU^nxeꥻQ?+SEVľv}AqmXȩpKQh_.DFՅjk^d^g?J;m6ղLc?![CVB"2jb$yjsmb~Q7f [OEUvNFEi5^:*˟ s\ L^2=8D{<3%젺XɛSb.U Md%4x?*<! endstream endobj 1477 0 obj << /Length 2274 /Filter /FlateDecode >> stream xYKs8WHUE|음<رrdV">6 h'@n̽{{82'Iݬ,I4, ُXX4}ݾ]W55./EQ4H䗛/'e"翸<<Ν,R̶ '9!C,K|*eE]_li Y-Ah)@LOZy'9A bfI-x |)~ LY9rA#|~ ,^ e Ao*Bc&d3.{*Lѓ>cE8Ul wȵu[>?ޗum}nY*7p2 `(G^.tg<:!r/Ŷr*< L! }?5-~wrw'iܬ/Ebwpp z&|^|cX1~^.IUe+˦^U:gA]Q,>6t:z($"cQJt5ߨƻ舣ΧV"QǠlVȄn1v0PmJ/rJ^KM7Z4"X| 8l^,vÿ4QiS>|0dy%|uuv-U5dV*ҕ'z`^c573a),bf呵I! x~$a ^ХEzn:P'I Zc$5Ep!˃IM\QX gjej 'HEԑu^ۇaӮr#KU1 ;P᎘ӕJ8X1UC7:C[)vkԉN0׺midobSVi%1(: <>kͺZe؄&-Zm V*~ly_(fɦ .wRIv=q$Y*QYۿ (%{:@P,aYQo"R fT7"m sh{STQrq7&d]n0Nj"ؚx 'wQa*q)}*@@W%;z5}3.tq?h˨t´`jQVR!Ԫo.E?MWRѐ3mg)4""Ѵ5f)UC Zj:ݶV`lЭij5B)6m!.'6ĜP-ՑirXg$v ѝ$t3R<5ڿ!if37u0o3^ `ġV`:e *bIAs?"Rgv.pvs(!4 %T5Agt NC+R&bh&tcjƖm 7 :ZTHgnSaHS#K;boN eU2?#2G!fHx#V#)u˒*de*wdU=h>vB&LEiƇC96Da L_8l6I)@U`LvZ֍NFS;;tTuEjL6XF֚j(ue$88&O&8oL]?'H퐜*eZnp%Pp2i6U7eV/7w[b*-/8lv]R\P34)ԙnDt)v͠6;f-g{%rēĄ'vpU\*JL$:bIjh먟qFnUǔx:Ӛݨb> stream xZ[o8~ϯУ ")-4-2۴i`30%GͯËn`%s΅T`ů_s(uKqmB3Ĉ iMשΨOQYVIW kCZ|ʜh}o7#7'r0"ΔԹrQ~Z3픲IXkYbJȤԚ5,G5.\h<‚; L!!‰ea\\Br"Js=d$6rD=Y׋q bn0Zʲ'RK; _Md Po.J GgUȮmLN=rq`r!eș<B ^0E%<㛼`4-+{>YIaٗ|W2\P>yzaC0O3+ى"Ge6IM_*1YN]<ɋ'[y!4,lI7T07 {s<8>)  yrs&R_eUEP}J$Lk! p= xṪ!7xy#`".3~CJKo(}EU۳GFu%^GxY] ]NIJT  eHxO+q'o?Iݗ= tfy 2D||Ul74yÆbD(;+QP*цvJ(ۛ>M{ݾ q__J |Jn? 6\74M[D< [oÌRUȓC9p=?g8ttunq~${;}/%+F6LampG>Df:YL endstream endobj 1494 0 obj << /Length 2386 /Filter /FlateDecode >> stream xZs8_]5JB&^fIbl9>)s/bg `]\91&%ɧlƈr*f ^A>3R6 pQ>%dR(,V `a &-qbH-N[BE:hs=#q QA*Z .A L M-% ;xʖR[CaL"xũPfo3(N2L?_*%#q% &CFr H@R\X8H YʴxƵUwS'vu&0:xy|x<"6!$`5Z~J`.GƱTUyĸWU7QT>xG܂J4@ DSɇl1zB$<<[Cv*)!(\92q.ʭ̣r#/aݰ&B8Q.|S@0ʲ 5˨(| VR8 wz /g*a%(>Txo.۔ȶ`URݞt vUYo]g<f) FV5\hjBHp6hG.Ga) Fd *Hrޕd*k43盛w"_JEҦ%daRF#J ,KB9 _hi!Vp#RF&0N)֢YM tG +'$F$H$K M;iˣh[ƀov ueЏCYq Pc}+ƺ݊9QW#5A$<6GC&6` e *sj̋׹vSp&Q]@AW5xPUnJ \__$ oOsQ@MMs/ 6&:ޣ jPԨaͅ(!cq<@˧l6Puh([{UKuLWYbf!!$y,`-gSM.E~0RգhUWq4D찦E6%7ijM1oWwy]x+Uwedk((Z,p!8V'B :#!sw߻)~ᰊwq%nou\+ROS&">CjS/analH!`TxNUZZ)ENhUr 4(I q4 =0@<`dз3 )|l_W72hցazP'ZQXgMQqZlekGݺVJ D]ޱ*h`#?0 &qN RJ绻{EvҎ(ۜҩmvX,d(&?:OdjQ[*{ޔ&L 8agl\RMc\;=taU,ے޲%$KȶMmidbd=Bc]UVyfzA{'(TbLJi0k@ln xijZUY ]'(ٝ;H<|@97{9āt+Sv"#B3nF5985`=ƦK'YQ$Z e4mNKtgi1Ӹ]EDlCl~m[ $^t)LBY}nZn<%O^ˇ2•K 2p^h=xHXk)e뻹r*4 CGĀg-!j.g5F?]A{/w5(d(A[PA߽mB e"^rJ@]HwtrJ0fA`BJ3@c#L yhlviߜ-baZFd4ZgCYjZe!:o/G>=6|Q=6"jtZk`l,RSGĬBJSxy#s-&W-N0Yf> stream xXKs6WH &w{ڎcdh5H)QKL/ow?{FNG (yә0 TD$4|oӏq`_3{BcB<:jgft<"{(KoKG#ʥC vyQaYvY- 3:܏x+]ecY+rBF"$,2RxEODX/Pi\2D8C)Lhj- +$hWZܡQDZyO+ #,6|W,S> &*c?n<+8Kui\ lES̎86l!e3d۸U] Er2+: Y-# ɰ)'D1DqN[>]WHS?ޔ՞:K:`褮t :Iѳzx݁bPnG$:0ƒdKGGߌp$ H(V> B쟜_ Qwy]y?E6˫CߌvmG$ .N?k- _1fF8č\鱶sꏋ \[}b F؏(_j||>vAesNtׅN,wdƍPQ N$D +*tkώ #N0tQ?/VBU)c9WYXY^;$6ŊvЭ[z5}*rCB^NrImiM(n޸mF:@  c?{Zhmhk6-7g+)LX܄v2r~gw7%7mCvAp>&EҜzJ-e(jҪnE|mĪ] z|%yf*KӀ 9@"O@3(Puv$e1-"壞\g˴dA}ܽ jUƚ^?UnJ) 'qYh Y=)!I>fVM7q{u@̳?AK .l%rIX8ލ N%3tI^ID%@9} a QDϸH*w]{J;tRH}LO:/i!jab'\@튎r ʁ:\ƁP`42h> stream xXKs6WHMf2Nи-iSw -J\Iieo߷ C}Rk8ޢT)hE1q%i>3bP8:; ?!!8 UNhðأ0HmLѬw1}Bsn Ƅ56E ^O̤ia/ɺ(EʽGg1gQQգ"Ojup@$ Fqfɓ~ `%>>|t_y1Sdd['a<|3P1dlx 2hiU%6p`x+S,1qBҘϦ ?$GV]ۍD s{NnaɌo].jgXSVBFB@󺌩ucEK/3ަarDpaّ* m# U'۠(|| XͱɛF" `#nj%dQ $X2]< %6UBw *~bj! !{5u% Jؓp  S'[}ܼ;\ Wc^~6|p @.^=~}onzn*1`@mk/rȥ S(a{@Q!q%ږϗ ~=Ëm=\tN;9Dά2b{3cu{[^RXwi{1(@pCOT:4{+a^תH H|u&J,Vs.|+R•;9 2C!T_ endstream endobj 1522 0 obj << /Length 1376 /Filter /FlateDecode >> stream xXKSHW(UyKl%!Q"+F2yHXl4$LHTJn"2R)EDq9f4:z1' wx97ɐ**)=ܽTчJ@{@] !Ձ~;~xmu !:]fYټBrW "I2 K"A4B$Q ŏ?k,*':CT!Cr?cwgjP}jbK;t 9HyBCJ$.;_$ɻ-ߏfï?Klkdub@Buwf&4.)]Tz!:b]۳ FAڒaLɮ7a4.fo$@$B>{k|ZEW|TuT7}} O+ /4c| 1xe<ޏFÖWPEo4aN+,璟Pt}Tx7ɎCx44n+-^0.L dzRBsB[m;8q%rK:z[g!g)NQO(RMETO/O%yp dC&U7ZWvս Zr5&lv qY3O~C?%PjZdL47͝Y["J0AT~6AkoCTuzG'MЉ3ˇRrIp$`۰/KC8ONcS<g endstream endobj 1439 0 obj << /Type /ObjStm /N 100 /First 978 /Length 1903 /Filter /FlateDecode >> stream xZߏ ~߿B,QHw-$A4a7lk~Ԏعwmr4}"Ǔki!\ Ou 5T-.hh,! z*~I#s H'Mn.V]$#7u5̯欹.RL(w S r'kTKa Ԛ; Sa5>%VBV|9 C& SJ"cԚP(aX a(WI47 5Uɡ(M a i& R6# N}LV,@@c0 #U{0?\10,q>75" ,ר bX`NHjVBK=PjQЊdz"[ФXXNU BXgB 9gL5 y<}/HRzjr9v5dn ]%$H)<К= /@\j A0eHў ,23]I3e*xPM<ܺuL1^Vɓbpy*}o_ë6$^_5`>m|yynC1 /n˟M]~^ }z_f?]ބW"ly"[l@C̍}x$^ٟ^^oyRܸuд,d (n'HĢ)T"uo۟9Cʋy])8q%ȴl |m@ iCkZ˶. /dۧyf)Gt/,+s+QA`ӔFLЗiۇ9+Lo㕓o{55mYWnŀPOכʻ :~КF\ּI(x8$%zq PB ;Sf(8(!Ƹ4FyCx0-sIVlgs[yH^LRnM;LR.iʵ`x]"6LLDAD-Z?$eڑ)p/>溹7^wznyϮأy\\N 4ډ +3(H7U5 ᣳrO֖򆻲D-uE4KӔK]$lOs_G"ɣxDTk'hD.S#:G96"Չ!JAVl8DZk뷌ӷ ?%eӷ)1 ]\9Cԍ[pAI\wBîq'c4ҸK;1أI@:MZju?FiMn~4zpa흚h>?tb1۠TTZ_tSXmOi~=C=MSuMS &*kQϡ,au%c ]lCYo*X"xvW!b:q T5hb[4Gǜx24e*8闃s*5Kf'((wT.rLNēײsrBC-De$iʔqJS9Ṭ[7cyHb:FuިSY\${G}t<ƻ#=#ly\Vet#@Tjv~蓌hb+)K/0^'oVmHr"dVZX4[Pj67]u-|ܣiO޼'Ě}Z3:Pj[$\<_FYi(ܢ*OSf'zAp2MTak8 endstream endobj 1530 0 obj << /Length 1646 /Filter /FlateDecode >> stream xYYs6~ׯ#5SuI&>4xh9HG\wA)rDf/vky{=m>F̛/=SExLgTiEXEqQ$Yj/Lz3$O3ɷ C쑭܋֓_wo=Xrq̸a''iy;Cwi.q9pq>%/j5 G4dB[ 2bD`%A JfROuS$ۆ` T-+ò+9  ;bD2Jn}.V ɒD}Pfmo#JҢ }_EB8r dH9$ UsH <eȶ($ oSo_8d%֥SՅ }i:w'jRy`#U\Vj?\U^a8v  %%'w1RDJ O7~?L! .:Pn׹!㚂ޑJKƥ1*&VQtYV})* 2<32WuFcdIAe;j쟿ywÄt[z>ԡW/iV66O[d(Œ"-b+[+/>ban譑 @;=(Ф6Qeý m{2'=Q'`!xޣNq# W/Z$um湇5fsgYwcOyiQ?+Mtá B==_itgiV9>]˖not)&L,pAȻdwc" .'0”mH "31:.e Ȫ4v$߹ȸzmh&Ffh2ӛV^< ixK`P9FH]jڐi- RU[Df MZoUtKBJ,1gF)AҦq(ƽ0 Z6k5$u eԀXTE~N<1x^יdcVɭ7@3Ttt;E\D&6N0&TKw]MPWIyoA )s{T4E` s+/YuE+']D=` .|ԁǡɰi je_ nc{rp,Le[MwB(ȄES_S^.E/-2YdᑤD5%8;c@")<סGRgcрalH>i#y0zfb,Ydg_oX(,`r8  A(;hP]{ǻ `}ePnqXe ,˛SI@@(fQnGap3iX(y`_HqbGC>yQ,T 5r0(" ?Ց 2PVW: [E>4XA?$y'Qiwn^d5vwtߗHN endstream endobj 1540 0 obj << /Length 1820 /Filter /FlateDecode >> stream xZYs6~ׯ#5!8ymԩرLs(Txu~}LJlL<p.`8y9m:z~"3]8>F9~HG2>2}0' Sy٬ZiIѷ!Aʝj vsF.\X:681BoCp]\Vy i~F*.:+%@`<oP2žp|C2`4F_,QM{d`l!=un!M'U:S4S̛'s#Jf8\ _{0Uyl&> !E( Í{߼puv-]4SZ ]scQbP^Ʊ.̢e tVk 0ez(J$!Rco?^ VkBEwYRG B>PީB.BhfLԟ8~<=:>?mL4C¾$AaTL`7XFiȮ (OZO`CC\kBgD*5&BxMXUZ$7Pԗ @ Gj. (1dDaڙ[e^y8ԆoU\]fAST;^Mfűڧn8Ks7D$@qokcf9PH*&i`G󸘙c) 8[WpȞ( Z0e:'d3h uLڢʿ T4R2RfHӻ}j)VҹlZMv3~X=H}G_ Nu+`ݡAhuЖ-J{ҌP`jLGQQTM>;鋅2k-SNM'm6JmƄCã<he6eo QqPXf0f7Oɷ] F}b;d:C%A:W<%ʜ:$:YV-nIa2 ?=|~x*@1ve4vRͺFQ}t3&}HLtoBI&ު4N@M\NKmJZnn[vvͧWeG ø]kGZzX !* fuc Yw8p`=~8!yރj[jGz*Rw4EPpg"!"V3.B <V53j'nyu{xH~fa=h?.5n _:ϱ ѐǃQB :KLBO."_iG{*+7Nʶ endstream endobj 1549 0 obj << /Length 2081 /Filter /FlateDecode >> stream xY[s۶~#5!T7M$Lӎ 'T\w RD۱=郆b7|]PY;Wr"tf+', '=gt> #Ihl+]YYlWG)PpTH=y9;r"i"yI7'~u8q\΍|PX\?j<>c>E:A7 "DntmkŎZ &Hx> x;!]2(+""+g͡ )x"TCɼ(*~+Ҧ2[Ҡ(ɹWXbbn<זyqWW⻅έ$xd_'@#|O1~o+Hp?4$B $_܊0d@T8A}xqշmbiujM4QU_]hzp"x= NOAp t7oO5<`!h )D~8}{y+_rxP}ZX%ln9F1m:5޼9m!'Hn}EʮE)3žo'bt>kw)K[ ! EH= ."يsQ,:ޡ}hqew,p#VDznY7D=OFF?2 H nτͭ\Y_f5hZj/.#KeL|4ڭ:di3N \6I>6 (|0@dqTBgsۣw;h 4PP- ʔTtC2kVGVrfAMHk^Ufl/#s/;(h84&^Ie[G*AϛJ'P3RJoV(tޓ'aB!pn WQ+{{G% q=j%"aO'rN}^QHGC( ^_[- bԿrY ͻq ӳ7.ط?qv~99;7q۞^D;9ʻ9̜NBk}3[ OXP%Ȱ[],iL=Dhaí򬹱++Pp"?#!!M_pjlhe1LlQn/5xmC^5Fc!rk(ᖸHs:t =-&=У"IQݶX(5N~h؄(}nb{'#Yx5"MKy+6`SG C1w1ϸ0/ TYmЕmL ]{v&sݬ6:| endstream endobj 1556 0 obj << /Length 2213 /Filter /FlateDecode >> stream xZmo_od碹˽n4 DʤNu}g&%z!~<3p绫o_+$Zw $:N4 oг?~ D2LObf<ÿCViv4`8&1?hw?$Mχ@*ADup{:=e1C8IHHi" - E"vϾi#ۅ$:: ,Xr8, D30NU:c*:4LpI“ \8C`D9H'4j "9p1:/> (#ZL8(04T(/N N 85'U r vMٰiC\7I d|0U@RH\IZ+"WGy71Hϻ =ڐClEf9hp̀,ʝ%TCAJשQo?x/oQU]p}Ze|lw5 UV4OvSe%~9!zm]GZlU HyxcDCWmh"{<2U}$@s4dړ ^p%N=xdL\L9l7 E?`fb$.8ңCe='M b86\[Íyvu4 5 /*w`Z͌wY:CC>}jkJx74ɶqA{w^KJD8JīuQ_6}:>2a U7HpꖽU8;XE_"[fXj/. ^ܖۙv9ռ,j׶Q.wܯBV.|SP6 @#殿W+[mܸ#zpү|}\l^W3aͿΘmvPڋpxpqZXbP{9r߾W8^ a0>dXDk;u(+B)*1^m}h _p$)(ܑY-P(~1dPA9+"yt)l d(:M }o+p)ʰ ^I\p^6DqX.:ߨ d@.0L12bLjp|)թtRxb/ۘ.KNjpqu>'8:<= \Iȸwn,3n3f\<zͦl^֮w7(~F~$M E;pCj慸Ynd*lm3Un>ܭOHJu2ۻ:l,8CIKLHۗIu9R{&NWY?[ۃC 7bcډRH> stream xڽZ[sH~U:}{8vbeS̔ E:~N_@ l >h\>tv?ͅǝB0grB8~H d|w9"1<*"z-WkI_|Rޓw!5 @N<vf0 燞tĸ"pnO>gC$ }y&ş#Z,# ==G"1#(V⧳ɷ˛յ> InN倰؍ A',ƬIǛ6|35EB@3Xġi2͓TΌ[2mzujB 7`snۜZ}8:֧T5: ǶUV A @N/ G۽cGisQ͇˷Ln2-LX ~Bd8XGGb Q!'D )8HPh8}>xGoeM;4fyk=nW_>|CE: (A4ӹY,~:Gk_{jo_88aɿ:vt}pH]uuh]=`jAD\V%ׁ#dF " .]^`ź>?'hX!#1Tt\^Ntͷ1"!SۈEka@&> CHX`q2X1Z㻏{ r iJqkTfGt@l0(A7 ECL헛 FwӋ@:R^ }_VYRs^e}yl+2 vp:>V$<:FGXpr 8[lUa8aҔ!p0ĹF  }rFɛ;~:FU+(΅?]w ?Jغkd^]phG*ŢRJI h>~Rݛ`@t7x&;Fu7$($嵌t߯lkC"> stream xXMsHWpe2ލr*X{uR.,F8~6`Dd rڃ kh^~ G [FOG.|Hɬ0򥴼"IidwM?ZLp qqz",4)G[lLG>l5}0bo,W ^XZ#lx\ŰK'5IZ>ػK5gsNP_M2[disPa,/]-s}-1Yr^}R9TZ{۠kXr(1,oU $ys4ڝC*Sb%cv.+!P={4RCX ~\|';g'i6 :[{dWBP,I(`&"_T%\NpVk0!.#&ޑ 0  Ac߇>:ӧ Ѿ^AS޽J`x d`a'Šyr_s:L,sܝ~q3Za}2T}:Ɖ'TDLAӳoxS$ LEƨEo&b 8vGgGNziaxH HJsA%*ەvuÍcy> stream xXKo8W(÷[GnEXt,-nw(RdNlgC"7o.oGs)Y01FJ N($mF4V{]k?"w g_G1Vۀ"A)(WSKT𣡜\3n͂?+$wFQ`o?0,O!aZ~i$t^ @E$" b)@m_xy^JF6/дtK1""%B:r:T\ю(R'`Q;D D4J|FcD)q15Ԕ B|jPg3}oLc NSS%aX/쵑={qfp/  #"{`} O{o>YGڵ,wk:oצt-kOEÈ1Z+s{U`wcZ6&YאpMuZץmخ}.zZhIDhr ƜCC]k KۊHDihAdU4^-0"JBeQx5ExMɂKTZc((A #Ւ`"v 1HLȁBlZIՇ> stream xZ[s8~Ԫ\^v6v4m҇ݶ!6=kpS0`ٗ#s}::`NBc1 m cNSOϹ@~(S] >#BP(<ճYciU<ŘV$ɒTz4kKsyXF0qц`8)ߧ %n5n#*^|2Dm͢|v4?"ܙ_EdtQŞҗtO+.HCA}8IWo7߽Sצ)jDe\D p74W,-Wt_?FXDeq4sJG95V$$|1Nrv~ gQ JB)yc M%BLy/JoT%F!92&܋(˕4nD_IzZ ia1#U!ဢEbՈޤMhr)BrkXz Ǚ!˜rvHe7é "n "C5|ۚcA8BrfqPV$-ICPFv!BjFgafs%F nnj=ڏG3M}:VYmS¡*k|?Vkm~3H1J |L{ahr<̎FrqLCtѤUuʹ]uӷCȨiu5;׬1ƿ:ۿ]Q? q\X0ΏOj߯t"]ͪUZu֍~u®{UV:ݡm_jvv=W^Z#ңqt&\؉2h֪ú=~%vs.ź#Ξ*ƳCU@gN셡yL 15bOScWV5 ۷m{~tcD-$g^/-Z < 2#1լM Ö#BU ': ~tXg! ;`4w[ŵG$O^"jȱ",8{aFh k4@BB}ßrl)I| ΣӺ0'z<|^,6O6)3 p?wY& x<"j`ͻtwmgfd>i×LǓC.5Xc"'ƙҊ!v3on}LCNvf@Ej? j@'x<MΟ>\=|~}nXmx`?4ҭq# ΎbM!+| SAX0ϡ9qLG xVghN>##蒓Q7͋ b kn,K30UﴱT,>Ua9&˻8VEh_5wXaF|vA)H.:N,*l7e!y`I3 endstream endobj 1593 0 obj << /Length 1958 /Filter /FlateDecode >> stream xZ[s8~ϯўU]ۦ6MSw:xcfmH 4M]-L Cb[sst$έW''.(<玏QyRg~B`;d!P@]g: ;3 ^\9.at>?V{و#ʆ#1|6.|MN+6(D(Έr뫉~ce$-[UWv8M#BP=%N 1E0cVaR'i:}#}Ƶ/u#o&cãA4TjS Ucmt+}0L< "y+?ϗmn XD¢{mũT{vC1gD]( j5.dEu"&"Iؐq6sWlxۼLܦ3IC̢|7nG߈:S5JYm΍UW-R'TLu 4gip~e\y]ts|v̆EAGzTfD{DmؚA  ĸV3 Cdp\*Ur赀f\~|F}pçQY![Uj>C [ZVNN)ៜ4p麀S.R$mZZVd~,:igEe5VpR'+7Hʅ iJ\r)ω9\JądPZR-,Of˹@<-7X"2 d{Ogج]RXh!Rzwn%\4C6>^A|5 Zk8ѹєڶ,F,`f[2;Qdl%M 4N!z4~ToMG*7a CCװXpDf >ư⹹^k3n&".EV.gfo N*lz+6!qvj G4U=fCηy^ d=a;2x|3KӴj5[w YG˝m!bm>/@=KfBOP!6> Q iӺjX'+[HC27pXֲ}p#%CL 0\_ 83jH`Q8>ĝ!kH<_8#5j/U x~a K[mD8\_zyn؁[`??`Gvs.}ԖlqhvF/#ٞ@4Kg,d⌁˜:#COHFZ Ɔ!,/[cŹt`{n-b4U_i ;/2d<܊qkb endstream endobj 1605 0 obj << /Length 1128 /Filter /FlateDecode >> stream xXKsH+(hS8lId1jHߞ&r܃-iBɇ٥$4MHL!""FFcrH~}"BIL{/:8 ޕQM0ޏz?z y)aKI $~dg&HaG'pe>>ޥ}$!#UhӦK9 r%@r~)/="VeQ.jGx tU-g3yɢțyK}ʐy6cױqRrk9& 呖^uF6pȹt Rwwz-M*ka_=,(CSfS __~] >v qfE@G2@D>c*o5MY=we״L"qܦ7JsT*טRl3n|*0窍YBDctĊam:(>402'HBY `t+ =:0*=7`D#i$*\(^)H|kGHmV8ZV]9O_BBY]/ɵ{ϖ>*O:oCNyJå琿B~Ҿ+m9*Y3t6fwu:q&S`r荐;;9?X?s_jϿW)"# ,+ )E1ӈGdp0d{.1@(~4z2itzYEt,|ev хM}=(d*7KCdv+زEcl!eyZ,⍋ϫ,g3PfdrR=$HcW*}5S!)rݗ?w:?"u"q,Xfp[3cped$(ܣOi2| )|5q;GI d8/n.> Q;ށ ؟ͻ ~uwyKUu;\8|.N 2! 914.HvAvb(>Xus&DM8_Qp>vȅA"x{cRR"E*K,]*k ,fik˃?G- endstream endobj 1614 0 obj << /Length 1585 /Filter /FlateDecode >> stream xYYsH~WU-%)gc\ ,ڿ~{ d>0Gt4ػfttr!HJM^Q(DIMgާ1Gğ ؎γubv2}qΐGLb4{`Bqĸ&nGFEԒ ܂Ÿӭ*o-ܧxH~1!;7o[ E&&FΦ/ ާ˴͠ 2/ sBt<iEH[HEX(jk'om&S~M )&j`- $.Ѥ7HRDd!hyrL( 6v/X\.ss0q^R>l>oZOrfvhߒraGUh4tsXǖ*U^h&\8pN:SE$a}@Y(Ųy&uVqܢCz+^2^Ia`I-U2"!\Gezf֒A`+N.\".:zJg*MV>`OAooؠZXJɋk g @[*?ښxnbVv!ޯN$d斩7(ҚZnӸ(=wi=*)w׿j D}Y>@ũ4W*-ӲwGU<--&r@CZ ,kqPj'  A Bh&4tXK솄&#aR Q2D)PHamK0ͲJ elA[:ɶ $u޶/"Ng+U_Oי'.Vg.@Qi~[?):qB#mיD)lCKp(TD/9 pEG6n67젮:U6'; 1 ֜=e=X,ڼk7$xUC=Bө[K8Yy;I{EkS3?o⃡HPP L,`U )lk@}vs+ǟVnyw<($.+rCAv_Ѷ*s,zaV?;xm;g`Uz8敇Ө3/&RNu@tE) ~!=+stsm(p _5qVG#кHJuާn1MyfP=E=n#QoexUd } 0elw_ ǵ[ֆ]V:`׺QJ_Y=V@I+C;)\pOڡU|83 ojؿC(9/huH+4 $ˀo+nWs7Uf {c_ endstream endobj 1526 0 obj << /Type /ObjStm /N 100 /First 975 /Length 1845 /Filter /FlateDecode >> stream xZo7 ~_E%ۀ bbCܥGNڞK=$QL 8TM(.JeA.1!9I!8q1V' J#6j1*tA%)&lhz!r3f\Nkg&V C*M]bhl֑4-V3DXsmXFD)f'cԈ)7R0 $1.1.51(̀RNfܚ$6 A6VӶd).XM3 S) Z0 SDeHܦP9غa{bHX٢LZ]7X%HQ 1RȐ1SV qAF*dDWHŎ  h߂k}k+ V'`#"SEORA)k2*&#W@YdJeB|G٭$jA cWH*oSDW1EHa}JjWHlI-5d`+O[x"JMDQу=xƏKop?3iseO DmH ,a{[ 3Ç[S7~?ެ2KhW-bXɗ7@7Ls7+ K(=].3`4>w/\^̻6Gx>fSjf =H\@L Es|tG?&_:MBW4传M&ʲi 9oc#wڪosϿa#5O/ܟW,?ٟ/ߞ/gg'{ʹg4 LSFSa`)44in17O!O\J!'{)iB F;%hosا\bEeF+9_}Wgg0}1E4tM9|_bgJaX kgqua^(뤫Y 2 ReR fwq0r8T?eOX7J]o1]Gۥ0S`b ú5hqv}(E[]Ֆmœ%e{Xm eږ&6J< ov͛0S@+3PsNycP;IHiR'Mi"wK>} V1ϵ%@]Zۃa`;e 8BIau&Qɔκܾ)eY(>Q2f߿ @V=di؆ԥ;yu)i(sUgᐆ6ڭ޳u^=(gY}`XBgqe@Tu'_삷aȡ U EF=9Fy}9Uq`9s-{MܜpNBM!͹Ҝ3zS R!ܤb]QW, ۖFˏgD7Rn.a*sBiGՠfytN* {m;83?v=JG SY˧u70{9G9g[ٛnb6i>M:4)W^;Y,B2k9Ok44rHu~x3/7c{x|#–d"EnvJ"W}`Q<iq8oX`?*n]y{ endstream endobj 1621 0 obj << /Length 863 /Filter /FlateDecode >> stream xڕUKs:Wh)B%0Q2СC^`VG R~=#MJ6$w#QQvrxFpԐeUhA5%MUzYu>cγwpV~04,/6SI=+/.׋ Ϧ!MQ[|JQw%A^s(s}Z,q>gM:e1˙ާE;7n:yݪ"͋:HEu׳]Vl7֚<[9v$(G|@UޙnI rRPӦƾiJh0se6A,Dı*4w} pnm\5[g ʩ.HԶfQ/@^2t }t}8)+bisrqq+ _%{9BVXٛFK`RQLZ66,y82)o3n+]"}&Q{ +#>QAq}|̨#-tRuI9Z=aHvsݓuxT| q[)v ܻ^Ww$W yKzqM Z'PZc.B$v:O_3<0S@.8 7}{W_q'oQi.x%5 Ü[hxAXӜRг'`oƀ*~5]]e9}k嶣'>1 d5"E]q` H UZ0@izDRG9eM endstream endobj 1627 0 obj << /Length 2081 /Filter /FlateDecode >> stream xڽsFWf}Wl&h-@q{܁A 9/ݽ;a_o nȓYȕr<$ RǵOwo: ,Lbp|}6{9Ca \*TFlJ"rk:77 #Sq%,n>`c5FT[u1}p rrOU;+,+EvZ\XF, ,0a"ɀa1"KKT.qr`thq{l& :XS$T4j57rIW6Y]" _Xu !O5Y_60r?k}Յ.`n0 gO413d$d")G\ C"$tC80\֕_O86Ȕi& Il7YkS"X_FrryR&7uԵNhͥ#aI|2ܑzRpN]%0RJzTçmH(HB0eQwxWq0PMr3(cMqS1 C|rg U:$yBh;5I fjikYM 260 /C7J $b Q8|X0PlOO8kIn_3v V.) Ѣ0|mAV&:ac&wF蒤]oS"<E($ WRW<%D@.:9C0\/ϛp}YK&Z+1_C:*{Q>g  cG=[syu~a껓`Me+hTؼHԑ*޸WlDaܗzw= e( i++YLc-2.Nn&c|4(" ͬ?%,QF'M/Vw5Jt+dV0NT3g  HMtfJNKjھu:&nU&s#3ksӷ_!wq،a q,F @(5pfW Ӌ=  In5N6KSxq\.ZDw"('0]H1#R#ܢ9 ۻdbatT7z;6ƿˏgݸɪANNz= B2'dNGK1G9ID)Lf+ro0\o\Q>dUppGU ϗi0f5<ʭcu&j|  [T8ЇL~%#|G:@!U@Q#}:TMEѫ؜cSYωLՁ%$[A7!0Im(_$RݬTPkI8hnDiCݛw.(\Qn>ozW/ :Ky5RP CM8aNQ]y;h |׭=BG *ge:3 {f0`ǾTɤ$MVuȊ+w !jQ@Hx2M8l jnA=q*P6o(2(ב?7y\٨4*HYoU{ $ mnã:0m~\:7?+UeU1ęGĠSbh<~j8&RpyYB4ֻKgB /? $oN$ RZ7 $)Q=;M&D endstream endobj 1633 0 obj << /Length 973 /Filter /FlateDecode >> stream xWr6+$B;3IĉML!!STp ʢ$+l}s/.Gr-28RiRHG +)~^B\ ,(ڧYpδ ~/fm:"wg,f_gDw`Jֳ JW`osX gcffI0[׊b#۷!A\k[24Zzȓy9jƠ(40J!HAJr)13Xse$; %s.6XDcɢV a*.*V;!^$"˝&uѭ&MY^q_vM:0z@_ܱ 6C' r<,7kBuota&x Uc_r*kz;U"|0SZa&߹Pb!XwSX/3;?޵Ձ&OVmIIS^Mj=bPh&2< 3B-e8PI6ס!˛34_d4Ƈ4g6/=g13 $ Ϯ0Xi5fP@ Np CQOmH/ޑx߁Opg@x,֞7nnϹ]ϼb٭#냷aPCxvF>> #K '-mRivw`~=1HSě"W~81n9 i0nzڎ56|CYEjЖOcW/rpCc_ Ì~XbbK=h=oa)!$HW}9X_S[%P|yVv0jcljlu7H&G qT'{nN\*KL+6SJx" m6mm) Nm endstream endobj 1648 0 obj << /Length 1005 /Filter /FlateDecode >> stream xV[o6~ aXuXʴ-LZ^ڮdذŢsswu ߟG$A"$Z"Q"e$@h&NgT%~X(E 'jh&14 Uu^)MnʦU E)!bPS*8b|y;[VׅaJ*cHQ?Z,1mqJqY1'o"DE3V)S*t0zτײ3 Q VlWd3 'cv"&Llwd`MfrEWuWkI*ks K n66 $hʓ:| ǟS(i–yzvҎ ؍#F\~^m>j32Vg`x)Z{nf;}jcY6yY&or>{n2 5>&/tW!*\N Ӟ%">ȫ{ڷ#ꧥu Of$@֖9I8mI27_eiIA_GΜ:Gn;h.^^ Pp!00}e´oߍ3$oᶺ!LIkb0!Ss]p!&7_"${s {m!ix׻ ſ` endstream endobj 1672 0 obj << /Length 929 /Filter /FlateDecode >> stream xڝVnJ}Wt^aUJݴR#5F\lB`س^k߆ "ltUpHJfkD*XhB_$Sz_eәMgv6= `8-w_wD0BX ^Htt7"a+nq L1!OhM|&i#vqB&Yb8)@  TIf$,uR,%:̧{74¡8E/z3p]U?y&ɱ:ҨK~ ,AD\ ޛ}C*>56q*m1+Sӯ6|0VB$饙'ٰl3zVB.IMw-E>UB6Õ DyeU%Xc +΋wΥh6۶eꍼ2ۤuPx3rR?!nntٷfBi^}J} nv(X T'pjI[=^&ˆCYC߱6ٹ_~g<^%2VūWQiw}Y̶n3D }1q:e ͧ{! .t|[P2JWw +?m֒%lG۲]RXXvWgD73G@*,cdQ@^y;5z.e\!hl POD ;!QlW! 7 恑N!.S$<ԁ s1Gev!G {3"[eG)T^'\tv9>uO|ꮧS%y_co`\HlH}l]K牧"AIv endstream endobj 1698 0 obj << /Length 922 /Filter /FlateDecode >> stream xڭVn8}W In@oP%& D5m~I%W&mL3gf nff0l@` 1ؖ6`kw?a͏nc6 eϟ]Q[^\Ř4 ?o߯nW+m#G[i SBAq\~FwQA( >W`Y31 i1Aq\T^hEtPƿkL@`idsw qQ[:lsܞ:%[Fƀ$L 4hXy}{[^ZP; gVJ@:i,|So:8^?oj JkwO p|3nYf ec\zoO{w\?S]jL*{vƖJx~L֡(Pˢv%/i2YTlJx:RV*%)ALR-<PA/3snF䚤S6sV;zy?&ͲW(}|.[cKX)T}޴zOoT>X*-i>3p*v~"r9)-FO-vF|^'CRbd`l/+6c@o`{ ZWϬݙ-Na,+vkntʣS誒Fal_ckcfCBk5횱8țC7L\ +/3#{.lޭ rp9̬YG`1Ed觖!q'jDn_$I&z2?h'`1!D[ 9caiAcL_,dq- g0d)6ސ$Ջ endstream endobj 1705 0 obj << /Length 901 /Filter /FlateDecode >> stream xڽWMS0Wh4B-驔tJNGJ\ qBa`hw{ݕΜS蔄 ( tb(؇\y 0L@Փ67ĝ,d/+2u:XnE.&~ҹF }%IIBҹpг0%&o-Eaw[6)&fJơxrk TWzrL qK*%M%tV׉dAUU퉰ٲ\ x;f ZW.J+L\.{2/]:ӹ( ?ͻjШ TiWoY X7?K{j[-Xcx[xjfE,EoU80ҿ䁧\H Z(d1GC$2CA&(/:d5_urkI^c˃0]󕱾dM,?*.8-L^& -`.]s0> .qϡD[3[K9yew趬f}_Z81ứzouf}On->êu֣ӘcX?HY.6紦e^~vji8k(g}sA7d>?$Yp=U{>w›z6S'[+64 P`7e""T0K>؂Li5og耭Z;GfaYw)|hK͆*m)o"~ RHBHJH`Y Xj ۻTN\jrY endstream endobj 1618 0 obj << /Type /ObjStm /N 100 /First 967 /Length 2552 /Filter /FlateDecode >> stream xZ]o }e>HQvH[` l7yh7 F5کʞ{nrݾؚuDRpA ^4D6hފn|i칻Rie  >2O{x r8v1O{ O6E!8{?8 ''LSK!@6$1&e{n,\b]a-Ȱi!Q`X(Qb"{̊%U@gCxN) DIJ°tRDt`)0HMF 0܁@>fESx+*L"BA}_zAEyEj8Osw=eL@q:l> j`p[62 ,"@9ߥ0ad#&Mً9,H{ zP⁘ikF~Hrk!;6JC=(FO`I)U4{nb4XѳgGgóg.nb N2ɭHl_PW6U ge^|1^/7Gxd^}Ãc;dе~igkJ9_|R~8}xmXyTɏY`r%Hڡ8y?~ƌ  ߞ~x/X lrrwH_gP*3m.y{a?hdϻ잿U d z-Ҩ }aWgˏ'o5QG 4)%Sv5.NhV<L a[d-s]W}[¼4S9#ž'AfdF7^Yfwua?:8kpV(#ƈek|n&m?_bD)vyQsy(Lq̎Wj/^m/Rˋubz= :`͢DNv$S5A:2*=6a7Q]\~;oe8$Ê4F>&Pۘ;=Pp>[Ov 잢{B%Gq1o/=}=ɲ]XϽ1\aVJQ3x[^HibEc=}D bHXYJ~+jqkhx4d!mVż?!ȼ8s7g2y=+++++뉨'jUuլך?D1#j1v >KZST?:N/= # l@sC_)*piKe?,%b?M&Z[cN4Tj^œ6˼p AI/ v&<`cMB{X&[hj.!t@71[|EҠlp:9kli!H+ѲJ骓F5RTih*f0dpۏlQLTneg{vCk24lƏwN޸bH Zl ԺL Ņ Ok l?{D-ASetЕZ#{O`n:,LmJ/6Wn~eFc`%uV?/ r;3O1X??!A{W9JJj}l?%Uܻ*Ҵ 3Ib/UQy)`WPl(Hw,ʨ0L [)-!{ endstream endobj 1729 0 obj << /Length 981 /Filter /FlateDecode >> stream xڵVn8}WQl}b7)jd]4HCIu"vg $h|]J8|4_$PK4L#CwD !Ϊ[,*&U.5%E.-(PIȧ87mh>2[Cݎ"#ﮂx4xYȌfmo`Yec`؀2l{#@֬>N4R[,D뾺W@G=UK]i礬n). >CcTuMf]VŅia2h20! %Xw-l3mWRylVuQ2|O zBO9ztPmVWkiCߋ#~f`gQulL/JD.S,z^g~;ԑ%QX^%px}"qhcS/Bͷ6EY֦m{mmF֋vh3/L&MŞ҅JZ>43Y4 $aO9@.#Xo>:Sm+[!: Ufv&ǔ3aD}W!']XVSQ=ˎ*SkQ[/75p'}ˏ W,E/F'ZHvjīKŦĪݴSwWgX҉` $ƌG 'w-4M:(T V6U{޴[f=C~ي;3I}_ݫe~k> stream xڽW[oJ~GemN+UԖCZ! k-,M~}g/8T~awfۙ-"j2L]9hA>!ncB6"dzp;`'~#ͩMw+ۨͪR+0KWl[Ĝz$+[y8~Q<\.? mhkT 3bekmڻ'Dv^ݲHe: J9[3YR\ۦ]SJ=#<%.zZӬLhteew i^.³6JtUeeQkcD*ålTAFְN[DPOEb;Wڶ֦ i2~zT =AV,R盬a<\]6 ( }@MJ/=!S'j*{iԼ!H|[ڴ&" /~U Q,2WW_~ e!@A?EҦF!ROø uBx;ҠaaoIA0 oM*oUz!`*,'30m1{4!Ok ӹ7r6&w9l>L>7QQ441ҁýKu<3C ٷXss$X,aMϏsu {j&u$}Ϡ|q(1=\͝2ArϨ3,!MGǀD~z>+(TCxӏyޢzVa\ɥ.ƅYE/*O}*<mઘ endstream endobj 1763 0 obj << /Length 921 /Filter /FlateDecode >> stream xڵVMs0+t[έ_L=4{J3 eG8 q;ۧ+#c% QQ 'Q⁏#St2̼'jĕͪPˢ(e:Q]5̣MOnn qwRkO'e *QL|sKzt_mÔ|,aE#&O]1xC u\VʒWw@@j$c Z[B7=km 0,Eì*ږT˯u[ki+KC;uţRu%≧E9oP8C*bϤT=Ulsj t.xYm c+a=3[V|k7GeYTfB`5Xs Q׆ Wfm+3] lxf 'ðrۺ_y&'j4G4d8}~%u2GSi{nҬ>?!r endstream endobj 1782 0 obj << /Length 1042 /Filter /FlateDecode >> stream xVYo8~ ):lRX hZD[p$j!E>4S!93|s"zjvq$ }ڢ8 Qx8h;GǑz}ɻΝ{Q\6i_ZrY4z;k5QxJM1A}DI ,P.Jȫ0qb)ԝSBӹ9 O]8{*b(ID2C܇]EC05n/EApx˫}SUM^.? DE)a+!(3#dBuQ5iS]ߺ8XH'nk'(^|SHzCa( HPp& r»gy\\˼U)}#E-_~f²oߢm KH5<inyQ9xP!iEZ(R#*c}ڔ6Zyl~,X9S`xΥB6C0tr>;e>Nާrʋ݉Zzm.Fb =>G4QAx8Jlz;|u7g,t~_A>wyQYɥ{w}s/:-L\X{jZ;;>+N~UpB)3amSP^ޗg+)ZQCO;Q5X'qߨQCʶبK>hON>nj|VtuJ14aFey |P+O@o?d³:h@=ұEH, .Wc1Ge\^o+y: XV ö[ f5 endstream endobj 1718 0 obj << /Type /ObjStm /N 100 /First 958 /Length 2377 /Filter /FlateDecode >> stream xZn}W1y!UE0ص$@8k?$kB_؎[H2ٯ)J㑧5M X}XwAم佋Nb1B]H. (X(len{ؕgK'N B[ $cI] o~$n׊d4xh!)fo nMnֳD,[.&6@lX 8Q *6CŎ(ؒP["J 119bSpt6ZhŕҠv1@)Qdi;M@M(丄hJN|68F&ֆ Fє!=:13>%'9إiKxƸC)l?)%8ͨm)ʄ4P[2*kN P@r3XJIg t5Ѩ;l5U`(m2%Jm 0J0mTaKFl <3hڮ{($8ŽYJ6BH1%WdpCLfZ\ 4¿a@+4 a\ܢW:5 =yrym~^m^~?T/_{xOCru`4SF)pgGۼt?l_mWW/~'R?/c)#>g}{g;n)Xkf>tA{4E{^3s`k`šĮW]F$^n?}..*10ub7(Of#"^pxA7[qKą[".+.+.ݮy!-ar*Hh+3uVc}BoY w eDT@-7hSaCkGHbki}AtŒ^+5\"<6ZoEءU: 4@<>VnjHCgGO{D[f?S8[ˍ2O 7GZy`cӫKF5 R(yz]eulg˄K;>h\!&Ѩ:{{@>S͈m3CX>};;Lje`~!.-][09-sD1/.yxSF8#:=2$>{N([nt֦Ah^ v}][ZiHqTd?C<dSUpֆ@PĖ uPdcw Pa_{P [OT4O$ EI_ù"] Flҳ gDӀM.e7Ԙ]E.lh+ʂdTPi} endstream endobj 1796 0 obj << /Length 978 /Filter /FlateDecode >> stream xWKs6WHΔ0|&g2LT'(X/]wAIv=>!nW7RGa9ǂ|ZNˉO^eslƴ{GUoaAayy0!(wGD0B̑KL P#JO1bpE%on,M9mTaqcX0ξ2&G&v<)!2b;@9ŌKLIqb1a ` 찳-6WE7GڴtL?ѝ*AѨs,މβR>t%ez/g8 [:㪂05> in\ qf WidV]Y79\lwd^0 _M;/]tȇ}e8})޶ԜNCBbz#M\&2ݚEqYO ^,ћC]+n5JKY:E !mQxZ4/ʧDiIDp #,$ BJo-M&QW e9>{"n:t! >4t0*/dĥ@:&h̓M}2ڥmiغOaDCm3][5^S&$֔1K٬$',OՁZy_!]:֟9sT74(Q> stream xW[O6~_/;sAUU 쮖ma*LR嶹@_\2 }@x;߹|666N'D5zcD (<m#&xqt5<ӡdUy]7˄Rl @i9}00r+Kå.?0f $6 8^E5%c^I~(6Ykjv}llLBr|Y2ƈlL<~"Ookn}Y'h޺!!?!gۦ[[$uRqxq:1.z5w\M]1#мk`h`*6w {TP+Cˊ%?i{X<.*)U!_cw2ώgO7Nw#Ĕ?yw9`9 CheW7l|jL? K^=ˋ$}K)p#8/qa 5k_GE:ͼ}50W5Am<p9.4G~2&oum1荭g]OS.Yţͤ^-ںFئ風ۼZ;&JG5~ :,|i%Q%tApM7#? bƞln(Tu}hMZ^KP miZQp$/4֥mgԨOr5'EF\L%{h`,F(ED[p]UOe(ιi&z!kjmi6B+f fm6 Suseq-*#(1uyMd/ؽ4F~m GPYJitDz GҠa<}W " 3.m> stream xڭUR0+Qd[~M')C!^t0(~K!%__ْ3+s__yp. @0}  GӃ6zN bڏEHZ?Щe#VH]H/-In<>!0g7Awes3ؓ`ظ7I QtclIYseS*@kz C ڼ] :z|Rw1..O|;^='mKT,kHEƗW4 th ˘SYYļq4.,fj 1wfVNuj -Afbs[ Mwؽ7Xc:y2bee" [{i+a^. I\;J'XK0"j嬏Dx(V慈XF-i$<-+qD]#\Y32W~]t$8! D ) OOg,n#XfNU}gm4_I Jm0Ҟ|9[#Lx > stream xWn6}W IdmS3DoȌ-T-$_M^"'&3E򜻒G[y8#}`K][AM RdS-ua^yg^<+YF%.T*=.Zm}|1-LG8йabL);2l-\*htu] = 4YQegOu`x}cXuh!Bqhh3b[LB# !WNM6m "DZAɺm,س0$v~HD30љȎ"H` <D93*(60ditK*nGQu'+h ΀*<~WºޗT+ !+(CEa[HDn[Q;:ZӭPTuJ'y\r4o4 0[H_ߥdgH_fLXO/ 4We>@|K.#A9C{9r_a$Xy PDWXˊ%BySll{\\7TNwgFeNNF/@}8zW:&GzLQN9uَr9(}WoF4{{#I6iͭ3{t @2]EQn^?moS6+{y"=`CG!y4.Qz~B@xNDPǑ/ɰYϯ<)U]' c-_4K#*x57C|T{'zt]z}ef endstream endobj 1788 0 obj << /Type /ObjStm /N 100 /First 962 /Length 2600 /Filter /FlateDecode >> stream xZ] }b]Q") 0n @!Mj4Mw@_C8^žeHGEJl-4֋&Ѧl@'P|o#6M8I>}< {ņ&az{:Rm/5:II bϰlM2)C 2C'E.fCs eY$Au }2lMplM!ň#^a>6-N9xN-ba併7InҔn}+)eJvgR|6)MYhpgʷ^u*/TB_qL‡G/g2t|.1?|w+bPYkz`1e FQ)ch{$q, Jt|7o_=M鮏XJ9g'trryng/OǧuOcËv8~͵ ǯ嫫]߆׶?iz E`x;7_cvO/..鳩i v!B.߅f:7<?ZU;Ϩ?Qd'$pvA\ O <|z9ap}sjO y~y˗ϟ?,',$1zr lf|ۿ曟_<|0,$!(Xyvh8OBՏϟNNϵ$?6Sh%oKJ,mYj=XCggG N}hOo |^Wn#}B~oO6YΈ ruHH10`W|ȭ&3qӺ-RVȬg΂m-s+BM9.BQpi|>Zߌj4X*,APhp'hSd_RY)ڕTN7iJ< &1Xޘ.cc L:س)kpT- 낄1e8hf"s*U vY3GqVq:G`8?{'q{`q(R 7J%uvVvYy'.]ȻpGfh.{%T7P{!u˪yea s-rUYc*kR#V^2Y1"E+Ch!)uc✶O`AEWʯQJc: |,7ͫ 3J+xVlWZ5sr+A(ny!EcKr\B/L _; AVkeKsAptz ֪U$6L6Fop[沐Qے,9Ұ  l[y+&9[x00HvH (3Q5UҺ9MIKmY3 WFV ry^r9^C"Z܄ַ ;.~|_pR]Iw'uU8TRDXSN2>?<- Ԩؤٟ_N)31efǃ!e~AIϩl-@ *w/.WΆ>\ׄo+?\ysL#:028H8'}TP (=UZwrrRig;DK*kŠ28Eܣ+YXߧldUXv0*^Kcٍ*xh .}>xvI^ǽڏ{ϼ __gH8F)oܷ8;[;od~Dʫ6̩-অx+PċK p01VX`U<!mcYkM9+Dqa ػ>䉑a7a԰(xbP*gz[|J-pۊ4\m%M՟mh* Ʌq/k$uV(=-Ѩs aTҚ௔6T =9 . k4ر`[m+k0j[gQQ}EW9ޓ׶bopmFti#=3ҿlѬ6"Q5f(W} m^Y"MtfcnFo*ZȡL Psް! 'Gy8>52J΍. Xu} [m@]":n endstream endobj 1872 0 obj << /Length 589 /Filter /FlateDecode >> stream xŕ]s0I/z]jg!2(j PXq?ԩWyyA` tD@D@ (9"$cec'Be]xZDMR'uaRDy74L [&lwws`NJBAuoHͻ+`J-m X: T1Dc 1Btم`@P !JS)U*|n29r8^!D<#I{]44c*LתA_=b%qIPF0E0Ux*&Ӑ]Le&JTWvTR=l1+FgӶQٶ,f…u\"o0̦}˳t18##3>|"!#ڛƺ:t.xڬ<5glև~ϔՄK+> stream xVn0+xI[zhbݒP$ KDIC-:mS$@L3o,&AKDЙ1vfGR(CPJ"%Eq\IP~*|Bsk]Uim/sP0% t\9"8B,׈ n(ܹpoi'2R0%O !n]۵]gT p{[6K_sQ立u^ON:.WquuDŽk/ySGkZѝ#Ll"Pfii^mj_p%qTWDBEe]Un_ }zLP h11nyXh|ܬQ</`9˴h3=liˡ.-v>ɭ]P#JM?r 36N> stream xŗ[O0),<ԵIiR)- $.@6$O@&99 B׈~Fۈ{9B Xس,LљѺn2u渆0/܋1l)/ahЙea2΢lמaR=!%ԬSBg/ŷQ"{GcOLFj*zHa(/MJ x" #{ M`qLm ؁*^aɜGŽCnXv 6Hd_f$.  D%\x|pY悅q9ʵQTٯ;ѱGT`uP஻19J>hn&^&D٨an |0i }20mĤԈi8zu V\,CsB(oqxqxj@0!4Q]NoVXJygR;WڐǦFڼ_1թJ&n-cyv4;KdRnM=,sXwIĖ[;SٳX4) NAJp{ao ̓yxwN8aC.S-r8>g{Ser+~~Kス 0I?lI@ACs0M9ZMv á/ UEnբPi@(T^A^/[B*СjA7?vPQLߔ9Ģh]4Dwp5s4o3G؏.6e,8OK/;\Jݔ ?Gޯ endstream endobj 1960 0 obj << /Length 1751 /Filter /FlateDecode >> stream x͚[o6+ ,`fy'5[ږ+I˲&w("&ڇ$D߹k{GFK~FZJOI%WۆeO7f~*|8]|ar#Frwػw/=1޿Yˏ or/(qVH )I^S*2e7mSjv1/ 2Κi^(vb_@T9PMo$@푣?$i'4'$h|6 I: N^#G'- }ҰG3Mq$@&N$YB'@\ x3|]E$h8 w " qmi'7RW~ 7%RIS[@Ԓ88"kI6U0\z!O( 06tnZ]m4MҨƭ0[hZ<,IpuX)oԍ#L84VmQp(nbRa &Ї}kv s܃jo糫`zt:8E2bzceQqQ g 7"؝[8T}6I:6n ;Ƒ|lq&3gϺTy DRd"m5A9U`޴M{|^42pIbS!˜ͨ5%ƂLa;GA(Q4=̧S"Dre@"'0$c!Ggq&.a8%ۦ T !WZH͌>xFx>ME *i d㝕V Лڇ0Ǥr ծD@H/MLaJ/Z&M21~5]^ ^Ŕ` 09Auawa>"¼`f*hvmoWrQӣٜYr- L,*(9ه޴@ +@#60 CZH/v%ͼ pV~y2kB]pJ^7X*(7xXN;NéܚKe4r~w 0j T<el˰hGgm< :t&ئN@ %Cd@ j c%Vqz7B>Dz%lOmNyMבTκrS|7qAvK`'i{|0 V3զSbfAˑo6<tǺQ@3&vT YUrIRhh%= .g@UKΖ{>U2{!9ؾ٭u3t:l(n_V \`J?j8Qpk㰠׍3Ҝlu pqÂqs<0O<8;L!>Ӣ6Ђ\U-/LB_:SE2^o=^.ϕފt)]ۗ   ~9nIӰ=u@hIBx)L 9MIBM1\3UŤX=jwku}j 6[ ."ڲ.)@ZqkL[n.JDY7&R.N^-ϧ3eY5" & endstream endobj 1868 0 obj << /Type /ObjStm /N 100 /First 965 /Length 3036 /Filter /FlateDecode >> stream xڵZkݶB/Z΃RaE:Ftw=]y8\///5<ΜyHd1 a1h(ay {/(? ,u U.0Y-!d.7 ֵO DdL\aBm),$)>8!T~@NE%}ߊJlEY._O:|-w2 LH10vĮ1. ?P&uWhXAڲѪ.?G[3%[90Fp+"Lأ ]2 JI6WXAʊDzR}_hQeUl1?uhPqWk"Wzm cr%uJ:Մ }%P,N1Kײ UpЩ`W;V`3!s#~ȉ`5Zp~Ո' \Lc nP늟+d1nC`T4 7#x塔հMU\\[mx<৆zォ돇4/:\_CG:k,/|y^ú8gtyhqs<(9+J̣ŜX` Ng\ G)QyH4pTXtL8hG~v{0p W`O_%ty owy{^ pYanuvuvn7f_]ovȿ_fOGgK7A_@~1'SEdy,*#>=HK#.jFI"Hf8?^9DKctPebE0z>cJrL4waZsp D/j?up]pss /#GO~gaɛ_]x{u_h-"ʸ&4Wԑ}pn3=|W][A< w@x(Awsjw{[>M'o^z~9Hvp-Ly;j3_"iFC%l d68m&OiII-34Z BZÛG.y:5LRPNHU!zPS5jmJGUKSmO鄄 V '2)XSAJ鹨e)5:nqk"uED))FIJNP=(#f,qZ'e!EZ rX8g6k;%O}:c(9r3󜳄LrT?UmwˁBF +MRe A >!H w9njejFT.k ܣdJ / 4P `yN r@ Aך?"ȤP6Š ԌmZR?#uMȭQtŹTt*RL9Z3`"CY+%,P,ܐE?pƴ>gc|?l t ִQY- `-9N(!3,'E5,ZrSiʵV 4MOZjal// &09"\"E%b @FF=͞r!J ݰ-kkZˮ @ qTJF &`qi9blN.˒4)"n&GoE*qOzז**<@'廾 *q&.5EؼIQpl)AtzOb|`<U_KC6muAx  -"!F)=<۔;k0E"SrRFU9#q/(C<ّ멖9&U AmX O8VSx^(Nm T Hd 9#}c5[riR-OuʸȚ>HQĞK%$g6f/Kִ>=v? n"ȅByr¬$HG#ؚ{w8tH^~>G5!X*U]LRnց{ endstream endobj 2087 0 obj << /Length 2015 /Filter /FlateDecode >> stream xZ[s~ЩS%U>`6r8Rp@>ɩGW`?f{zzzWۚ\)6FR$ ϦD*Q1{a ' }%hm8N~øoQlopeO"،Q܇aKה# ._d r?6Fu?ӑc g<2/pn!^+:6$MBHO3>i_*ݦtc|VnV-6/l5zMේR/XrTqc{_SFAR4JUzưT*9HdgVcQkr$D(+|ԯjpJ0Dk" \uoZSv+jkD(@T?L#1[M&U¹:Egcq0]з(wi%!$}kѰ n#ݦs~LKΙ㸈*/(%9ŰWN2RՈlě7w%\ u1񺏂ox`5"-ZGaAsD.+}o\E7W vGm7-ݰf9-Ibm}؆q ڮL$3N4P\uV+tm1.8,cvA1yAXW>\_NyWöEr56w:=sj; [kOaͯ{ڸc/3Q ʁH %1D57%Hd;)#C /XA{yt?`zk{s9żsa܈*fT7YN~¡prYj9T%*ju < sK 5'ɯ@~[P'?~hL&'#*~D|W ;?-8Qe2~Q4%څs*#Q۶ (X,K;g0mQ3}YJo475j*4f2h4"s!#Yy9e1TMJ?gI&) hbf[oMAd3(u)Ft`de(ޔX7gk3W*=vJQ{ a9 ڪh3Dn,0^yu2Iq (?aWPߕ"eDSEߧ}KExsHB!)9UhMwnA-yeZvB?~6_%.G4/A@+dEVH:>y%UR~≦ٝ4:3L>rYnсygoer;؎Q"#HqJ!Pw[^M :KJYt;O B< 㲥}'Qo[#7_zB~yW!to„Pھo"m$_Z#7 9V2dE% vO6;uuVկaUK¥iy͎.a)Y]t* 2=#jV{,iqJ7V6t 5wҩd1$]됅q[EtYXzu^=v+6e u8@9iosL6s@xV_;ϰ@"//_TLKZ&ʼbUx[?$gxCVKmCq endstream endobj 2012 0 obj << /Type /ObjStm /N 100 /First 1010 /Length 3313 /Filter /FlateDecode >> stream x[ko&7b>—}.HlU@ia+ǗMJ6+8PXH&b+YǏ9>K^O$k[j ^BdIssG~lT{?-hВ9.g_Z̡GRgs1| Sؕ07*.ؠy%g%V^0lD+"!7IjHud߀v -])Te>FE+-n^ 9/V-A| $x~tnM2623yledA|Kb4SKmXBJI\&Cϕcsp,t?ajΧ<´ 19,0cKjSN[=z2cofS9I0eEk$m:Uk^&V]$kŢO^\|r˫o7^Ϯ[!*.~qˋ_o{YĜYgf'5{sW'W_-.?wo|7_C^˾yҞB R53xO^sd[V@k2_w-`~o <'.5U<y@%U-` hZ*μf+cJjYK-ED%t-50h611)dMmp!(uF@D'}rf?ZZr?|x&DH889X/"pp0JtGaxE#RcX^H uX=",Ux v؋P\S,D)ut>@I= zW CiP k4J2 (~Xrhl\=QÆDz`X.ՍZq6 4,ḣS p9֞H35+lg@u .hA=)E" ~E5k4ы675NDպ|s6蚑Ϟ6!ij\[q*P٤ D@C>v eI,a$AAۨtgZK8$Sqm-$lxe*u-hpwgÙ (.3-{s5#Z oV qB3[nכ|{U.߾{iCq#D|: -tF0<|*!U|t#Z:—W~{uy"%3F;J'TTDZ}7?H+Bj % y`WjoN@^'{<dv4*ҰGHvvǎa E]݊P " cڼ[UDnW" tBZiX PB<x(]aWIV"'1x--Vؗ"#'ن3j|_ؑV8= j(Vg҉(w^lG٫3.:4?h*>ΡzMA[w0"[]#O^ ]*I)+m%mS+xl''׭ u4wF endstream endobj 2207 0 obj << /Length 2596 /Filter /FlateDecode >> stream x\[o8~ϯУ 9_;$` L;0\[M%cN~ʖ%٤d*Rv%<|J Gn~ZH##%D #-e EDwcOwF Ÿ_?J,ǛyHFtC~HZ#My4_}G߯ht59`HpgՇ+\JIΖyY g Hi (CZ탟(g^6Uq }x'x~C02cHv?;Jzz&G?a><5oxwA#2ݠH0I?`GFlVzz'ojiguy4y>"if8<At+6s;_,`Y~j   1J%e&%cg$9߂A~5fqIk`"$ܱ%4KIڎa_5e+RP ;)AlcJty.LZ)WHSƗ\* /)`mPVz7`ZXVYg`p+mxn`;;UA0ڰC+U yuXAH<V}pOa B{@7s`HҐQӓ}Q=HbmIoP TKHiR LU(KTU!cF n{y*kbUn=2o*wwA&Axc 2dz=uTN͸:?^YjeM|u6T҃ʇ2f?zO&KoX a:GQv碷 Pwk<*jw:R n3t1y5|;?G18ȅ{תU$+'&x4}v5A ;ǜؗZ޼ѫgfy=Cv-]ʐ2 > stream x[ێ}߯䥇 Y%@0:B#_Sጰ۳xwc͡؇bM!.t̺ h(T')Pkc5q5҉^H2ݠ;͵ƺDMRBM ˑ: ;Z#ʴ+ !E@gwP/Ᏸz R(^B\9KqڮtLu:x& 0\0l0r']P2( c$1NH.2 |t*QvD,:XAXu}%)GV]r2gBA$ڜˬ_dߣ.=u\EEEoDZ3)\0T<"c:LV## ZRJVW ])䚢KXF`R0TkEn𙍢(fsPq({Aq0g$Lɭ)BZVyǰ!#ն4ԶRmd8q` 1WH K&ƹauA5|zcM`^DopǨ0:Yw c`8ar1o=}n۷w7Wƻ7oyݼ:/oviױu!WBkϮH3}={^u?~yw_p՛_;ÐV g025O>Ny5_v.ޠw}s30}5H>[)XljQ̆Ga˱m@S08Whɓ'}"z_zky̌: -M/ǖ8$'Y 6{dzFtCDvLsZOL4ζ94_`C=:,lcbzAxE M@ʎd%qoMݻ_~|-_/wx*أf<$4QAA\E g!(vx?={dJ}7WMOj}KUՐR&Ur{ӫ Z)S(_Sԗ{S9}BEUEb#yPʘkpwVa(P$UT0q]Մzڭʂ>> +`_l [GhL]xѥ,œ UgZ.nWbhb!2?rBX>oς'ee t8ssd⧥GYɨWx-YkI t#EjlO/*#U9ł"0"״| n{E'6LdxǷTNd/쿩@ 踬:1Rf]bLvѷ~͎R҃> bwZ,viYœ#ϫ]2YH4]b=,!a+:`_@ ? ~Sr:"]''74haN@Iɯ^\s(+'>_#$90KOH6s0cCPz򂈮ܿO}G&O6S=> stream xY[oH~WX[&soin-]! -6&~xaiUiUs.߹ vvZSR2?r<|)/H?t>vz8 8Mrt(ijruADmb웉!?ʬzj&UJ""“+EkMߺi;d#r'>޽q0bܖ'g `=uZ["Uܫ =$s,2#O'O^9sS9D`x 30eڟHد1v/(|R_$7v'3ˁf/cYԓd 57Կ (NRI\')G>?Q`Di8$5D3,KEٽSKc/=P3?VnyQ'_j04N[pW*Rrss\$8>tϏ 4&y~o~Dd~˴†"Ζ9@()o a*8b\OͪmU=z1΍dSlY =s)WJ[''^OGQeH[ku|1PM6Y2*o|TfTYs=D|s`O9_Xx1+su(Ljj =9=7@O@@@U+һ$4V`#`>ƺ_tyj/{YO(XsLaZ9ktu/Œss,%M $ϙJTK+yJ6U\E endstream endobj 2254 0 obj << /Length 874 /Filter /FlateDecode >> stream xWn0}WX4%;djBņ-aV( e ؁@ ]+Mxs9>!MAJU-f";#`sd9:#trݸo þ|FV-[=I4"L,Ti7B$AthMOF-DFwy4`rGUkJQ? OZ{-RD]4ùfnpU[mY Yر͠ ې.G}5 a 9`-&0,quf a\ u9{率w gcFBS:ϲlo {},`lC^dG2eR.B%)C@UD, zӉTق0d׿5Yv۽\ˆ: ŠnpR5p8qƲEŒs6GHo 7ɶGv4F8l~h6E?(*@-CIE)$CsVH$O4۪4 (-3Kuڍm>A:b;lW3 ٺd!471/cjӛxaaj7% e۷}~s.cEk0Р^l# 8.v6[НM}mA+eDut)t'3z 7%V$x! v,"`ԩ(z^P]+ vp)]CYׄp1MIS}Oz ;WY<'o.\79'ŝFꥒs9Iū)Ș&K~H#)ծ01!G\hY&31*9 AyQgQVIFv?nU endstream endobj 2228 0 obj << /Type /ObjStm /N 100 /First 996 /Length 2555 /Filter /FlateDecode >> stream xZ[o~ׯcC΍$`nE0MT4PZYy8hv9v8r![qS sj0NP)ةE!SrJ vWs-P>(RBNa2s% k6 Tb5jBkTDŕ3(;;o@zyprz.÷MbQa8ڑ1I8<?8 /3\WD\Adljkǚ&^Scz8%pq*{q^\.|WWئ?qI{DC,gsTJ 7?zwCgJlm,8xuQL+)6 iU[lAC(<_'@E.*<C | y*ܚr7[j.Ԇg(w " _v0 C+j`;aK17}c5;'F{ҾNɤScRZgiNelNexuON/~*YOgvDwm ?]ó?Ͼx//˟gws^^xwtq|Z.ne~=|vcNKF*pKφs[RD݈]k"omo\mox,fnmDوd$&Y6ɲI+/V6#Et{FJqhwSiMT4#>*}oj#}v,-k(&bKʏoɊiQ2,6˽8UΩ-еUԔ- kY mZ$JG܇y~^o˹7ѿ<]~y!W8y]!{3˽@iؼItL#:x{bk5ޖj.ctDDg9ߋ}\ZRc$L)upD_rLVB>T+Ԣdz5"`5È(!-)rnU[~ F5 ]rܲLOeXiǽ3EukĖcګwFB[l^lk *j}6ljhe:;@f}]iҵyi5sN5yo+|~F(wE1dӷTdȰ]NEE-Wc}]4J-ӂJTiTZU޴tR?5n꟬F9pK}]ӈь5-S6ͭ?ȭFEQ3݅˘WsHuۘR=xk";w V1+Ioql!ZJ^ +Ky`xg/Xed2?+xc;d讦w7^of?3ژ-,뚚*75~mSӿ9j>f-#8y,ɿeh/Ŗ)PRm2 1CE"zX`xl7Eۃona{BO4Rnd^Qڐv3ew?>PQG7y)ڍ9P{!Z>MC8x!OeYnk(TҾ endstream endobj 2260 0 obj << /Length 758 /Filter /FlateDecode >> stream xڽV[o0~WX Hc沷ITM6V&E#g]gc`%4!>,'@ <;z\߄Aubt=ViRY)],GUu,4Lu?w|L.Yl`5B{ h<z ¥v}@$-%mq څD`gXBpOd@K }ai ¾28iVnAҝrd0#ӄg+GÌ$e- XOٰH-Ɔt*茔>i5A>`>Gy>iXbT}+lLg_`s5`YYTY%Yd\P#p?68Kr!y_ޛי^fMHS#GzgآC5 \/+Dp̚g{b d,/Ȁi.تb8(pCZܸ57tvxY}k`SIJ kaU)W98>=<;_A5rk?8ߤU>Ӱ:bfOS˅bԻ,.xH<_Iy:$htRtr%ݞ#*Ԩ&YWBX-ϷyfFQ En/&-R-2Ṫ,|Hѱ-6h(6lѕOXUFSA咇ߏ +q_sa endstream endobj 2264 0 obj << /Length 715 /Filter /FlateDecode >> stream xڭV[o0}ϯ䡩عhWBZU%EӮ&t*$|Ns||` 8׾i` ׷L0w%ŐW95N,ӻyR,(1r&jP{Ԑ  zY$ T]{๜&XY:Ȅ4M$~2NPà'9B$!8 >t1iD{HR0m `,=`԰%*XƳx1i Z4d& -b`5'ѷA>1lJa%>ߡE^:c3UO> )ˋOU_f e}A /{ӷbmF@;Uy1PdRN~z㷄0P?8r7a M9̽S[9+ck3?/ i C 3f=%h]AϞ K#l qo#C׍HkH5JC|7[$:#Ӝ.K){Փ> stream xڽYms8_71 ۊ /N$a6)r$&o$ԒV쳻Zp7p~i2^s4Ӈv5^%}wmSWuĐIlΏ'~ )j] 'p=30%iGxS?MRAa/ =rكVװu|uAd\_xe@]kt1Yw Q. Gyr9xד}OR&\1Ad(ܑn͆q7u^* ^.lkk٤c9U+vЈT/ w7}G I></mp2&#nw`ӧ 8K,r&ėxLV4^핶Lqt7i<0sp }IdŐ&79bCy2bl\PBAod ,-衿_ha՞d [>Y7OhڬpǏ}䈴TFmF:\>Ec?o0Mpz-m &zOv04# B{>7XO|w&d8+Wv>}n}8L}YUt_Lx]SP.(V!Ŵ ]ō%K6>Tb1 D3^)Sd=#AAUa&6P:*?1KLMT87s L&06`ToMw7OaU =4inNzW&fℑO*(~ vk%( 7+MP5% mꁜDCqn< VY}B%*]PH(WکwDu6LGu'.ȯ;}Y RÜIkZJRQFpO5 A.my/s Ilt1r艀ܛ`sJ#vbZnLR7 2] (@xcf욅iN=ܛZyS4ܠ,={i9`^ atPϐIrf|7ۣun"BbhJwm4v Ϭu@6 lq# /hGO:`.Eb,)Wt ɐGZvhQ *9.v=r6I-8>cAZ`zjFٰ5j >HLE6:\&lȶ-ϙYrhLj2K/nR:e_Z:fO4nxb_K=1> stream xZ[F}WPMC_hrbGv\(*ʼn&榨(<̨m9|5=p"wӹ;W s8EA!U(sCW{_!LttX=JW_ϞWaO:Jv wЙ""(sU'^sQU%$HKe+e#*#l%X)Z)AV?%nCQGܛ'aq^!xq0Prv)4f(lӨ opqa0{\>?%58>M;Kn=1gܨteU>uoRF|q_/ R)z<-YrX=7q}!ͷpy9WFo)nT@d} 1)z^Φl.}j =%mVc\$&Yf?noYVğ `=k~Ψ; y /fJ up$Ŏu2}DzhC y2U|lڶAZ,g!L W؄A! tαkx^dB 1 \ w!f ^Z+x:XoVӸXa1iRA ; lBb3gDȮvJOx`ɑz*]ϫvWxMуMt+1jl}m|i_  AȘrt'*ȩM,3tGy^e#=]yuvlFamYE$T7, }y kzIQTji[M4¶ L׺\ǠUBxc1 t׼5 I‰gUvW'V)UYV="Im`M )Y! N~$:%Pɛ0 78&yD_UzH~l6 endstream endobj 2359 0 obj << /Length 1796 /Filter /FlateDecode >> stream x[msH>ldށ۫cV]rWSbV&~(0j2 Ow?t{(g)%a*Pu@*QV ^oBVxR,= uUGDi>(@ņ|g BVc LӨTC4>U-VTIDTّYI0~]dz?oUu#UUӬ+ *`712E'*@0^ekrL=)VF=D;Ў_OWO׍Y;u39LuC8Zl6zB[ "#ݚY=U\k F[0c%<5L8Ym(V^&p\!RB?:?xѼ0뭩d}/0 *qg9yR;A>#/p=Lk,?"A o +^y'x8x4-ۖy"VO|~>hhmNP et!?2:8INJ /38׿mt ;q.}=r^mPԏձ0(s6.I=zt AM:I+:oy s欵̵)ķӉ!R*Bc*ԩ25<&Ilt|Qm"!UcDVZ&@8,'2pm{y+} {{sq.4`eSn]̳A-O7dK;khTeD^ 뱖z xzKI%c-L|4#ON-sG@3T М'KIsE:/V멗S8=#PlAL!ol,6c?Yb^h_>c6>V*EF1`Uv];ܔKཎPB'oCa,NzJ Z ӁZ4qﺡ$m=ǰ^~]jM{y[_MKͱ {Q#9dc|Qi7Jv;<=aHm{*gѤWQo817w$W0}so?ʙ5mw 71 o-Sk6ՇڱyXwKM|Ict|XTc5[ :QMm+DS1]_:t}:7ZwԷt s$=T)dz#-bheC =ARvQ`J5G?m|D|G?tj }){USYO?Exk>kwcˮkpIrB]|1V|k/n(o^e)FEFո1%o c0ٱ&F]"]=:7'.v$AoVJMXXc!Q,YrMB$& Rk0QcTtS|0i+$^XLJ1W&t?p=Ɇ o}̼E/|Q y+}(zL7{ϋP?3۳FRF)9>18x|/W<G endstream endobj 2257 0 obj << /Type /ObjStm /N 100 /First 967 /Length 3021 /Filter /FlateDecode >> stream xZ]ݶ}_EpH-i4F`HM^?뫍m{):ΐ2!FRA#Mdy`RHѓ0 BTE*aуmH_#% n{2`!9cPc! Eor@AE0h@i0(Z2Gd~ C EgR?oAR孬1]G0n6z:Kt@1m="O>nwɭn9o⟰B/1dF#Ut״M(ACs%-YpxfnC`T UcvD݂h>ϘZ~ӁnO !nO1P*@VIOs y)%Elǃ\5oo蠖`-1F+snFmV@`?->X}&ϞF 2sS. fLrd `4.95x##ȏVDucTHiAˆvIhbB>N >9LbPH a'M( ^k`7k`"I^34[ϔU/=bx 'axW7v#3#AịO>:?zq=2y{1\ě+$gTbj p{<_OtvcÃvq9h/_9YqU{uem~OͽOSEGgsM/o0XH*crX-lh QtF<1`6wA:KFESci2z= EGWH:G ##Z ncc!UvZo|DL]Јc-F_$YvRrΈ#V5x1BOKEdXM}Q}3Ib{t*#WhaͽyyߕZF_w; QhE{[/; hw߂#ր{k{/?} Oo\ѷO^_gW/r#|w˿\~ B!Fy,dWL??Y2??$䇄J{&Oe.hO#i:ys&76بt&*9vCXӾΘQL7 O >/l 7ʡCoPotܑsG9wܑsGtґKG.tґKG.tr@2РS_vUGnKxYɝW| a[Zf-Kfu*R'ij30 cm-[1 i;˜9H͒Wyթ-at}T4Mb]` fgy!z|"}R(V:Su^)Vªrb6JLwIJ JPJjuO}}XG߹a0z#[q6=@qX@TiD"&Nv+=!@6Vczu4p#t2}ZٲٗyYk%/up}Pbl;]?D};>-l+LM7$]$ɾ'o#zZ[SM2[iiBLKZb 28a IwIx Km֚y#Y,g aӞH1+ĝfa\$!\&X|}B64~z.`uX|)k\扲|Q(T@SaGNaujlK gHO{\>>H:jOv|YY>B*䏷 6gsvZ5@*qKDV>4qPDB <ؕMr-\TrSrj0}:W4ہfQL<>wZ"ˮ MblT#%c.K>>"'pMZҩy/H.Er(īubi@}Mwyj b\bLg~ cbH[lDµYՖqVesZu9Uf7Pބ;&m)Ti"?%i@ ~F.$'RGXf\4Sg3LXTx;,r*u* 8&*uyTi B?!$@*P.5PfҖ)k9/wd:{qKXTaAͦfnNlt E-PʛZ 2*j.)aА$EUC!DjסЮ,}Xarno{oSߦ?h}thpoHohotdԑ#ǎ;rȱ#ǎ;rȱ#ǎ;2wdܑ#sG;2wdґ#KG,Y:tdґ#kG֎Y;vdz҃UcDd:; 46|XRPpZSVj|Ap na_]|]߯={rMt<00X-J{;>>뜐HAK)ʄuL91(nC觥.|{$iﷲ́L[eQLd~$F/g<\J.wio i@+,HJJ5Yu%y1J1r.H~!$fY-ml#P{ƍE9kYZYb</DIZNTT]U.b!|s'awōDRlФ.  ܇[IL%Q(ej6<#r=ڪ endstream endobj 2390 0 obj << /Length 1898 /Filter /FlateDecode >> stream x[s8)ٙN>8N^:a׆g_ahξ$DIhXPDI0n DH$P0?UI떥gj6Ubf86mhFS@;* ,g@fuvGU,[,K%{*X@DJ:%"H0rxgH|v͒ICj~oyz阧#X.zƲbYsnwaeI 4)K!pUHk <%re2;QeŕZ24}%0*L{?3{ڥ[cQX,sw2z!aMJUag=M;ZJWvo E: ~)گ\ ːf q7S Mk큑6)SEJ 5aBQR?J$ Zroő, ٽ^tj`PeH%epLbH}#GgCnP@) kk!&(|U?m:i>oZ#-vXHeY?wXvԵ"$)"%gWfx3=ܯF&Z?,h"4| A1)UQی)ңw<7 ʧNҩabI}Y;;ϝk_oR DzW;.Cn# 2N9%!^/Z=l@Hd'ua]kO̖l^=s|/kj:.8o+eT*}inqrbOv\>o=?x L$ ![7in"5K̚3sD̓.*+N҉EUI&&AɆMk:ܢ็bv1;kb9͒7Kg>t/Yk÷J>1#"gXƢJ,v˥'kVT!e8z?9lBp`Y54[ endstream endobj 2441 0 obj << /Length 1811 /Filter /FlateDecode >> stream x\]oH}W1ٙ;ڧ6VvvR"$h i81),fEƞqܙ@:_~"0*ŃU)1JQ,菃g@ڜ}F;ro|uaxi,cn;>` (_;o!q0l\tuh?-E&bR8~2D7?z &d8|NE8>4ZX ,,«i8YNzK(AEy7~1=/FJgWAdT"5F$~ޅ*g$ t.m_3(h/ F@EƟ߿~;x9اVQM%-usr.MSp]LtU9ynT Vl93.h/; Ae) joatiO"\xcdp1]DQS]<@88jw~(Fy3tpA8^wRS`]/d!`v2Ѵߋ]I+)|ԉ)bHIE/ 5i=] &#Z7[` E9K^9U szgu|~{쫒AZeԕWl힉C>"ZbeӰS) 6C+j4U衰\o{.FpoW뚼DZF4Q*Q"2ʮ0B){nԵ _>DF-N< lfVg(I$R@S rYte$KC4X̚Dގ3^6bz4K :#9;ھ ?e.{78NTR:PKI7&yҴ^ jIX.U|veNmטQN`J&k[Pn^?L*\., kZ66@(bpҲ?!p^'<;'&Pu7O:<Ři䪄(ђT8Q3jyJuS7s xa+7?Bv>Ϫ׹%OR"hIqF);3AG 816molx?(oIP:ݩxכ5D! 7߱tȊg}'z;e''mlCm=`&99Պ) E8yJl6b,FVb $*f~uV8Y)}5$c^3.ChPqB$IQ7)4ӑx(h 3T3a8!b -\EL1GEQ`@Dpf. CjoGTb;u[ OA)n*l9ˤvEXFv=H XAe|j|?ddK{4 f>oLB_=7f?fg, Dqw LP}(Jv R]4Uva=fx$ڇ)}YpS?M5Ăm>"oz;v;ﳚP[ x"ȥOԧy}>!'@Jd~tBH,7TbU8  kyӳ]\3F endstream endobj 2362 0 obj << /Type /ObjStm /N 100 /First 1034 /Length 3803 /Filter /FlateDecode >> stream x\kod_q?n\Q"#@2716 O Hl6~On;ѴH`~Uvަ,;H:Qna:x-l/bM: u^t$%b }C|JAGi6rODqF 錉to7c"HR>.>)^}ㆅBBXh!APF EFAqa+ sPZx,LQ? p CQN%Xٰ1 Km,!lfY8#PWoK:[E\TɁ= Oۊ`/Ii{5-ʦXDIaC^K^!jTXd%"K ,Mg2ªƈ -Zt%C_ l>(8f{6Au` uZ7",)T:%L\$` |B'2 k> %e'Lf pK~oo/.,?|oon[ Z.wwW/B .Dqņm%5Dfr7_,/vw_7_쨌ɇ э t}.n:K$gkiߢ?!Xk0,)2j=^n~>!4ku[-ț+rO? !{"H!8\ 7ihŬ.)ZRVO}ZW`0V`]N9`3Te~oWV2`{#/C T^FwkZB<=vfLoVm5wm#D 0j:Vpݻ&nëxw k<ȕT@jLb@3^^& l%dToݣM21]q6CͰB-g@ohlHِV-׌&C.JY-fKJ3ukN1j RO4jb=TޘYЫ1FqMyޟǚ֯Yv8F=ԊBqm$!]KZpGX[k'DhcW=z S6ʭlÂ^J BmhZ̧>z#OϗoQ'Dr_͂J`zuo~ lҹ} a=tGz:x>wM}߱ϿX._[| _iJw{{e'`kVƱl3C%2 }Ѳ]5V>l9rmt^L-&lpDuLffk&||>;mJvu;b,=+sOA iԑ IZV<>cmvP"JͅLsbOxpAù)C;L^HXFn^)^Zo?|kJNF UBSƖ`d锧S,o=״yWu*|G-$ab4@`j(̒9ke+{L!EczT-gze|s zv9!ZcpQ FX5?czS 9H(dFaOX#k>!X(Ɔp@# &87 lph%C>׺nX=<؄@L{GzG?_t~5qxԐxsE{6RJ"',{@+>lQǙ=I`eKZ|YI=4!z=6#6I yw[?- JDE9POa:rDB9W}k_oȧ}g%H͑4#i6Glçf%.z1|?sA8Sld;%)NvJSd7%)MnJvSݔd7%)O~JSd?%xҶXVPYKqY $y:86kG?C4ͳбόFE>IPDZ`g@M;_Aj(^4ڵ\zM WYyJGȡg.;jT=p%t'H͔ZẴx[@c׉EVԶ]Sf[d5Ʀү|+/!Cw)zЬ!%(FЈH'evk8\,P(B$0DƞD%1VFq_01*d$\+< 5x.N7(zÁiaI胅CDN0o,;Kq}(¨z%+ K N:D$x 9m]}kCEsB=/ ;o O^xCFw&P%إMF=kpP`JzwA~EAA[ޔAeEv"oMTa=ߑAjN>/-IMr_\W]p<6z m+> j y(IKm~-ZǨczdd^gڰ/jLzaf۟6 +zy{{Eds)0`ɹd~]A1aP.Ul괱U6j6?0m?{LïEzz֯E<D endstream endobj 2511 0 obj << /Length 1891 /Filter /FlateDecode >> stream x[nF}W\۽_'78;Pi@( QE%{h˕DVDxٝsf쐄ޝn3F= zɹ'y݁-;Srs_rl8Xɤ? EI_:ziD)[>Co`ν̈Jzߓ+e0Ji]`J< 2o%GffBDL7J34f2;>}:D C؞]齋9+^XÈ"qjݯ  IсF%g1 \"RA4 " T#BB6&Ǡ%T`qXIpQ~2f8JB0^Cl_ciQ?xAOt2~tzO#4}=+M]LM1˔erY F0I0gd'a͌0l i(` `#j֒ edqy|Pc+bApTf_&f\"lLy_~`9˘r{Jdf8MbTEce>zʼnSlsW̆ywB6H< xʁHȉ"/5,!eڑbV\^"ARV}m*U 3(fDE%-BIsp3|r.$IĸU ਴XjgSNvg*a`pVff`W$jȢ[ 3 ՚6:YH5{R]~ꮜ,Kgؒm759qԬH_/ά*`ΫlʐMA-!Q 6fU vd",XWeRfd ;B J:_Y\pSơf06LTUf0U.VOӲh%_3z;|a 1m Ρ%ؠMhӹ?p8˄`K~3ԬLսp0,ZNSFeȹa7d_=$`LTDAMp1๎:Q/M_E)VfkȘٳW ˝ 2 ~"pdi/}; t*]7~珋ܤǨ,b>wWO;xRÙzy?x^CVkKz'&bE)lJ\f؀J4W+cb:k]g `6ha`6)9gMâk])U4ru"fuQ"VS M$ۼHz܎\-R-ov =Z??>+uo)|Yqب0Egѱ5cҥ `>䕆op6iwmx_1,Miai7~CZ%hFwWFEl(YT #hŚ20p-,+@ 86n?m]8^: ; ׁUtak+M}?N&4FCpE,җ#ϼ{eM2mB\s n?y}XEA꿛E'%I9,-j|}lv+_(`e!uC39#㏻m6M@ endstream endobj 2550 0 obj << /Length 1461 /Filter /FlateDecode >> stream xYmoHί/tR(U[5IM*5 ztov H܇cvyf[ [˷[rd0Fr)֍-rloc/ Q,z ſa4RlOW~8Z%4FTW:l륎pp [Ny-qC5unbˇY1ױe#g zj :W\Q K"W1$NbKaNO6n*/:MObl_~4z>Cp;Q>S[kaԌ|X8$KTn[,ݰ0:'qGE~ɢ>*cp!R9&"0HUHXԋ-5ۣV;1ʑ{Ɋ EYt!Tts+fUW:%r(ju,#}ddSMTHirA6У. A[tG:J>eaVa2 S#QF}3(gEAfngiS 6EHOl2i1rR%*jQϖL&"NϦ %IHcfU/ǒϣ nԿU6kMz3B fhŅ<ꤔ)ғ_N۾|w0R&d2A'%|׵|SvW`Q&ݥCGP]T٬Qx*t.DlnrAa7|q!`QCSoC{}U& tu2LeeS>_cV=y6W0o0!&m~e B ߈BGy&|#8PH^kw|rՍFtvB|¿frg:`29ˎ E.4 R[1tw?s%8NFe'.re$z$Ɛ r/.Ck/< R-ĉ-'%CI9w7՝#\qpr~ -]ݔqQG]87G@؆1cQK™62c"{PgV{sUCX>\U=*e7$L`m {5NZ4X9,ٹG滮W  f3VK!i)o.o16C֋MuZO@ȡ6 t1`u] Kr{yQ~5˿ Q@`G7Z^9m+ݴfr`]:OeMHobVٖٝV5.nBӍT+6P붋> stream x[mo$q_1/în@0`[P.>}%yQG<5ZREKr^VkO g! 9dr*mu(\hC3({BqQx ̯ʎRfٯ' U_LR>3_#A Ƞ R 4 x|UeqI\jq)YYmPIJˠ8:6h.~6qdRBaj&erΖS߁elj+CI)LwPd$ Ū,UK\J*5=UaCm ՠZiPۮfDCCsf <4,5@A,JOV [DԊshߖS"m_b DUF~jԊOX&na֊^cLVvz ˯b5QMXMXMoN4\@̻0It%S|5VR|%]JXB3KLՕxMZܡ񃴺(_uOdEw݂ ?Ϯpo~׿_]v_'D]or7|{&FԱT-+>φ|y3\>LwwMrިIijynj[]R_^?Γ9 \x,!'ڔ*ww7߽{{>>7օި қqH22"\cF74Ԇ2 ^9il,{cۛ?{_nS_96Mem*ʖϸ؃Rx9懛Kp_:MӰkFjz6x3d`ƮX( PChAS !r %K @.\r 5k @\r 5k @nr -[ @nd!H9 B(!#spXմc<,P.Q;OZYL^mVҨ?SdL 4ɉbFھzAz:;&3'cZzzԛ*gJ׬[giŀ'U.lyEPxCBl"A4=OinYL.Q#Cu|A7grJR_d׻9S7gQP^:O(γ1XL4)iG͒lˢ,PQqw۟lv㳸X>ƤuJATrE-;V?A{?GJ6k#Ѹ%Ɣt%, )psh$#OSg 'hDl'`"d2N6:k+^w2oVLm}}1d?Bvǣ#/0dC6yIV(ApCv='4^=bɛOWI.D>bшNTlFlr'>:͹Krv"]4kH˟>(ب >xYr)(h6a2[h6g|!Es՟C5T'elĬH_Ɩb57YO'W>$?2 OޏRRRRR !j9j9j9j9999999%%%%%%%%%%s @΁9550 ~_%B#_ҝCC,B_-1y[;\!duC@'J>kEYy'牘7sZ^~P y| =cGO2m~8j? }( rxhBZSkO,[GS5{*1Mdf^ !v"O( Ӷ>28JQ_)lsiv@юXVԕSFJ0\]?*ɶؾd[ɶ Μ=5fp{̸O endstream endobj 2570 0 obj << /Length 2252 /Filter /FlateDecode >> stream xZ[s8~ϯf_X;[Elb3@p)cZ2L$0'$l! }߹sk&'م,q* {N偦(:"p}Jg'[PRsyjqm0]( 3;D<'#jD[mOs>Gjs.$Yܓ'( 9$G†8Խ DE!5W@!J]_YϢUosI@ }eMBZ9Ckn=7 fS/c-CiDa؇^J6T0'”4҇OIF|iᑎH_ Q0\e2L9~Lz(`7]+$ "\ o]6 xw9SD4(@WB]=A i}yqPeQSdF r3CKNnS:0qDL{HwWϒd.Ұ*^A3 ۽swϕ53G%Z׽!Sn9:t_b~H[y^!+Brii!Q?FtG[@ m8ҏp񖙴.94Fw;2f']wh iG69%g>V=.ma7A|tVWQ\˘2x -JӀx'䳫aVm63 r>:$nAV AޝHAVWUؓWݐFXBսn.IY$K桅wS ME5f .FK(#F)Z 6fV+jY"^SґI爡^}= cJj =atT(3#,HehIa̳Pm]61Y*5T(5\ns41T:jzPuvf(Ni<"Ac񠺨c?FiP\g% WHmx|71z('}\!UV0(U2 $i냢}Q.]T{t %׾ntǠK{=zS*6ns2Ԟ >[c&dyy>l|E}".5@Eyο ۡW31qt3 5Ǧ5טiX׊yiz gryA~/ g47ssfz5]U Nuy㙣Lf;WK ~:6L7/1`a&6,j!wfG Np.WV{gFiMyg.G8pygݼWf`Wԝ®yaYE'GOiZ7c '1. ba]Ķǵ ε92Oƶ[ ͹k3ZGckp `Y5˴`Z8+ϴ{ԾA c.Znҏ[(㠷۪35S%yxEd8VG^LQ8_s ]J(1&3sbX#ݘQZLwLxδjIFg:\Ȣv&a'%K9{t9-S>BEYz"XhZ}؃{5C9(@pg5P@`]y9p; 3'rA) C?EY=s.*wOgAafDfǾg3Iej!=nٱʉogQqmgQtf ~ZxEKWS]]C^Q"QӛVڒ89Xpx_~jnv,p$w._"dK|t6&Y]v^j)Wc^vi4mHͪW *>.hGJ;I=J.!Z^O9nrS-AE_)ځNSe%B#}}t4Ze_sfUT*R~~M{$( =6 ";za)dj4} endstream endobj 2583 0 obj << /Length 1485 /Filter /FlateDecode >> stream xYko6_!t`1ˇHJ+!m] hG-+G$mH./=𒴠5uyu<1bySC0fq,/ ؽ>N?* YMD:ZqZ;d#ƛdѹz @{fA@\{ml*ܺ"BN-\N"B B9[VKӼY*_ʫv>~C=nk$Wj/&}9NXXPo;%}W< n]0q>v~ȱBdk.<\ƤC _4$E"( EMuEo?%ρ= &/Vx什uur9בzuk 57'm[mm9 IUIU/ofx8|.oaPGfxI6:]5Ͽ]jq5˯-S(8ڴ& r{}Dѥol뛺WQ}takHd~R=,M<©ZuA8^ _'ǿ)Gp~ 2W:\K (%\2$lصw/feG: x=͝*o|\jzqԶx42kqRF"FrLU$ ((Ƞlu(L$USBѪN,Sޒd!->%wtWRϘ%Edp~l{Kt4aŭ2~31*,Bbp:6CYyq%4vHhk? apF9}L/0@??f]ZOL}I&#rLgO&DLEL{xfޗLU4y7GR^HfSIiVB#u/Yd_]> *) bI# 2ڼ?ZwGuʗN+NcRfbO  U4)< ۦHMVxM2d6Y7l($(s܈yJJ3@ n68?¢o |iRc4MVqK@W܇l$H m 1)=˓t2ō(k׎6l;7FJ1&=W-%,{gعXjDM%88G3#N5T2 '. wc,qNïIè~0]^޷>KvC:/:!0wpZg[Lwht1i6 |ϒp>]ay89\Äa4Lx}sE?}@}dsf0yYC?ǩW7= ɲG`wE'! $ endstream endobj 2588 0 obj << /Length 212 /Filter /FlateDecode >> stream xڕ=o1 ɀ$ǭU [lr)B:{ҩ-#?; X碞!c 0q-V:e.Knjf.erܞaQZԗ$Ĝ1;mVkVvKb<&;1MϗS  '.E s` 2Qۢ{3!a$k> stream xݙ[sH ;"~IDV9v)Bj`.$Xg0I Z1vT"5O+hgENKԶLNOXN,,"%2bzŪ'~9T-3s.𑴿3Tsp4t$POC i0*W&/J޺c;~bs=虗#7>k дh[%)`4`|KŲ`e@*]O;>"QiM^vT$0\ƾ'#n'?Zc3 qZ3SG7VݑZd|sm8^iU Yu3k5~v=]7n+* uk#d6Lo(SxVZq+'ɢQeNEA_7j[ht&c J QuFI i7xZѰp\`=5*?X%ܺX{4fH#Gv`΢]ď>/l4iΒzнۤ5YHw j攤D2WkW7ph5+jDJ*]mU6di5;n)R4[L2JDjyN7^NJx׋HCDy(%ylqɆZ3t+T6b>bƱЛVoL6E&W JohLd)ǃ*"q_ -0vX2͐U#ZVA 8q>/jPT%o'Y)pUhvWLctO]9;՝o9a%X\U,ru p1~tA6teŌSTYPߧ\кڜkє`E4m>Q -{Ԙ7+%z'?1 endstream endobj 2560 0 obj << /Type /ObjStm /N 100 /First 1008 /Length 2787 /Filter /FlateDecode >> stream x[][}_C `Hl nlmc+g`h_3\q$ײ]QG$R5K ).h(\&J M|LE]ȁK%*J BZ^w5H@s1@:29Xv wB07>/K(SHZZ e'Po! 3k-X?r8N)7h?k8 Ik8tU )7!(w 3j)g g*udQHRSdj fcL9`:վÁwϔC :~sɫV=hPUwgveW φEJ4ՠ}}2 ڍo nK-sTq85-$mɂisNDXxA2"anDN*'|وa\;4Qlb62c1[-gc1[_lo7toy3k]y]^>1qj=P%Pk9H  .iK[i -Ti]IU"",Œ='2f5#\*K]nͯbѣȽRVS*x2(אzR&F׊(uּuJ+Hx3iDjI-#lhus~CK)"^"E| <]o^|o\~1B,*T|w LY@'>1LllCRN\r96s{`i[SW"1-Nҟ p\ A9!HE{7F+6]*}<%v&\};U~cϿZ:"zb)J5 8Wduy Ey hR~QGJ $w;&3fdNO&җ,^E5RxwX s3UΣ7ԓ~}?ĝC˙K'P> stream xYsHQNx4.9x&5)Q&5L(ֽXGXjIԨu> E.N'+ysglQ]/R$&^ LIz4P^3qEb-Cl+7銞jYٰj#NQ>{MqXŶ1tfJ-Լ i"_)KbVUm! tɧX UyQ:: H$BCZBm\аaVHuTelt֨HEs8. 3ͰnϳڒE!Bm>7>X&Ȕ 0uuBՉ@Dꤘ4dSݞa"8T 'Ntڨ[=}μMLRn#J_myEv k㜑e#{XD»f?ďOz9ԕǤkIǽX~7N,׫=zx7O{- Ny'^BBYF+ T${MEs}]X/|me endstream endobj 2683 0 obj << /Type /ObjStm /N 100 /First 1016 /Length 2838 /Filter /FlateDecode >> stream xڽ[Mo]Wpl8~F$-`^5pH-9|OԆ@P}s3gr= *\G"΅ϕ j\xIn\ V"A9\ U Wx΂FyElܞ?b(Z+7B)WHU\JTJqjF,^zRjКxQm&;Q\I$"L+߭h0O9 F%ajϕ`=qR#>8(:|6B uZs҉0>JV=ԉ Pr8uBKzS!j[t#>ZeeBncn8VpPZ ;ZSh98kS'|ٰC+H\YhQ ,L)x.>6kK\^$7IM9Nп֔2&RarX, ÒF[xlv\Nf|s"5 7=5% H(.9QHoA H$>Cug6vDc1:Xe' tUx&jIKY܊iV);[(04(D{( q#Rk-vG}H{+_+#Si-ر ]A OmA8ԠZ` ֝qNBRvV CQDV@YJ,3#Zi"(Yf5YuXU+vfvL,d:,Y 12V{A@1Z٥Dlt"$y кgRi4#o?") ?U͎JTl*R~uf_O =J>ű Ul;X¦,,؊JP .۫6\0Zdkc5FQy^Vkiғp:*cXWuVdRR8==  qCh$S٩/lczDҷa & ^V>wN9PqIu;x u"#wb#p4iHs{] yLOݲGIU:c$/{;&VJho5Kq0TWw+'SPT0,ן?ۄ뗯÷ z 7 ǁv[=o:G]+^x#aB]Q/`1[$1Z,|.\Թ>/B"υŔܧ>%)O"B"υ΅ͅE:m.deJ)YdeJ)YdeJSr󔜧<%)9OyJSruJ)YduJ)YduJ)٦dmJ)٦dmJ)٦d}J)٧d}JGӫ gBz0$d| af5P( "rj&D } b&;1 D P(a{L蘚(H+8EEceM[(ՑlynO T D\Vac11zc$D ~v"yOp< 8JĠK3 B~7&r~ud9C= ۘz#dM>=YR;UXA i~NEg0Ԅx&r5z.ņ-1~\p5Kvk3V诇RvY)E2 j#[0霼Lf+땮3gK5g5b+g,Tyt-{ 1 dk^G+3z1dȉח'm bH=bީ9H[}+Wg/;dȚ׶޿kEyn>1.> stream x͙[sH(U5&fb %!l_Ec,`"/j}w.}N@0cI "$o CVA*"fh:b_( $ tiyCካY(‹`| + |r D  a $[L*deF PFG/+C=]g"]U4͟ M'+SY7ǪTi& |i> m FCx8 O`g?H/{Fw8[5K/G-5 6||psLb=8'1p, IY/Hc8/^fX GO> M9 SPM=W^ԞfFV;m[ʒ;' 8Ii/RcFեƮS/̺i:!tX-2lFke'1V>Nwjmo:bagg{! {nT^r\rށBth.}Pֿ i/(<߱`F ',vnͥͪj^X$+)+QZOiN>h=폄9iL=Bq 4.܋vΟjӐc::ܥ^fžt찈Z= quUztb=_` #i#bງ܂Y²0P#Ra6`cTV`K6$SLTiw4Q%I:؎p;WQ|E`._JW4(c8|ŀpH$.5V䠋 KǸՒ[fQz6o<<#ȳ8Z7¯(E}SФ QOWA߽ĝNObQB~2t/Fɏ=;I ߊOU?''B&͒}/%w̻{w2޻PI39o+mexch W!~ endstream endobj 2910 0 obj << /Length 1130 /Filter /FlateDecode >> stream x͚]s83[lK\|$;iaxjM¯E 2ބWyu$ @p{7= ̗`u0:1}Ծ?d@^vKFo2= qc}mEػ'n m}2[:0}C&48`B}0a 5v1v&ۻ2(^hz>cM,^ }q>(^5Ä uYN}QBJtf~ e]LEbTE:G i*4-'FLXV+5ix'\QF4#wViue^|a3>ɋ_3_ n w>ǔ)J\ hTl9N}XQfl9ZJAYπV||(8C$}{>WR (; RluyT zc̢}l™Յu}:؀؆P!~rB? ]G 8 Δ*PRwg]Dۦ05IA)4$X30hGx>:nJY5V? ~TRs!oRIɬnY{Bd_ ='iP>lPq:NQ൓ ggY#iGgxGt /躋_ެGn7gwG>ostT5.XĖڒٍT4[JNYs& :hI62뀬IYݛխIU˝eR- aLAh{Ҭ'@]--+g\ ʳҧȃJg|n;> stream x[ߋ}߿B>L⇶а5}7w>'o[2+՜9su%ݣ9.%](78qސ$ühԚz>7z2oDG"톻@[WIATYsƘZb]~ #6We3jqΩ:C~#ךD#E՟xс;ѯVڒ2+*DKo##V';fjٲT_*KJίSU=:ںtIՊ߁:tCK{j"R> P񷴒Zg{)$uOS9nVΑ É70s0+3V <goH2۬zt;୳?md6c<1dHo4؇@wHEiT{^p4O+*ZƠyr44 b()ÛDZ0TGZLQ@2?h;=4Omxx5i=A4d'q(ZdXfYJ."3RӇEpsXXWE,o5$R26(fIZ0 =v9LE <#֬l(Ռs$Tr% =G "s-vZUG"U3aaOְzDfU$|bssCSWNAUe/[yPL]ɥ:{U:3rR*:{qܫEE&2YDB<^%Udp^GbnjyfxY;r-8h tc$".c BT]QQ_4Qo^1| !]!QD 2j)Qe3#D"Шv_0P2*KST /W(j:=Psim2Ûa| ]xzݷ N/HW?=7?`rsxw\*V_n?U_nW?Q%h <8yj5$sEcl^A={ @#G @<y!y֠hp4$ F S S S S S S S S S S s 1d~CQR3֤uzۅq5A!/B sɍM*H4kYQ*h4l6Ȧ+pAQT/fZ [<( -*NG[<?t9@~r_WqE!Abq*vR\Pܺz'~P YY"[J჊DJ!(}ƹB ݠ!w.$-y'ˁ\ pvU<x ʱOƚDm\*)F&öDp%60jI9 2_ &˵ڡy*7v44ױD+Y$!P}5 b3~ ayUjSqkщ}ؤNڷJ]LbӾ;G$׾OAbӾ;Qt1M$ tλ|tY;!+`jt,Bǩ VP{ @Fҵ?_tɲ J ׿L?&w"k6sxTs2o AQ{|RٯT2t"%<9[<917Muϡhvk?oUc7ůj]4)`ZS)Iߝcҗ_6Stb>{|PWI#(8K /mi 類Vɤ6Ց"V;D)X@$+7QfnbU$Pmڿ47D `"UzQއ#I\1k=~/9DLPW{_Q|f38~fFgo1ims;ÝNp'H$=H$| d d d d d d d d d d d d 5k @\99Vr -cXx,|<> cXx,|<> cXx,|<> cXx,|<> cXx,|<>>>>>>>x>h 8f6alimW moI endstream endobj 2951 0 obj << /Length 714 /Filter /FlateDecode >> stream xݗ]o0 [U]U .HYI D`?=>!gOB\M=jv ޻erj1˷ʅ]@w1@~P3], @6VۚɅJ45$ձ GKBgJM-#=/p76lgdڌ|u]s-Ω тY8傦>#TG'3PKp}5XjxӐDEȌI.v5TxUrNU+YryO7W"tSDhB&].9XG?i z!36CBlF(ĉ vdҠT`Uu7FVjn+O 8b42UFtҘyQ(CZНuBh2leܮr, GN-˚צOQΣlmoꦎ. zk'Y 7{bD&'.Ui0!Q64\]n*fI mRDNN=n]{{nG?e[nM~]H-K~}t}7ƚacu7FqK 9Tge{ZXF;ҥ?K endstream endobj 2912 0 obj << /Type /ObjStm /N 100 /First 1013 /Length 2529 /Filter /FlateDecode >> stream x[M1pX,`$@Iy1,ο{l|p=m@abGY*Iyj0"٨TqSHmp4]ٮI$9A|&}I7Z'sפ tH֔#űF5 ~I[ cPtRi$=h$(j!bp5L5 0DÓ>QDr#-9'!7[I;5I`3UjFrT]HTW-RF g˜S>^/)pG]R o5BTS4#*>y#RFoq li'XV'!-T֋`a #GQSy#䍨FK=NbR P(%uF0si BǃӰ>4*em`#&w=>)C;H]s"8;p,Rt,U-d0kR i UXYD)}C `K!VDp.HH"8l(aw1b51b55tB8j:y6LѦ+S1j:(%Tns^qN8O/^oeÏg#L@e q yR- ղ- r 22 #Wc >*!VA.Kn[2iw8 w?c-w9BYc!`(#A"Co`;`!4K e:m I+, j'A^7| !+XjW^ET-.rk^JMX; l`;( H`w_?_:~*ycz-ӗO־~zûG~/~Iu8t~Ұϟl$x55Nk0.-k kk(뢬.ʺ(뢬-ʶ(ۢl-ʶ(ۢl-ʶ(싲/ʾ(싲/ʾ(۝j*,HJkP h7 upYT2fErWmYٷc[}9ϒ*h͒Z6;$ybd],`If#dmn;å_!S v,0=o[: l݋=xTfFTTOG zlvJ#׹+akENWOH Bjn$)C)E|<#lib14<B.+EAҿq?+ɱ—$dER6s{bsŠdPܮH FUQ#W 3Ni9[aIҦ`Wħ$SO|O \{aU*1v ASU0@3T6!,~82rE'5oﰼq endstream endobj 2968 0 obj << /Length1 1416 /Length2 6052 /Length3 0 /Length 7019 /Filter /FlateDecode >> stream xڍwT6҄RE:QCH* $$ IU*H* H)*J/_PϽ_VJޙyfϳΛwv05$Iuu5 $, 89XW~) #RPF XOuW XK@@!Ho -Tx큺@-$p*#Qhߏ@n(,))~W:P C!.sïP8 2NX,JJPS@x=X'! C{# n? 8Np AÀx+ C`)04:HS!~u~l,W?_(醂 GWza! C< pWuPMOg>  Ga1Ōe۬WFX ?8ﻷuA =>[pP& $ą%D0w $x7 +pgA!Q@0? @<`@,?`0`pnoh 0{$_G,htO)ߟTRBz}B $"?]Op@/]ߨ{C? O]L/R42;R{+!npW??ښ#]D[ORؤwY8)}EW&Ң^YC"i!ɮxEtOnAKіzeZ T }3]QZVsbUXTD.W<3c3NVaӾ8;J\SQhB͌oF-ZhzU2mq߷kJ YWkqq4R Ȟl-28A9VRW[)a=A^ދ@=aGI`&t0@H߽.m:(PnT-7E੡pD/]O+SeIaݤe}J'?~iW'F(.6FU1R"H& s殰#3N5vVssJ,=.obH\zя N*ܲn{Y6!l:;^򵖯U`A%HvMYZ!N1vy:<mA-@I߫ ĽiNF !OHѠG7& @7t}g ajS%'$yg*=ƺݱKh"P (.mВ̜ F.Q~1G!TN^Dz;|Ш9`2Vp0;X^fQͺJ,gPջ7MfoHۋ<7.tAw;3!͇~<wx`l޳[c'iyMlq 5'Bgt+o-_p|n^N>vj8cgآ -ִ&h^ce`>x/8/ :e4x;6xدfu$2Tp<LV9Yߺe1JIvsȂx`^i3e7 h jg'zH֞*E`׺6 p{# mud+pai@&EV [[eU`W盟^7Q&C,lQR }2G|PSMJ"1nl}@@sP!+(/s.{ɚCC{rO:&|;u]~ %nTR_[#{&fcZI?2`X@hE)!gœ'{1=^4h92oeùakz;4veP,1̜;+f:<&.,=XipՄ=XeVAS@Υfx3(H~!M5f<2>;¥ܒGكr ѽ+oFK$׹gzAЃAgz9q:qOzMR+3a,}3.IOOL"LV$2D}׊Xaʌk +JfJRoV $Ѽ1K(j 0(MHA}!PWHCCx.%*o׻zo^F҈,x7sLi31@B,q3iU44yg-e uix8[~<+Jt^^Mff4#[ΦV'@mWj ИNOPnHԅ ÁS3qzџᷙ?yjbCsW>r{Srר{W|۬3[eCb-c{w;fZ|`dNCA&G}sJ> nkZ TDwR^|a>R|btD+DF38=hIR0e;іIͷ/k/FyO$U R&:)+5Q l,qG؂UMI|; dSQQo3m_\Rwߩzg%SrܤT˪Euk{aS3drEyg{صʲj!\a#1,εk]j$An3& Oq5#B藷ʋ QݢT^:*o"v3$D}rZRNy4ȫȚ<y9X=GVIĶj񌟨޵@ܫXt9 (Gs BȸRJ{\9Cb +m a779^$w{R)?K˦ݓlnQ s6~h-}}u@] &8Xơ@|(&AhoKjt3-l1NWcj >Z@]*Շdaav[Qww:BOi753{ӈѯ,_?zsHXlF@/rx*t|DžiPb;2jJr*8UeYvKqс8GЯsHT+Nh Eȫp[g.Q-MN\k׃B ̶K Q7Ӑ :T+C,J\[_L&ҡ#L+!ȗvfD+~Jj{E]p ,s=pPjBEsP*UC6uwpf\c'~nfY?tp[_\Ni'Q&"HLE뷨9'Ku[K6>ka 񽭥e[/=ڢϨ brgYVEJ0RVB!]jt4gw vo7{dBgN]NW|IGCyo{JsRGZl4K>Fl2| J4r3Y|춄Okw0Ĭߟm~]JlAj$VDbRt)?Ww|ܔvYHIVcML>'4 rvXQn{3j9Ax0 ^iJ`cŋ2 gKVY3!wog9 }DQ美-{5N@겹eա*T^h`']mk,cag䕩 M&. Dq7oB}[百^͍lxzܩ"PIdJƺgforדm3^9ZtHQ?<ơ{52qK$I_a+|SzR*tseWʑibcz[=Hhh%ʏ*dgq#)tYeBVmz0l$P Q8uL5ԶwegUV33jv"іB&P­<)u"%C(R%Hv#xQ+,GWU ]]|;҆ш! z?kMn`ZIFJzgЫBi(s;K;e5#zmI21ښKX#"r*M֬; #w4k^Y m ,r's֞=Sw.yqj]cAti{ŖbFKo~ɲk)+n|NT'mY?*z!b Ƣc_- ] KbfR:;I&*2<)[Vߒ_~O(4#!ØcMSw; C^DPշvS !I<*퐄K?QrVn%R.C8LbqTFhWh5G[%(n@ta'iv)`u$F@clEUoW_?=$% !lOA bG((wy4m dv K5.ES1)]P+ކ2l^Y?Շ*5}Aw+y?L'Ku2R]:C VQqՌT~?/6dmɿ\DnwXGy];p RE*j!9;a2O+ͣD.`1aE/%T8x֘:ο0Y)T|L~@Rt|dۆl#/` aqFz\_K_g~uPԑ9n^|:6lU־Ș6{GǪ1mtNQ?!E g^ؗQ>L<{N_Ed&svXHI'jgҟѐ:G'2E0}1t;h#o ~峊ƻ5_+w: <* k?_.P60FPfkq+:v8&R;#X R*+ ]'Qו e\ouF<.lrN[D/6 XKaQ_]Ȓpq@@uUk#$Մ`XcKptzy錔 AIBζt36 |E[ϝ>v圱5GD-?\Tu Z$"qr,8jLŅK;J2prݷ\s~ a~Ѳ$:cNLJ juxL> ͋y->jŁync>yRXPHid{G %źQxz qKʽwǟ;V>|Fz`Ga\xmI6.rv kz7ٌ(I(^ endstream endobj 2970 0 obj << /Length1 1397 /Length2 5932 /Length3 0 /Length 6894 /Filter /FlateDecode >> stream xڍtT.)"]21Cwt0 0 14 ݂"HwJH4"H{׺wZ|{gww?d瑳E$PT@ ?hG9 F0w8! 0 S8M$ `q t(BM^ * ]}(1zC9`119; A4!( D(a(`t@\y!.Hw{in7Ѓyܽ`_ .?p?~}p( DmWXn`^U B./a;(78{ /bP@wEyz  HA?E; v_?uB  ;8|'LU/"DED07+wˍ  C / ߁Z`0El`p0?6zp=07 4lgHW@ߘ#}<`"VсvO* tug1-$0HnA7ݐ0}ФDDPcjl.UEABCأ =>0[8 2 Gt_t_1NBPˆ>P/  _і-7|$ @CZv@",'POwwtn_o`>0(*XrZ%Gͳ6*vj3gUZNʜS/Q+[:kɻ2}ZP+xà͞&qs2'q#FqB^ {el{l53ެdE"ja-ZmUEtbF;+z&~5c*_cͣR^2K$yW[_ V Yg G(I) U-]fzmoT^l#(q-x'(re=nDLϡuĮֺ׾V/3 RajIؗ}`'PDWSJ0\?Gŏ_ޞf3g,$Xn!^c5a}nV8>sY~tk[J@N(KE@' CаaH\M͙<[VqdM|bb:Yz wTZ.Z,W2쥽|l!k'Y3Qٝy~ch[q}dftLQ^X헟clρ]ywƊa2 =C0 /~`L*>OCG @1)E2|H [DAG/OcbWTTJ;r`6~V`dF1] ilB W5Y",NJ,k -+1OZ|K{-V7Cbؗ6~L*EY%aź^;J{R;!*: )1BtƜC`~t@"EU7˼[Nks3+0TTjOݏ3Gn}ڄԫjٯ-7tJGŨ_a.2};`bz 9 qZk-\$J>pY}0>x/%>9Nb( m9׷2^̉嚑`\d HH.jMC"2 ōnj9r&t[6.'_0šb$jfuȄUj4\>2²uQ0+|elk ΄j]F^y[ĸ&m`:yҜi6|Qx]g:2NF Ux=Recrug!jY`6즈ؾ:5$ɴy`xvm;Zm|Z'vnӇHe |Zd_xK8e߾?iKrf/>/HE~z٣{i#?41m+VםFSS~aWeJ»X?s'ى +l$Y(H(-?Zc|5YYLu5˿?o'ɩRu6Va3xgqH?6{E"S/[~yj_P;eY%\[=KM%8.3LSr#lzֻ`/2l2 \H#765$?0rdZ8+@_>Rhbȭ xdyψ{4ǹތ֭,Jo*W\@w'FYD19Ɯ8bTu*E0=vF5|<񁗤XE%K~zqCe%{پX'& Q|, NTwĔF{rkK!_"ڃD &]dsK#P7w& J}$|M6ʜ`o?dڦY-J$r~0D@!Lf'yܦ 1{4j:)گY﷌mn|>cRzHˑ-jbټmg$nUWaӛ:3Ͻs"M!AV٧K@t\ÞpApMKˇH <}!P}nHTf-{ͤ{ē:8hFXG$RB-RuP,KCCJ־0:ަy9fEPG d}"hSgL=o"wUA:d0xUU<BB  5_'h+=)M,0OOϭek U U}y,@aɯOk]L֒dD)s*)icTY7!ǭ~BcGJ>4Ha9fOKQsj͚Q qV|}Z`JA~2(i ʱ9RYy!z41.fuhgMz̹k;@ld)Ys+=ɴO_c0dn3ѹpcsGc^Ly{;? L8j?p R VsF,'%j3yfh91 MՑ@6j V]J?!.^I3fF7(•ULmD('Aғpd`(\~rPm7˷^rX~m̓သb3>wKd6bf(k#N_ю27l{\b*Ύl,/iTs4̴뉏 ^UyR5o~ҥUHh0J]Uj@K+oGKBU-K~m$P,WE,'j`~ygF*dJ':Yg]z.xYzcdW75 ߺSJI7}&p<c =! O]Q^ܬ{%I4S|m*}cABk.)-A`M3:'@>g6nc52(yகCǢC5AajD{3 ΀%Չ ԺVs7a4$:8#pRKV!?c'~9i!TJ~az|-kuϬ7q'b_o2(}Oo Y(dLgҍ[ڌRq%Y4}Xd( \ ȎtNS-d77i]"m~qLY(ʠY} ) ћ2d5׫;촶vkR% hܠIXcUaX-BHQ[/W@b0+: ُ|9OX"O4fՋu CU߀A%7'զ]фQ/-k~m˜yv?0iVqo A_nj?-M$|^)kojWhe˧@RS0oOYF=]'/2N΁zK|2z k\W5V=Uw+z &FP,S ׁ}pCL"(jrd×[ilE~(Gx< \pV[pTLumZIɥsU_b$\7͞VTykTFrbA =>T(fpr!ws?`"\8t sذ EBFs ,[>9H䆰_ZY2[ȷ^M4cZ[8>=+fxƳN׫+;ko)|?#:'j{ ۼi$5筩'sSB6f\1L~DFkPrm>UT4):DCun+I6ul> T[Cۣk +g2sLMao[$dcfֳSlٵomX'4@NP)n޵!$IW";t3JW`FsۜLTgiܫQd½_uH t~-## b*tL`\/.M|R?FkpP=I~HHg[0/H$bƹ||Sgߵ܆G%*6pL4$r9a X bmAh"af#9Iy?HhJBċLYk'%:O_Ļ2%C:8)$5[>u܂̜-:KV+H7IWoe+C׹_2ӯ7# XG%:TM)9LVX*Zi3c==/@Z\|M픻MexXo{\*ZPet?}ĕaPKu& !E#xj';c2de ז&w2x68{=ȹL@9mqc&nnt6OKyA46d9e#RR,X܃;'ro[F>AhJ}4C_ssL)^Ac2SXcd̙[xbO4[M;&OJAEfoIG?hU.~J9*~YHx_[7tB}Oe.;CY2uo&w?ܥ n~O޽u]hlj$b/BׇaZAG0{GaibY+Ko'̬( kRi)z[ʄQˎy{,`FsM\-Е5޻m..|Jj㹬Tg{#T=)ʗҴX/ i{3~38nfΪcS'S~:u[ ֺB|NR\Xt4Xe1NWh5^N K2v_X?5V UJHsei1“/Hg`M4L [~VMT O;#QDfSʎ/v8 @ʢG6v \3[ٕ7/Jf%}P2OsHo~NSpRo4ۏe& _)WҒa!A<.E2Rbon}X4W\dNuv#VoͳvaXD t;1Ӑod59-X}o?\- endstream endobj 2972 0 obj << /Length1 1388 /Length2 5940 /Length3 0 /Length 6894 /Filter /FlateDecode >> stream xڍtTT.H(R*JJKjfZK@R@ A)NAiEEcssZYk~ygۣ*h"0XX "eg7B`nRvFI/XN4<DIBH,/ CPz!m@cHnG',Ϳ^.7;w{ `P :]qaP$`!Xvb$ 7:p nZЁl&@9!0h7H 2ȿU ЮnP/8 p@WEK(_@(C$=9Py ܰ kE_epWDQX p}ܬ k8 Pt4F!=J!8|p, #,. IWy#_7 A p-@8qzxw)#`X@: wc.~~B~մL-xlDwp/,E\u;\ G[8[E0)7bDsa+c'm4NVnt:S<f~XQAX1_\_1`.G?!(6keqz(Dԗw8KjMm@PRڃ5A䯆8/?*<=p&3)7UhD4봴Ֆhb0l}ek&3o51l%2&C'USw bO|zJ!U!i?ef,HN)מ`4,+g$6qc9fjNCysJ,J|ܿF'69A ۘwrnP <)ĉǷxPO6xS@2:7b0ќ_C8(ix_PuAfKVgIw Y6O+&itzLrMD&\pq%'qgn~+YZ;*&W3]18,8zz9NC5Wχf+Jy;dY26fXon($tءƥ;C4a|sg7DB!<٠QnGU1w|#:9I6?Lxk코NeKlQ3O),-NCvX&>|u']f' >_ V躶`'P  8eÁn_{Hõ2uDnGdY-Cy OnFrڂjBtLs01ZOcʘI-uGTm5( g^ hӿӂ10A;_ŝ1D~I7 8S &7lQz{4uL" ߮-;5rBӳӘfyPͰ4gpasbv|JHCq xl,\fKۀڥi{Oz:AzXByЬMWB'}7Oy̞ȞiZs h.5x)=i.}~ WwNu*ׅ w<4/RFGέ (j&-$v#Ǫӈۚo+9Nl4YlYFj]TomT$]WZAI6޵,W>\=!"$'<[MPw}CE`7qvwbjۏs۟>rkxx4O}в 6N^8%R1: L⠴6M9a_hN{3,$Rwsʼ[l'q-ķSZ*?iQPWT{;^|8{-@B^@x°P"p tdVMtzW9' g3WۈX(> ͡q_T 1}hTK`{Ȉ齧n0H[9e6cN3zO&?0`d#z*cʁ+y;qI9߉}#]NZ.&\|}|a .M2f_H|G\)p%4W |XBL i39tQB[}7X6i5o0?8|}oh6 VY#aNtmוqL;T{9DOzQ7#~Y޲+&=WyJ&9Zk$YIn}kMݟoGo on4豴 # `vVqnr'MNemi5@4<}.WI2?do<AHf-#'3y|\ ώOsNIGtQ}74,rAP'[nS ytOeURC_\obj‹Y}`dQ2#ǧ9Q K5E6n\2|h\DXiKs+~(YvTU'KՏap%&HMn1zS+HY1?nQT$yzu3GA{d%E L17oߚn;w~W '*#6z%1}Z\(qW, mG ׊,xr~Zqvi߼Q`ӳHދ"K |jݱ/漬ٮI`c:vt{tLGk#r^-=qln,U4ӱ4z!YGq%@IGY'!F́"O' c)ɝs#[|¼ySƊr]+g(0=K30ǐKK5GC#7nlA8T.ԹB7߬lv1Ol+lj2G_~:bFx=tWRnquj<_C$?jkP5^jT!J?UFF)^ !Mdl`r+bȮZtnF>= x7{y~\nhj1{sa/lԤZX.07.ԭZC} + y~o-gݑwbKEO>>s+eǨ[ʫ?SOSBhgt3*xTLR^U[pwg(*P$[f6ѳUhn_7J C`ontEBbJՋc"l4sc?A~chU~diZObN@4ϰjH#P]ۑa<&Uw AǼkw6eQ#JժR¹7~X8}>1ᡘ3)jl :V1@rbռ}H6Ysv <8󭜛4f«@Eu q/VTԌp\xwc{>9lK SlnbV͔e7v[cٴ3E#fV6'z;~ +}\H'׮ )q[Q^zەi ג2=cK)U0KN%$"o>nٰgUh 44 R&hSxLRhZ_J^f!)NWƚ PX}]#q-qn;D!rػ2r]7<"W*{c_T8֢[oftU~Ȁ(/ne<T>i"HObŎ쨵X(N79OyM1/% γ> 7C*M`|CL=@UN?w5>ΌTdi`Y6~p0Md,9bމ3JeS]ewB)FDLJfTNvk=:*ǯ5]ߟdDt2 m=)S M263uFֆ(s:/o(^^stj!_7cL[i۵BCj4@[DiW&t.WA~_ݗe'(ڒeCg J̿ݣy)DGD|ަ%%O #ГA1vdfeSD7T؜qvjLYYV'={N>@pq!w.Uw*)Bٝt'zȕw.-,u#z厝Pif6OJ+4*x^-Yǜ3DL"LmDB5+٦AQxQ!߮@ ]?4g EvCF/aC>\lH 9S֣CЌ) 6]AaPF< X>/t{zKxsT뛎iwbNoV=:BcMEtS6ѵPڶ0^X5"r*zKc)stЩUL̵r!1u~>#kxMQҊWĨKFGdKDI~ǪpNe U}96m=Z Bws̹ǀ4Rv!N@Y-a)謆@$~Rw76=ȳ <`vv΅%d^Sf %wW~_o bs `k¯B!\wEZc ;}PjũGjg;wWQ?,O03ʉFWNGƂRヲ.3GinFac=ݺUD`*5^Łm<3D*_`$ΘoLZᮠ^J>/#)@h8TŸ>ڝ."%Y?X@^\R1Ip^}8`c"Yz'm:^&z%I 6=ÌTriqGY/Wl/WTHx!+]W*)ZVB٬_[e endstream endobj 2974 0 obj << /Length1 1423 /Length2 6229 /Length3 0 /Length 7207 /Filter /FlateDecode >> stream xڍxTS6"J5 &T.% Wޫ HR7 R._xZ߷~gw,zH;  %چ ٍ`h8o;! C"$16%0F"pHK! Po CHEȮt9:1} p@|PhNPW̎0`hzFI z{{ ]QHGn>7 0^P{:`WFN0_C` p@aB<Pfw@ p п @n`/ p]-F($&vy}P%(+ 昕HWW("U W0ï6=0wO Do# JPw$k#_7oo3@74|^PA = Aagǘ1,_YafD} =bA]M3}S?-˩ I%Ā$3UG8 9K?3\(DB0C,%W s`W\O4FH 5%]m=h0F G A"@0 jCCb_v_zP=$ ˇAah*# H_b=_<|VRP8/vlwψ ?Lg"ĵL1z e!p3wa?6ga[C?$4R7~ ?W舣a5܁ "ZHJ:*? A:\(,3ŊDVH[3EIžM:!u6{6 E{Vm6s iIq`S`:<0j ͵ [sa$; $d& ?ᙂmtAROGysg*)7=QGHL!f{}I/Eޒ(56 3Az]Rr &¤FFZ[X:%#gH(]>W0=_}*"v?hy膒~Ymo7<5 ,lt85"īm#A68<uL!=alb 1~o'gږZݰ kx 9AMuX㴅gԡ\Jd3zI{s!BBxF;C($H} bdSBɡp.DSg%R謗=e[=Ơ$Tw/=wt#??۲2ugP nŋ6Y-;l!/2O-2S>Һڰj]ZTK'LQ rvwx#/.Mu2d+d&`~HȄUI0H Y%KiD oX PZE0 uwp!.Yf\cdPɪ5r-,\Rwh:Ev܋߷|5 a19)u3ZF9siׯ`*p> d5Su%ĊmTa&ȆedٞԻR#d6ʪV}kN˦28ePDHG2#g×?H3KBA%~g]ِ彘MYj>9;o8l9^1 ,ZWHٝ |5rT<]Y|>\ |?A/Ff4*9c@r;8{=O.oxH q,X/_/l ȶ:ݖ#>8CS2Ē~F{ؔ6H$qXoNd8o;x-U`=,BKOӤ&E44Hq;NJ[UϱSUee /fٮO{2RbeηCK9{?v36dZf[xGK:QkqEWErIj:6GKmӓ|̯sߴ6ڣq׶r @ k܉ɳ aP1z3j\J0󰈾s&W* w\{W f'ɀWXq;0̛ :m5ᅾy) K^w)y%0*7A߾XI؛9cC/D\A#wt>o/ȷj&K تl5Z^ t`0[(9Y)2i (ӛVyH'yoZ"<5F?5[s,eˉZT5AtÛ5םhxWu%Qj\)B/)ZPPڅuB -NPc}2{dZXk" 릠;ٺ?]"c(IHoৌ5:QGaÅWm7$n4V\ C?jKόYd9ȐU\t5>4\Ń/H CxEeG})FƧ[)VʰQ2 ن5s9-~Mo}Ory@֔$sy={DZ&1Np%ljةXKm+l뿄1o:gG%c %0N=ȨYPRU5>T}δv=eT/|Ƌba/̽~˔{LaJ߆&ժT_:НG#nO8H2I~ڒȖ[br{B+NvenF\Ov 1^6i[8gZ⾅|6qa֨#7+qYk|DcxZ V~mYz$zE Պqe@V=o&{SƱz!W?1gzDuzQ_ʘ7?2:p%W :K|^۔H$#R0:,JG䮵b 2zCIB7\ݎ?kD!C~O St+0>b;P.jIt&|l% YkC**|^qA$O!k{3g_bW+S"MQʼnAU}7g_ vqGqe^:?=9WeY^;!X:~{4e9.TH]}vR,7tV nyo[\|G iPwLƌk˰8'봉E.I7^xSwK;J:%}pd-.VQܴA͆E~/"Ce%rX3 &q^AH\q x:_qANMv~MRõ2$c)'f2~J:7:LOi̹dXl?s)@^`Ĩm'(y^Xu2$R?WN.}HE.FmD=sasqa٫=8^֒+⚦|;p ׯ})+nZFSF.6?fɓ{ojsI= q=ްN4>Csnltq~0r,H [!Jǝ?2pZ{^t{k֖}ɿC9WȁZi=uR⭞x|zhZrd|4\]{9a7p%}:,,;vc/}NI̛Cntu *rzhH vy0͍ Gl"Y˜mM ^͵犫u,P FzI4 Ǽy5Ə3U_豶kGFVuLwA)eU\ig0{lF)G|\qp_?KRo}$Pl|t\Ҵޮ66h`m>MGGMm 1TF+ t{hBY悞S#F\a`E##i[[̤]ܰ*+48;޳# _ zXL#P>Azj 6{vi.jϬ'<>&iJ'EEu71,ٺpɷb(ԥd X_hqΌ6%KO},*6#X-+]ɳbȚ Q_l/M:|`Q+{/P/C&>TtY:z,ғuAaZzWWG a*bu@-)^z8%Deq%4u P. KzP;(2%M=ܠa֌v­."5NrX4l5?8TM! </!p=W־eG R%-KL"OolIS u!$B%teB\L/]J*:Gj9^|f*%y`\b^gy5O"L%CuK,͞ZWYHg >qkk`/d%^tͱ#~FQdd)剫"L9JװvLQ͋_*`["GpC']<۷w3^چKP |n.ڝkLﴉc[jw}z}fWX/.>r">NG\1vz1i /,r!}Tﱶ 0P8G!S ɋSatTs϶BֲO ,gb ).ԫ?R%?8Eբ|JholF-;p*j!6y'˕oeɐԂ"g\˺aw:J ]Up^e`,pǩo?$\Rn? 9.Yő[߾R %g*k^+zRW6|\;iIR O]L*-+979o*ȌE4Ky}gTkdyó: bDzf;?Y =B{Jz'xZP0gM|fǻZ7j^SxC"Y&.>(.G9o+RݠG{q o;֤^շusknx]~4jY.ws2w"y  ^vͰ7߷ꏐOk*})sT+g%W jR vprQo q;=7wbab :<@",;ܳY/uZt. {I}l܍'8VpLZ6naIg>Tzd7ͣE\SLxp S;SJ;BMd ޾:T1'=U}k[v/O gD:z?|/:,G~u c÷6iw6&BڴHJn* ȠɇbizE!PVn}Ӷa_Dxt @ZN!UW&(w)Rd5]9E Ħ ^f[Q:<[/S?ǚe?no<<rSZˡ)"Hi˻h*ĵ z̑J>OօC9CI )8%NoޏK Ctv۾>^\Bj$݈($7,F8U1ި%qh b#ml Z>HzimT۟l[l[Imm6Ϯ~/2]UϪwl)Ș+-"T&9>Z6YrofOTx^SC8`7  7sJ/@i˓}’8>F/VFHa5n _kf4R"gbZxӳeA֥z>Q1xvJkJe^菇<]u!Xύ7 -+]w|Tf){Ku JFjrpr)K2'b52^,Oݝ::N7X{)EW0atm׵J=EcқMxC+)!oH7?L>j5cy#I>j1?TG{lߛYF^?cK.'N` dcMK#~" (D endstream endobj 2976 0 obj << /Length1 1399 /Length2 6072 /Length3 0 /Length 7039 /Filter /FlateDecode >> stream xڍtT.(04Hwt8  1HIHH4" %݂19߹w{׬>}cc瑵AXCpO o"'bc3a"6C( /< F10 DjN$,@0&/@ #\0;{z8 Yg(`=#G@`P?JpHأP.@'/ٍ|zP7(j50@ 3/Gآvou#<0!l]0Ww_ "fEĄEPW bU;'uAlC@aP @!ݡ;APk Nhjg|$ `Ƈ7 lp'/TXD!< !G?DD,m?p[@OcWBU pG|B|-)77;;0'hQhh"67ǴPGUQ`dvh1y07%F/9P׷_1 ZCP}"3~!a{/$ id@S$ѯkYO'-W7 `7]!H$}Łn_VB/ȣ0*YO#x˭OLzP^kg*O=)3UyGvBJ CgU'[Ao7&t Q3F?E:6* Z6Lv΀d, 8eԠ9Y<,@V ,L9{,>cp~?'MzWpy%KPRubZwW) 芜#k@t|΀F!YXfRX]S0?{Ool#)`,p]2غzTѠ kN~ᝡNC[ZڗK .MQB 35$~QPܑtd)Shg3xZ @q( ٲեqP+nKu܃!KĜZ X*%9kKܷJ /5@G RQ"{r֭zXվ __)bSu։R =3D)K߯Mf~n*qiq]g~HRT?2S@]|MiCKm2D\(l>t) n:*o w@V9X]} ;ޑ*9!x%Uâۜ*秮tvG';êyY"4R@)%'2q[W,U5}sX1d!9ݔ3J4t3,յ^X1vEkH ,H뚫}mq5nȩVAfCC3MH߂-4Uc*nnaYoPD _~|g*#aQ~-djvYV{.Iǜ0/ܝTنeQ8=kG`rV˖8 4!D%a8ҟe {zópaϙt>> T_.YL.ha8#@GmgHsԨ'={,}Ep `$ 74LKM)^y*Ҡ(3{v]WuWߚK.HUVMIsix2Nϝ2!Uڂy}[;&4~%B~'#*BT@SXB֝ir7EvG~;#֘ޞG/7.>IBdPmGߋ_QHDca%zⅥ*Lv|9K9hr|B!D:驕[Bo"ܸq8 F{5ۊgCP @YC/9 fg"W3Mq x\ "nyyMRUqA ٴ?+~:}upzg |mxeXLXsv3;~Z+و' h^{7K8cij_]?.7 7RآNG˥&Z^;Y@'WOzf߯JWǃg9YMz#Gfyj,Cf ͝]y0%T;STq%?_v;@z氱p0 yʉ t>:JODǴTQ5v\6I3ZM杹[[bMIY&6_obLP#\s W~`dXShوY`g|WF饯y\ZabV~D\zZ,>(N?"x#y ό2j>4]NPc U[2&x@_Hs{!ۺ0lqkU+ԡnbJaJ5Fn 4hx4.nC*~ 0:""T(Ѣ̭"nBۀog9 gN4mh3Dq ^K?./pbn~L[!FК&9)&%*^ccaL O͛vܲ ų:we.<+5Zc rIYW+Gr_zHt6϶ ;RZx;&l0~Rӛm\SjnsȺY 4cLfg8׺d/y;aMKh72'ww] ͱWeu}uDf U˕_I=ɿ0CppŊL}bc:p;9i)y% N~QZ>ӻ1<]ӞmRO=艺r!GGb2Dq*;bγ"/p;puJM;3LHtmKiL,5ѧFmi7kEc{ں]SDU(d( J6|R}`T<Rl~)MO|?"j)sBUзYH1BQCӛj&ipBligBu8* x>/c.>⎍}L톱zdSÎqIkDJsۜ9pŎy["ɿ[zJ]:=+1E#XE줭E_bL\ jg_<[u8d5빌!1u xR<~#@xLWi{'ɘ[xڅeAđ :oBbT0=bxxZ~roDSV~5Ie&Wi3Ac5?050"Q)v,jF~+Q`mʲ@y*E.9NUz 3_W9p-_8Ý`plŕvmـЛ0l f'9cs$Ԭ]w q1c Գ!Q,닶߻Gk}KJ۠פZO !;N+ L9}ߎX*/ӱ61ec1&C#ɀBuRmGOKGŽal״4GF?eבC$=4 몋|)?fm;Xգ7{Xl3I+8cp*-{ TN䧟ԤdRAYH%H0Gė)CJ Wj.1ҨOQdk/޴݉ aU&p ÓzFW;^Wrh,bF lddR9.?sFr$bGYA3His䓠ޱd CNf( ظGT F Iq^23v8j-'xhHt\kO޳̜4>VYw~tHԊN mCU+x螦ȣ[jHGy@ৣNz{A"5+$xc+ ,wIP)؍s =34lYzFLÊ:Tyy:6;kgZyı [ȃl[./mZ:=5?-=Cpr ,_ وlObš;AA>t1ON/;5mu5إ CpcB-1k3v Uc,c;ID=S# Cv$/Jbu &k&wqGfsdҮ4F#7mH\SiķZYdl\WګRlwgR[cA_Saf=O=サvKn5`)rS-Ij38cE[`4&0BS ɊH,sA'jU&ZR"5gy}#&97P.buu'GZd!,wgh쫅SMoqh`&5յĨrxAQPe+!7=FnulڍB,tYOpP鶈0|=֯`#o9Y+c@*7DFm6, !]͉'SezX[G8{[(# f"K@T(w-oaY+2w^&KЩ8rP-*-:7~GlNT]j%xqSlK«ifG-gC~Hk)' #"F-ל q'o\'tJ3ݞnK]@SG=:)##PǢ]929> !UO;Ե?u")s\̜cVAt3OVir:[YFzHmxzB<:u/hO])= \:z(lKJNR;ߐGA<;ůlg҉m*é c :B3UfH]Q=GSc+%ScY|=oen^Y /- _Q: ݊&}yPqFk{jy3wl(hAU*6tK-ay)N'Ӗ{ݯ%VLS"H϶ci~L^KT%bP|x1Ǭ~A"F$eL!{"Gd]{n0J7HM8J-C9!Amiky&.$냻*LjcSdO^ҮyLT<0IF׊[%}> stream xڍuTo6-N et]: #6Ft " tHI -Hw<9{vOܟ،LT`(G& ej@0X X7_eGc(rPC!X PHPD (")+"% E`9в@u74uQH8C#kEddUh@pw܍PE~H+z  'A`&p  5 q 9#0pS= 7"08h4#8q P$t%B CP@:!@CM}+ a!n. AAq+5U\@,AjQWܔ505;~է@á ٬+ {@j!lDxzu 0'8(=p_f~F_0 x@@,  <DD0 t;!d{θ@[0{"@Ͽq􂡐n~q_amC:MU d$$""@))`?A'VyS-nL/x\Q8!X }SwῲHiz6f;^X P8 Gp:XN*H'DA`?8ÌXI 0_\_6&8N>W E~LTBA!~0N} f2PDaq!@\A{(4Zŀ g_߸X(A caQ Ʃ7Yp%[p/ 8EFW0-'-6ɺ'F=,YJ֘]XōtҨ@f!_й4X<m'-iX*=vjMD<-'#:V* /0+62@w`!%[3Jn:A5W;k;jmA"H%o6!ۜޞt|*Ɋ(FZ]܁>FG9u18O V?5}-.ڿj}0tFiX`y<;ސKeOkBj:UۢyUIrnc>*>,Ekw:` -~@$ڣ(/)LP!z0=/wX֘뢖7AX' tԥ^y]g](LBdd-r>ۆ9(+Cد}R9}B tzǶ*3\?jaj_䡵w {嚝|.YaOܳ$bc\( e0PJ GIHöT%['b?ʟy~e|pD=6MY=TN-ĭ+ ,>&-bˣcM $Ffpwl(*_x݁QH9 #薬dϬ+2Ժ-Xվ'A.:4(7Րioa'czB`##ZaV(pϖ1hv/|Bk:,_UJR& Cd+ƍn{{0$nPcyxX0(#0%·u 5WvNM$l>?8X=5gW{{6.Bi5O:S\R_vH"AGz"z.'+CP{*s,6-+/́⃆Z[Bm!-@n` }Ƭke +6#d"Gr⋡ <ޤf!yĪGKI1엧["7ʪ^fG94%ߞ.9Ok7|;f~vE@x(W5|gNEy4,#I# 8*2[v;y{i+7xG52NAWfQO;g2SOo1 HI0SJVrm9έ|ij<^c~I (U~(Z+prVOjSK~,A|6ZIbf1ʢ< at+ Wҟ6of><ʮ{HGUFq3oNn/c#LvF?@dԳ'I,)߾<{Bm6 ^.{g.Nn"qZT:,9SZ.=df 3?5{8C<\j0H5!sj"SQs -/_4lC|P'+NX+' MM=LB5Oő2g̀}-k䰹$1f9e0&5L')'UB[?*uh+lug?ŭ3> 9(K_#?r!xZj4Lcj '|>P, g<%Fo`:h%Ɣ1᳡G% bҠ Bn޴6!!PM5U _P@iq]/&yRFz55<hΟ;y#1LEkOD\a,N]OT >N[tB(6)|p J$̖_9c-o>! =I]Ȩ "nEehqq GJ (]ߦ "&zAFaœ@w5ﭩ> wST%!YDn>~ޱT\Poy7gYi%nʱOɵ'jz(S. IXY1їz"w\q4[`J*xe7l\b-fIZ+x},ז:+CzKP}}>`p y"?XH#l挻Qmc%<>9h!+ "?JiDŽOQs: `JTr?M"Yv?n)ӑVj5bbjOu ƋEhw,oYxJ~ax`{ih~j`fau;;p(eȮPmQ5a3d0BV>jyy3\_XPnG3/DɐRى&Ebp霥gɨ H>zpZ iZ`]by.%~D@)Uܻn}c䗟\8K5R0G7 Y7 _ŒpTWnafΧ/a6~یeKҸ{)9iy8*͒U-oȋ WFQoNkM=}&4UMIب>q`?zCovU#>Q(mzzA~q.#_]^b )Hiu]t=݇ySlNv]P?"BSxs.A:БJfֳEjš/VF(c_7}ևj7Wvv$ܗ= |#wu+\VVy`0VȶBE6xņr[k`); /%ѠifaJa{O_N8fԱӷ2%ʮ+{|}ˌXiyI'Mu%x}34b>x<*ڶ4KTUzk OjG; mL< [_w]ɒH<%2FPg ɚ,F{']ҝ|u-FϿʖ%2州: ), ɶT |D9jr2o\}9{2?Z*iʢĊ6^qdq&3bϒH#)\4ڂr?ۖ /Hˮ2$p(~HyM˦6v{FW)K@jj6`nQ {ST/1ڜq^<M'Z6fsu}R+*<vZU::迈6s7cr>3^3yHx_RdQo}?}ͮqY E*iƄyP4uu}w5(}t'h:=~sDtg8jMa•njz: ZKD(=wDsZՑm|8pYS,'=}\ת,Cܭ/Oؔ gO9/_Kx}$O}A> stream xڬct]-vضm6;۶8v:}ƾ9wxxVUYjZc, e5sGS #3/@UAAhk䀣sY;:yZ@s8 `ၣ9:yX[Z5ThOzttP9:B_oTnV@ #(RH.&vewS;k3Hpt``nOiD\&W'm@/3?.z?`bnk3;w[8Ko__0eGW7W3k'7߬ܮGf/_+ O.S o`N.pwvO/_uMo` `caonKk8Evsw f/ sG;o9IoJʌ}"7H"oyВvv&?. 玱3q[y6@-q3 ˿032U hlff0۩@;k_Em&ԭli=_$(/%E_j(E-u2= l\ο YXaϵ@o,?\ 3GfEx/?n3w{?:4[]r4 tkg w*oV/) s ̈6~gl^9y2Go> 2)j=p҈H44C3`,HeB=wGn-f{ !JF}HAf'ﱭt30eT2?ERj*rA*yCX`hu/pwXpƁx:˥@7ZSI̙:FIuY~@ - 9;@{GQ?;KEe@?<>^Qs *g b.xRpʄޟ4ZAÀš2 apSu=DNK>8蠕xam5qaRr-ƪ/oZ߆'S 4Vw'yiQ6==ff0 _R*$N5m]k foV[w!s-j,:}miћ'89y#ky;|Skz7}Dq4^*"-k93Z CJFfCU%ȏv Wl#yOZv0,&IbG-m2l}4ŋu;!8'2rzaOs͖ߢq@04px$IPr/a%[^H]"axA*{WDa+ Z5K ևUitW\=1)rd)8 Rf#ܸ?30NS@E& H]sjdkKVx4%xN`Uuhnt9sϧ3{,TIw g iYliM edyZk@DR:ƪ݅F,_etPlQДT,Mq!ljX gMHyj?' w`ۂg:di:: h+f}4ↄ)|M-';a1z.Y(:wM|_=ӎ/>lpk=ޭ8(<.}@wԃSy [d\D>&v̒># ļ}@:J/6'Y}54%C[7j+A8mrTBLeRQ5h1;lg-bf*Yw.z+WEHH j4o{/Ywi w͞7)nQu]Vg[B"vAiXH 4"+N~W_9:w˒*%0"[amUPjwU'܇W LŨa/hpJA=75}ELo gSbJo|_W"PA3N3O_3>YqEg9zɰ@ُGT>^)3%̹Ӗ~m0 qƼ!\]_zaDِѮ$yGH/soCR^\G=|۫fO吤("tAlI gػkb tҗ5!|gecp[wRBD;\pb_6f\< ՎdIIJ,La?}xjX뙜tj>A5zGȷP涮!휎bRq},fWUx T* ؗ@,8PQhF9Es:H&fsvݗ4{caokc2+S7~^ N~;Criَ(J_'tX U_ d7rX0sןQmi0u_}s8.:{"v$ vI!M0 vnjIeF9T5)ಐz{Fmwû帻VNjCSϭÅSe)ueeV|b\f.?\J_I\V̶N,Н̟VGJ@6P*s:DѵSGz-xX(@}Geeʰݒ,VKZ\= 7BQ':I%?'GJBCQp|C{5=Oœ/hb;)Miuv ( zw*?A4@9|XX?fYEsd2U [ب"1f(1)ˋƴf%n$Ef:|gڳ*yɈaK"ЎhRaYog}2poflē HXI߃m$Se*\,awպ''[G|4Di"&UKw&!s5/$y"vR(}& 1H}ۡOlП4CGܜb|2&(*kaes(w8HʅDzoCB șj -Mf`G} g>p->b=Mz&g"Kgf$(9tN\NrWrBw<$ߩv4UUڛܧ[+eqt 只:Qb=Bd\I%;x+ [?/ *R9^1~އL'p-Miz2z ','pl֫3)6\Z.@/K%"bW10?EщPJ}0m j*T޳U۵F Ƞlݕx0ѺkSFOvequiĎ=`gKjl x2픶9d 6,~5J"_kjaz- ߫{C:b Z@[Dk-{330q m1MH9W6WOԸȵ]Ex.:H~#|z;oy]"t (bG2DCҗ 8uҌ`R-.p-8ALJ-̯Coۃ16etSGD5:TGBʥe햌ᔦ > Rg#5pgv68c-Q3d{ @=ɏw$1I)erՋ?st<42un҆Aۺ8P͠|kRD'LگL(ǰ46\(&qϨ2E k.sZPQ/;0Ձ]~U4rg9;lܡ>}w:~=Ny#G;dj"o1[׭ۦv٥B>yI6XB_z=]>m=~-Wb$XAI&F6P[V_A4P ɿ4Hunm$aB^5nwԀ )c\bK/·%>EJQ,8.RWy~?{Pۊ:`ӘhK#2 y2Na!`MПGM9cizښ7-\O,Fȓ1ZI/@5I3[P]7@a6ţ*Uk1NX$fE#v7}31fT~!y/G˔vu;H ]72g}tPU=/k](Obn܅ ^gɛHܶEUgҔ@N릐et3gjo>e>Ԁ,]!,9Lk.9F MP $Jmizx:.}&:/KX~ڶ8,n]',[;`JnYZxL+ӈj[M0.SkSm'9$DNV؈`s!$|.x<|l  ]a|q\ mr|tdvFay)=@M\c2pX|Ư͠8,$#Xc`\QW\#sQkꑼɉA[(!ʫdt8yv}U7:rٞ,B:R;J 3e]+12C}:@FCU/אIJ^jhآbh:":gJsbEczC,ϫh20xk{c,s7wTaXLA=%PԴ M{zX?f8ΫHG^k˥W-T(Kc"sAEE͇!,_B&|Z]e /HC|ۂS\!Rqo {]U]}tOHb̥bQA:Zea!GVHVm`P:,T)TR'񊽽?еMc[>/=oZ>TRY0o8bgl=* a,huy8eÛr+gBLDy1GĠ_"|b?<&\#~ij9vau~7X4?V ] ]4.wV2lM%N9BIuipNUg{YwNxk!|_6opjV0&1l;Å?柱8ʰ3NB2Ap+{,Z7ۍHĬ]-\A"k!Jq5m0Kv@`?MEWxAnWr)\nFynz{tbȓ B>5_"huxx"0u/'rf[ޫ!Fme &:NPK#J :d4C+CV?,i#Փ0.B_詺(^Ò< %,alO֒L{ fc^<GS/FyF. ^ɢIJ:C^7⣣(E&B5ǷWO(68%]JG5bhr גY8j8H۠m9̅ aǘ^'!(wo`q]#`Str5#‚HQ?$T|l_w\4^\qTC!>\&?5=ȩ|ʛK$W!]F8ka@d3دÊmDĪd d#oѷL *"^0h,nXUCop宅N<4y%`=0;/7ͼX /D0Ef_5r<mk^c?v1)Z<$mpYQg)@ \"ЀPKVrb!Ch!{mB%0;m鼒 ,e/mr>΁P?\aO+3X.hQr 9Y}$%qEY@‚d~\^ݮr}s51<3e\tFٵ)ݧu,"~1n4\hh8ٱ']JD`!vG9C_mo엾6L Ӻ׋ Xk?H0sBHo73QlP&QV00(GiÈa7LhV!S;-?B U!dH[uj`78}߂fĢ!`Ƥ1\յ0J^m,+Iՙ.#]0jv3_T r*Y"5=x"LHX TI-e~Ktxd[$oO@D/s֧!o\y_l^(iN}]"j>Lt'.dFYohj6^1d_S!hɱ؉wq4R`[_3 m%1X_υ[+etG1 +Co9冂CJO? :h9m?i."MhF_( ucpgeB:j S, % ЗLokTس3]L%,:<8,,oyi cЬQ;IXGO*tEok˺ڰɘtyj+D}?t-&ܑOFιD)̑zdV)@>3FԴbx^ Bԋ-|1z3P&5N \#f 7\}L %b%AU,/O\.NoH3=W_tD? &8ӡʵHI &^ 7L?L#NnU/F8$~cVV1"J\.ŀ7-)CA Ǫ:׆.zy7)jm+NXtT+%wN/6ݫy$4 '`THY0m$hSr;$t܂l♎hI=K.~'T:Láԕ!^dBSc+:\xePHA!@Lm~#C~2))rvFir=cRrw. #ᵠ+#Ѿʌ]՗ NK'g|nȥ@ohJ?7>F^zZgqSkfrvp3Uxw3W=`m/% zyRSx 9K4fA *DxUCA9]L(4T灤?{}V6N`X'QޯOؤ`чU"]71-^.F"X`=ΉWm[^~ωoͨ+❊ffJ!Օj`ec7:-BE-!MN߷.0{~TU4$'tKt8tO] ߦJ8S5JgiSeWjN\fFwix:Éfc~Lfx io˳+FWpf9*ͅ|s=kilm ^Ӓ$xtx+e5xfAwP=z[0Dy~O]VE7j9̶*% ]Oc+\8_~$>\a/y@/B{7Q#Sj4o2Ƞ^8as ) -IZ:1ڃ9]2 LCZLiQP>o;nY/C޴1Nvx D`XAK؟d[ǔ'*5Gy؜6g}T5a2u/N=*R&\֘æ|SOMX5q-ȹ9t<<~łmv)- F Z?c!v Duz#|aFv&8tUq f|9 jDZA)=o[lS6^#"Gpܯ,FrMgd,Q6S!2oiyurW\T}q'l403gYs,8OSu!NY%ZQa|JHl~_pr39sީs5=hS2~縩GAcNkqn3lś,W?DZxμe+Xt ?pW/Z?(+߮0E7pq.;5oyȇ64k>ODKG-Akt>RWuֻ{omyu5ܭ[eYņzuT'VqyS/դG ÊDvl) D<.9ɓݨ{8<xJ1B &Y($#&7.|XϽ &ω(ggZ5׀YS'[$^vʝt [1 F9dzɋV#LL!`'Fij2Q% yMVoLv+o Z>aݢmw1][I TuS1H&P#?<H(`ʸ_JL\8fn#f?⫼ k&ϥmmf/4Z >\ѥIA;޹k?-ݣxgWCȥ_dAU 9JM"R%+ˋ Ќ]iv+Rj`2knpa̩!\!@{{YYHU[$6_%\Tì 9bE2eBo R!r3ĜbB _1 F륲Sna(5%i61f:s$fx<銤=(tX s3'Qn«7(IMhւ68c QGC> #"'Ks0XzS3 4A|Z(!F[ꁗG&8=ɳekU(DQ$TY(Oki' coFh0.nE,no1hUTU6$l W"4UoEqh8l'#(nv/ ֈI/" &*G3Ul >,Sa)mR W>iʜQmOfuIM].w,:)vk7ÇO=m*yv3 bYSi-/ōxvZ1eg*zKU@>aw.u6z7g2,Zd8Q.7=:n4YioG]Ėw},l9B-ؙϷzU7j?\M ?y˰I9WwN &bb9'8j?jܚq{E)EgIGF_׍a@K1ϖ/lNı4_wGMiH)W5(7=CB\_l<@zkPf]aQ|FKa4+C1ujznriL/?S.iy0I͟o= 1f)$o7+Ĕ֐GM.8(4 $/Gw@g[6A%J~FX1`Q0vH m*R2"ޥŰǴW/>69)feQ7Ҷ`.QSl8]gƂdNG&ΣnݵZ9Qh+ʼniQub㢷\vתdJm_~bnlvͰ(}X*U@,pę2P zR:):éLi-|97DEyp )1q@.CٱAT7FW/TKW@LG܅@5r|:̇PhT!S~]NMc _!Wunh&~+>NF:5֨!Eh^Rۿյ(}oFmWVA١O E  ŀ @B JP0KHhGsS0M lv1KN!\$ fO&!˶:}6O_0o($'lO^9S`#7ށ@*uIFZw`"z)2z5U`M4ėæLZ\r왽<'Y% `|Q: AQS2*"m/rRgi.2H ov%dzTOaלcI]5KH㾨It7Szפ5H]|⪧frup]\zư\e*'gXMj{E=~XG84Dۓ(WSsN`X"$O!y? T)wT6$iHt)k$l 4{K iQPbBٝ\ȏHΰ5hm"RVfU=-706U+?]dy2˴2MJSXVNI7-BE0/?Y*Dy[^?|}jQ*?>^feu Q61w&UN6aЮК tsg2C.Σ MA4~u;Ov~&t+snss'8>3&=A i!s| \tHA4'b uJpP)6vwr'Ǡ35 EpR/_ʉ!ލj3R{XQg ?6a)tẢ8XͰPzTm:0Ve42ѴX4j_F q]!dXe"q.5U N2ahDR1K4p_'i\wbNW! +Aͫ."bHj7Cag Bw2N]D6;6ѭ5R+aILk&m}c7.S}7C\!4rYr%D1wy"˗ty/?c=gxP 'geVUR &o:·SALvG^[?-2_]OIw,{Gw;i.8 ]4A /w r:>89i}?WL[=g)v6o/f `2s1%C1~FG5W EhRCz~+N;k9\K.pMĪ'!UwX1j^_~b̡( V?x ԛ-YX˰Pg!3C\7*J]26ҤkXjwua!g3&i$Kë ?Sß %Ad]2vx- ,<6t}OdbcKAJh" N)*QA@n&n=SC=JiظʳS2a̡z ŝ(%cgqEWQM}Jcocy匭Rƚ|`zyl+ ,K`ֻmoE 6t_6AXof3LE`7F[h\ is軇 Yte܊F7-H6QDGO3Y">kblx0. B٠#Ӂd qa8Q#zd$s MݽOgr[K',hd:6SLLXVbcA8OxAf5E': #CV̍,c u /*݁(9S@v@]kOIhOVw+i֑i5g9f^gfs [\}2ps} Yڼ|GS+K|Z1 Ag-1ZXʆq1}+ j 9C9UnX-'sC8ttE\^"?U }>fUA65 d@ ObLp`J<[>J7DIRӡ{:B-%z?^ hu=i* q$}ZH.. f!$nS]@Wku XdBN`g5b O؅k:b"%haNF/`- r`г)Epb Rj&^1adS9ph $a+>_V3|=6iP4ު9RWvVZ b( n%5]$$wP؃+/$qxHG͙M5\x!{OW.6$E2 \*dܦ RmĖ uU!pgvAyS:?PFvxްJ4PN/< PG3n qZ(O]-$.8nu_cܣ2O>>N\ѬI=rM9ҋ {M4?28r: ц>NYdiE)nX*Hkq].rafn+kYkl/፥@u?D5 (LÎE)y@wi+Ls&>tuRiڦ5ȾbԊutW|&Lyt6PJjHՇ5o\*w} `˜([ KЙR- U/5,֭nF M%L,gT0n *E~%Deqvbe c؞)U*bNQ4i/n Ǥmߞ4.$F' +uU( vO2»v.#k:Ѽ7/:] ]^n2эr~9^GLZ{`]Zݏz 7$ JIq;oTv;Lkϴ$n5TJ+5agl8"5ݞAA!pe:BbԀ2{X΄7'N0>>X\Ptbyr~c9T> w[L}f/ۢK˨6>Dw fUƀش3e=i\0\<5R}gv ' C"|1D^&p/Nr0,X^Vw*7ɥC@8Н+|m,A3s&ܳې$Yl9b(Ph!]oIm̈(QŢM }DHX W[pquL!ܟ3ݛd@D+M8Yowc)K7d12hZ ѫ3GP2!.t.xVCF%_aYfΰ$~Ndl0Dc _N&J(.I3[T XKHWniס+JnC8'!6x3;u5#Tj+ġbhhp7;yqH۽<,i3+Yqx\&屔0HL6LSY)I\c`4#}y4#W] *d]c6m:qf_FF{: qo [> f YAJw;;໠z=vrl3ڼf8ΦsxN\.7%}sfaDBڈDߦv,au*ۍ@_(+,(/b;Dm46N>?ǎp jAq6y~܄8TN( Z(練#AauLcdWjH(,Cd7@UwN샟wI`iͣDq$!|]EE L,ʤӯ4WK A(!ǶV75wZ(I.шP;B3OyC9┭ Nqgu92  $m3{Y~AxbB*S{#զ3-C78@WurpOm}aTP}{҆Ywu?`@ ~\G70!1ذ \nbop΃DSY?݉t탵|MEQ!̤zmI7LÿKĎEI }i endstream endobj 2982 0 obj << /Length1 1630 /Length2 8314 /Length3 0 /Length 9150 /Filter /FlateDecode >> stream xڭTeX]ŝnMpCp'8Ah Hw $>ίN)9u/)P!P}0uSbUZ:ڂk4::)0 {c t7@3S@@ eYZAZ:L^`9?8m>@ ,@@,QVY MlNϭ@f@; `auۙ~a{撀L9 jt  ,&v@ ;3['<-=C30 xΪF:V&߹!g`oino?33 5AP+w.S q5q{L) W,0ln @iO_}G&nx`Czi}m Cc,vNN?b3LEٺ́hl9GKqU6=2WؚG' 3u7wU<EYVN.6 h Y,LlgǮegۂs0M+o^^\gבWT}^?ϛts;[{~HJڻ>?'׿_&P0` x_'ÿHۙٛ 6s5s@39{3@hQVN j/9e>ɡk˃jf6:mG^4L98+|ٍ 0Su"=",Bl_9Zї]ז|T' yhQT2dqL^xPhnaO$d(BŞfXbs"E A*.u_~5g) ;kD3jΜV/_S#L[zLY4S(-gnU O\r߮wtRQᷙ"iNyP#V R(xi=]PNخ/Sh[od#gӬKzyAn=u.< !&[jS7I&Ҕ;_3hVN* f}slc;~ÚvVmBp-90_ \R8Xq*43Z i1YQJ$GT[uSpS7!1ˎUX\ÎF1ݶC˽A@~ B6 nHoڽB;t Hm9Z2.!-f=NWR=h$[&0e#R?<h+BvЧI&(8OY-0\32xr QiᨭfJHVa皗q@xD{QReiaAHsŊTAsvր@ 'GQq\b-CAeHuJK*quuS-k₠F_`&G&k5|vMZ(ʒU{,Caǜ_w7Z|dN>-f`oVvu݄Uʱ毖]pih̒…&9ysF)_$*O;\WSX9Ba[4y<ރRnu:41haSiҩ ~]^Yp:q0"w֞ ;{Iwvf&<GETs DV8?E321^WKf-"Y;.rԳ@3̄Kѧ[0?)}+vz=ڟ. 42+E!vצ oP':{GxxP:j!vh#rCss0oL:rvW)BğX%KxSHQx}ʠZCQBӕIQ?'Y3tCXud}雽 ct+}RZNwRP …A1m8ƱzOlT鯭H!\Nȋ pwA, 뼂hsvBPO !Jj.o0ja0V,fT.D4J8:a!+.hS9D?u5/(#OK2s6s{)gOz5G޷X>+ٍ[%+-^28tC-T(16 t|wS7j5p&3#tOi2s%5!HYt^gnM+2O}$-O#8QyZ.?eڎЈ6rO|vބ^U*RHUq7V& z-hp,CdUIQ3[v)4?*&h mke>@iV 37_eSOMAj^v7R|h!B+g9Kߝ+=z-\2́=ni^:Q]zv%KMLLwJ|oe4W^ {Jzqa?vnkZr͕In}ɘ4tpe d0`ϩixq"A=p"(jarul1|.՚}e?r"t?G&}:bXbgct3O,T+}kNVUԱޓ\݈v4C˿%ib6l' "Ye([vNZ1 |s~1Ą"wݶv&ZH_Ocl>t K#윬iq,H>da\Z#TЭ%8c>ݑaH'xV6'y\(~Hi=Єx婲;U-=vh#UdM7Nƾ@n/4Ӈ'%4{ei4Ri\f] ,w~C]4g򯇉+6 s_l4ƪ!u'5ky:jsՍƸ7D7.S_+Yq^DVJA~c DU+POfQ1R5@ZR ɤ$堸iz۔#TG0ɥ> ?q( dBQ/S8ZCa$%Kgۋ 8c!Ɵ}l-\6n{' 2%/`Di> y[P'>ט9EWs/X.9W'ظgb^XFKG2Î ׋ 2:j*^b|NВ2{H~"3 f嫥*62ў.Z ;I[üLMm!\uK|5FpSZp] 'j^FJqo;J(VfccKJNXO$B(cT^_}IPSGo9@ ;Q)(jEJb > u&U+x^{"ZZL>.Tp]#|Zb|{~LdHJ>U)GZ)&N@~yt"BuAN{`̸'q¤\nڙHjNJ&W@a#m:5XX4h\()6 PJ<$Ğ*N &x *Q<. x#u?F.xD#.[3f)@%2=儨;V"e9քPzS:@q8"ѸFk{"VώxaWn"[T0D(>iP4wEoK IlT ߄=Jˇ\E/d2tXa7S2KF«?tZ%Yr2qKA* L>>}: GDW17' e8wmntMb)5F-5#vg?"i^DCzm08Z+ZkySY*_{uk#]gDȴTibh(2&t nƵ26L֓iEqWm Mt̥!w+X&YGx$OC)JB5ڌp O&ދSgKMɒXl  BV#.O]~tW_15^h)L;]nfvd Q2D\|#t!)S!l"p*i,6#u"^SP۝{+&T5OݜP5q|ynsW8Ie<9:nzT/Ip{ fMxczXeu'ٱA+[ RS<:)hW/6>%Ic%G*(>2W*`o0 4, aEH:B1;ۖybBN)KB/Dw!mDWמlRLxd? U/68|q5%%wuzYMKIQZju/?fKa/ɷb yBd]U!m{lј;U҄A絛NVfړG-Q׼z>7sSd#MS&=^ןr*k4EI^nI- '$e9G,L}?F* JƒT|O3!}b <S`S_yMDdP6Lz#x5uQKcy,izx9Hة Ǧ]/4샍Lx&PxBr}aSR'Fd~Pʼ?5*V$3'p#˿q)ܵ;V);u„X{;dz]땩J8uB&(^<2 |EA4, %ǵtd5yUػ]a#_]:Aw¿.O'MnDpʳ6ϲ<鬒-&-^iyYȚ;ué.͡QY03o9 cDB /!ғ=Vw)C"пdrŽJ̔#p/Ȳ+ܻYȕ^;p}3#<33R2;P$;V*m&K\ KddJ̌w$Qk0!f܄&`(xJSx|#9b07ؘ YVSGfNDC;4cq&`;RZ*j +}e ;_ H?XO_D[>t/)$ )ƤO'[cvv"[=![sIqe1X Pw=rb{-?k~m)QnzF\eG֧]E4'3.6QzBC._(78Ўzǝk݄HeMK QemCՎAۋBwVp_U>g-z}=l [XS:^~#:kZѕ79CwZ$)!NR;dqM Y,i;C, )gm=EZ/Q){7K| pW"V6 6֣5V @fa|孴>R TK1_Jl*?nϺ`衔q}dO1pj9ۻ ib5]F[ejBL_iຠ c1n1F/S&Eɕ!eY< MAUn,HQn -v |nKь";dnIJ@e+\#ZBΧ:k$zORrZ_!;vfW#2<"}sR k|ɛ4ZpyG"s5dq×E;BA**eKsK֝k3[iڎrcGHk.u+Pks 2ap(k%[1 <tHM$~QqT*|W|YLZJ!%hGwI[-<'{]Un:qT,4F57? F DжEeA>k?J J{~W^^@wpM^^VQRWG_q;jO D%,;ę g7$0OfiXfyleIr:T9k3wd =bҳ_uBF|Q`Ry ^NÌTK68i]dg/:u$|54no of`2"Ã>k=kD./kltvir3hx7çˤ[p=@Nؒ`{hbEqrӁ;U? ٿ  oć*7~/gK>#ײKyhBg))Wm%9͉dzœI.X-HϏUň 0!LJf&?-|:՞E)ߦ\<\爄ɭ+ZIk9Yp "!?t^5gꃻuke2JPs^MnWFf^ƦxS}fxz?s@->=??aA"ZYǘrmo* 3Z55ⶴSp=n).SĄEEj-K'lRD*sFaRXВ=,w @DLԗYE5 ϹN aEAn~q"~Ѯ)DxOpNXP7\a *:cF9۔ aQb+Y6M=.޿of/ ]t|mh~|jV񦸳FژGy{4ǧ0'֦Y풌ԎXEژZ{d=+BG)-o5v[j*L|7LX'Mꊥb(ۭmbBW2Mft'q&?HQfVQ\քas/)2Jj҆+g_s/-~PcGF*%F5{ȅY̧6|n 6DPr;I;< .CRY%MdF,ۿF]Y"FOk^\Ζj[➵a7~LOu,Uˑf=j&?Wl8s+:3fTL3zYnΐe>S0+.*A2ͶFs#TG%䤞(Q{ dEA1?(Jn R@sLn}~t]`V1S0V`w'hԗqM1qBSu>̓RpߥQ(%۸˺XgFVLR,CWj[G')-\gY7穊+Zt؟>%i`EٗCBw\nEecK~G.7L|1g? 1.NqLoj'=Ԭ I6ra03_;^sMTjhxp\@oI!"YS oŬ'XḸ&ۄ1z!7&@.m&IǤhE2mHխ8!>Ir)06vedKJsѕSQ?[)' z- -⎼4Dڔh{%լ]bSc!YR6/}7i)}hӂё qKW܈)M>ڵXKhi^踃J{*jˊq~ endstream endobj 2984 0 obj << /Length1 1608 /Length2 11875 /Length3 0 /Length 12708 /Filter /FlateDecode >> stream xڭweT]ے5Npw.]sk%K N|x_~?{U՚5f5&WQg fv6~+D,%.6`  Hv>>>dj@MO_!3X4o/n@{ި\K{ @BYEWVI@' ΦW3{s9,,`_AXް Shn atp:;@ o0dnj7%oB7 1wqteUOkSrCl[y]Lm@ \f@ -4\!6 2`8L-_gV߻Gޒ-[n+2_" apuO53o$L- {OU @S'AyoF_BK+: ?. (cXS{!_`?ȺA d& ?6i5G5A@g{M˿`f详,<fUWVRQg(7]4<߈G`Z!.x30s}|;ll>.>!@\+8xߊfcx2)99Qw1Yr:;)i+?94G56MHs!aq,(\O +7yaii;r|ޑcNRcҴd d5*FK;֎>UXaUU3~=gJϸTw~)ux P5G4wÃ?/{wHcL 'x8ԛ?3Wg% !3L\0oZ'>_k90 6hrW'*/Sb<>I!A_0^߬(9&$.pɯ88`$n>9u"چ%Y8* e=iZ]d_E|󶦌kYE4V W+;Xq(sj>4(yH))G^n:D Ġc{e-̵p8jSYB)jÒE**M,=.< Gm+wRcwL2Jݮ+:_8"x ʸ:xG:⾴$!ߎ]KA_Cg 6!.b/!Bw#?=vOW옕m%~XI2ÿѵ5:)/D0ޱ{.|t$ܴ)h3'bbi [X/bjįޘ(:|d?r~5/{ f;zk -+'X^gƷœ j$%UW{t#{:g*Lh%ÿ:w.$Ol3G-G(=Na*Ia,o8Z[9ؿP)|ܫ*cѷ]|s͟#IkRCrM%[EhzCӷCf6#y(_\$R𪦐 f@|v?Ԁr&Aܪ<·HhAsr͑ٶ,E1"w)X|;_Yx0)s]z>j^٭o퐏NT.YKX;i+3[kPh 9_mb|A>J#=N^3bS0/qq[qy=,0'N^86q:|6\I=8%&hrٟG|B"6R'/2^ 1OB)!\VC֯>_ŏ.+Bg*^sliO;nl(F}ڝY ͇G}bG'i2Pd@{WYW.y2f&_WӶX?mdOl1 H(&UĩʲʶGWpOۡfF&t2^Aֿڟl;z{Goz J.ow(-ph ܨCe p?#,*_X\ !1jھ']Ѵx )J7s`5-3l5ZS'Pѕ"ܓgCtnq~dr) QRk{ڃeWN&txr q5Y= |,`>; ׅ%VT<`J.5+N4V/7G=O,ޏ3NO%v>T f4щ)iRa*XOtLP V\vW㸀QsMJ#v3M!_n{ 1%Ue)3ơ34첡cZJPDgè8ݩcc~9k[P{?{-?(X/>D7 pMJ3ID\ȱ|3^.uB,AG6Ώ$͂Ejc.S[E&6 >?h;.ǯ5*m# !9EtOw0V+>gf :JRz?C+O0c4ߗI_G" rqV'tyvR%Sl]&N%1GsP""<>M^Zd4[=< fʔN&CIkN "?i?rԉJ*b}M 7Hϋwy*Y YvTh)sX|rcV)J$F{$YIu9l>S|G~Fp?ʃ5.kWR-)vWQyHA mL%d 0^O+ 㣝`ߴ4%zh wYPbB+oY qyᲑŤ]þ,7蚸OT!cL9%#/Y?"eRnXPbMn#j'˯8&+GȥDv}lYVP mSqŁ*Iz _jٕIb 9 3! 6i}= 9t$c ҶZZfB#QrBAPa$p 9ZNIrlX]0cGOCzvb,=Ҁ֗\׍zReX%ӽ!`κ šŶ.ics79j! $>|`AE occQK-Z6p֨*. bxYt[J¾۾`FmsjZ+^[G%\yR=t_͗| ͛x9˩FٻjP" x'e/Zo `k5I`.|p,/}%15-KX=՝&\s~njR[3N׸6hUEx9Ig\Z1?݈S)ʧhC?a6%]Pz __oRɣD]Ym_ť#d.g7X[_UNS\G擑>Igٿsil%D->x}BIߞXx%{1J I|VsgNIͼjTקV&\ ݸ2g ?ivflhhvV܋]~Vr_q{Mz,> n$aQ[YqzB("[U'ȑm4BӋv\!}Ɋ p@ 8;H-'R~- mƑ2IqꢬOͫd^J]U4' &\ڣkD3ol5˴CmOw}+xt{I< Lx'D;(*z;I>/蹝=ʅDwwLeakxg qh ynv-7`asNj^D7dyi, zքns]+7P^}̟]MnZ99&T1qF4 ^r}vs/S ;+miÆ`W Z?Z9=c(#+B'- {8٪gʭ*0[krvt?躋FA ԟzT5߲nKghCq;0Sѷ)02ɉ4O†Vj1 q5❺жȩTm2a-Yc-~ qXF`Uꐄ?j&u'#]<)UǦ6?jG*õ|V‚j|xQ]|"h;eq8I{qNR /ZVKshX !wRn}ßN3-(PNꏽlI:? 9QJ|סK Jޚ6lxEb,ZD?U%)5FfBgDuAwt)OS)\ތ{bw!QZ* ;jWwJϘ6κQ?8٨+x/VzIb3E(`Ŗfl*&.U=r5i Gx#ڈD!@jLϼ%)2~4kMa*-FW@tߊ2u!ʑ{VgZPZy>V |L=\b|@~"X{EݏKD̄{)YpWJyFYMSz1kSurn&#/ REqd,Ntc3z t2k7=rRQZ-Fozaξhr%[KDPZSI왿8Be'œE+YDKj)O:tvm=5{HŹgדw!╣Wm䣖:fh3sVD?RyD2;@9LO?l8.OHo "Kb$K%k? :/??.O}LLjmen[oA=5O.FԸ+64ksjj^f[:lyHSTz Ce@Zh|=,;LJ*0 Yt~{*)Z#%ỏX/eajR/3Oܬڃ;aqtLT+Av!k:?z g;C-e5wM2C_;3!P3}4ɜ-#,x%.w m,>8^ VZUoR< 'XVHVe1KF6?}nE:Im 71(lm&+| FͱwJ?hvs# rj]Jݒ4ػO($%M)&0]qysѻsPzz)_ԫՈm{끾:wh]?.O]Xu7VPezr|'TJNs!F8a[B!ߟ^x3s:T%>B ,;k:oiK)hݔ1$o*Ynʈu L]C"\K9U-C-.$#`Xyڅz!>;/曆) 1.rߢ`gZݩhn ҫ`bF~}W?[;;pt0:;!7ߍ_[k'U`+Ei 'T{*Om/.2@Lߺj>AxQ m{V}WORxed|G:lSti,'Hʟ$!Y[G]09|wK MY43`-T'< T]\J]r탏 yW#,l"GU!뺬0]y0R#켮ޱiOp8\#SIߙ1T"`u;;RHUQY'bkZgLP6ZǶ{^D|xUU(y+m|rP~.Ф/[)l?t:nG`bt1>Gߋ 0_R>'W%ӝu1PqRR#I$7&Ek9:ǬGؓĬ=d(Ζ^7"] 3|&Տle86Ng0{D$䒠[ߨqb~ ? }UѠu~U"ߒ"`6Wl2{WUPNraAn{HB$=jharQIrKC}e~<G FNxG_:;Rv>:2m$\*\&O9sYfAG&_qΧYlWYe)'NVNK=3L{ZB45|Vai4ŦͿ̟>V+h)HOGF#w2e?P#أRbaC')uWl}se`@G{Y'x,'W?U%$CX֑mG)Sjfb zs\錸`LhWRT].PNjY<:$^><'%z'3h[)l^KMWyW L^tQjū:KCmat3E9rsJI8ȉכ0g䞆W(rP'&rtN-٤>TX8o{ Nd$oŦqqxSf7{_Q${̶ D =;LFOMi$$[,uCGvMo ?z =$ qӊܔ -R',s GQI8dH&NL)=Nh[?ex ~yڑ%*Ί_HBj87nLgݕBwCmtiz:п 3JC~?- *)"5H4\*A4u8HO? "^cRsKr8QW\W#(|͵L2RHG Y,S( NZiTrq<[`(R)uA2p~EC} MV8Fӛ?f sgASq`H06ŘȠqs'$^dZXtfu-'31g^؇z>gU2p3ysŞykY-LW.e=}GCŒas[ZCCc*µE;%VWr`.fS`!㑐Q= +&;O s";WAFAeܥxW+Yehژt_|HIshpsvau9nu-L$z\,xsd-{-gd dTL"HbY~e 4$T<OY۽mO !~H# n#"*aDRC9kS _*?XxI3FETw{0ݾAMGX5|m R!U髠= .:GV6@Ѝݽ^͵;ktyuYz&oK * 8 k sHY<">k.@҅xL+]pn6v |$EYf4=~.~a6FIq 49WstsA'=׾h@%'Eݵjָ)C+\5;(P;']2b<;X#׺J:4l[0Э$\m({dVKw5X3ֲ? 4|I/6!&bz 'F8]>|\Yв2-g6H.'N1u^Wӑrzؔj)DLY}D>?A+N?o5^H%F1SYI^z+^Sf"pȯi9}peI!4!t;O"0gATJd"mo-}gGc [gi?P߃F%@N_P[CrV6Ypi$lduw1Ty'!"DF 5` SS\x)d2I%}F 4 896Pd_\erQ%.;ۧnolF;H܇O WCR%]901Y{0TdhZn_B!`wRy_XWݻUsG챺!tm˳ ̵DN^/{ҬO_tr~;`ڄ!LM*Kvmti$#3yGsF 9s-s7ìjUN8`|7w"QSщPsb&X잊#~C=ˊ,r+ܟq<0ď{a+#{&hdKv@2L(2%,Yb%sm{{Rb`@쳟"orhǴOk/sa.\,ʺ&?@nAu|Y( r9юk&rno F!|9|F˂sRĶAAθ,"@q]-V K6x8HL61q|>r\Kvt na~k\y8q9'G14k+qn; fyڰ0uH8s.yINgjnKfPW -S~m2hsej44xpvs6e#/CgeB12̷fuR 8 {xT,3J Qd>eA+a ܚIJ4Tcp'uYYΠĶ,WQ%Ƶ?IЮ0bRZ~s(!nsZven',cM=M9#b{ԚbdʜBō{\UP!(Lj8RίnjhiP?a{/5 nK50pލǦn< J Ȑ;jC6 I=^^eMv}:a^XOYD'2(־rS`@ )}@.:"U]/.Dʕ+ ^`~fWEt høzNo$l#&}Ѹzb$6%lդ)~\#ni5OM{Z3n3N \m_qZߣznE(հ<$}4>ISVس'5M GҐo]ۃCo8 endstream endobj 2986 0 obj << /Length1 1625 /Length2 6602 /Length3 0 /Length 7426 /Filter /FlateDecode >> stream xڭWgTݲFw%t"&% 4AzޤEt.M:( Usu=3g=kUϐ_"h~a!)eFh+"JHuqr*h8 Fä0(P%%%8JHWowcl` wM~xœ.0 h0T3SQ`;a @@JPX, D p5s](G4h$8{@#.XLB pW4UOY/h0wn"P$wI|X #P@4 Q`oln,; a/|@w= C0XWQ=m䟨rQ0g;"alN =,;$PX/;>OD8{0;"A$SY?'@y]Ъ:`d-jE0ͽ>u4=V!p*ۭ?vc,wg8UOCBB9!N.ʿ1 "ۭ"36vŒZ~(*"1@_~aQI vJJpun!?_'QA@Cc#9V󟉇00i$D:1-3]s7oHM0n_kIQa~`+ -bY:LaDWԶ5{ݴ])WzU ii}!/CVWFD NA4?\ɞBRS4Plp%m{ g G) 4y YLp+EyU Bi3mi zU,'KSXR`RWFRW653 +R y#g28B>A(mBh_ynf`/ꞝ~ I] 4f9C,%("HZy27+e#Υ*C!e]HB삞l)956No;CB$#qU.͌u<ЯАõKX-zA'q5| ;&Es%&CԔ'<>Y=CANBAƓmwh"ZԋcB&;D$Itls &QKDr"#l 䁹 2ڲ;캼W/!8OhSN)j2'y7LHy~(@oBu#  ZzmiY7poQuZ{%Xsluh$QIl4s׷W<zׇݷd^D <'y1uܖ2W>Mun*o8uw%WyH)YT\uɂِs.sEؽcfx#ͯȈeaɇZGm-z^zg?)?MpS$\/G[g[)ĀoOgg^vEtD6&)RifdӻhZ7$,VdL܎2Ջ@Eu.GpQyFRUgmL`B9;KkU-멪m[.70p‡蹢aeW'i-_Wc)A쯿#} dյo(/Yeh[3:j/ !Ru_P[?XY}\ Zش*ޫ #|PQ]n5WQ/̘`|B!3o9ń Yz^+dAsx2QR) 96qֶЛN!]g7*źY.Ҹ7}]ŔBj *aPf'M$dT*IY¦CB; 7kxky9 mG]Pr^@LfԛVu,NSu7 kD7( Io"}V$!C}V mn<2ګEz|᚞|Ԓ&D [faaq^2A9*JCALI ndӋBwǻ s&,2 4z\Q)oTQe_Zve^מ<02as rITŃ_s9xȪO&:p;>(98eᮇ53 `9E=t%8q @u9uʂXcol*,,G_xyLLbŠwZB٪BOM m+Sfw]פe*裣 XDy ~^zFrcs!zuhx[`̀쥜?_T0glՍN<έ$g21n ,j3m!)ߊ]{[igDMzu9PfV^fg̭72jt.O˒n|7,& JLNyPz'h^D;ahf}Dȉ-ᚯ6!!NRf9Y@yA;ǵ}Ӄ{&x0a'k Y@ZΨMō ]0*n|LF ?L(B$ιQf% \ ਋~V;- U^}rC?THdxvz w0q=EA_ ps\wC#H3¹λl,?^@f˄aޝJ>y)Y#\gG9`Ѧ4o%|#DK3jUQ߇ j"qgujeA6JΝi<ۚ,/JVb~EFMޡv3_@V˒mKl)T$fzL_ 2}R+vRO}il3Vf yԹOe}v_NCt.c@Ky߸,]W?#36P2gjj/:KEv0i~X3? y&UDgK,P6KS=i}z$ yT`0g>zV$jiVd샫+6z@TBi͠ثٔ=ɴkM@'kod¼y"KUJ>[7Nok(6_=cL׆J<~]GѮ<ՀYyVpx?1r`F;A1N8 V HtsnרLCxgV;ϫ_=NNE_ֺ%c']^(jYuJ)?g~OncО[Yaڤ^H/iBxˬ3~"TQ o…|L,z-Gk-9a@V#0\Q_,ڨ-xf?=ڧiמ}gd沐s3C!r킷uLX}q< qa5@BU\m1 @0?hji(?=hRnFFp_]*6z^ԒlhH3A`zlNFya,EL@xSPsD]zJsKky>_9դI/P A8ƨhG[`d )7j(qIf]K\ŏ`+<3Ky{&OȢVX jֻYh :K05ߟ푇Nl.FX~!e%*$z,!v\|Kpy߉"ugyݹL{lV&SEYՕ͈7?$[@?J3mI"S qIdQ P(3+AUӇc2B7bo\p{&zhG E9FUcJ`*yW\9Z>wA1nt?zqڵm忊5͜?4ʲZV|O> 6_щ)[Ы~7s)S%XcE JS؊DY!}'4ĆF0[N&Pj-h6R@ܜwMZMz*W\,zp.y2VΓo~ DJB,^ LV隫 b,>av r쩭kg.1̡zz7.g'Z`G/lc`t+nYEsiagD ÓS|V~Ps&$Bޯڱe +k,ɏV8օ𶘦9{JMǧU<_y/ aV%:? J$XnnIza}EqqVd-L/AM+YjEM f7fSZ8yG*9VuAvt{CG"0\xf/MkPFڄn+;_F$~,kP_g >*^2oQ5.w_pJE]3pëy_űZܺ_ٸL.5^InJniT,͖}};f k5lf^Z.Rqch"jݓls]\rQ@d^UcMT9 wrQUC뀄“ęɟ/\Жs)JH۞3|Sz xBSk?`XnVUpX|ҍ+LbU;T4n|sfL~uӎ惍8Xڝ.Pq6) $]ze,[~H@,LK}a<„D}ŧwPȌ Z=э\`)Wdg~~h0fv#XԷ :]-oJ6Kdu.A&`upƳC3EV&r㦨FIK}IJ?GI-xZO]$Yg*Iwc^3s# /]c_G釵=Y~Hݲ$lU#8i%8YYTj=ykjs %f:'NȻ"iHK$W0溚?;֬troj',%͔ݻYG^Sc2%rz6ĝuǘ/7kD܋honn*]mHh1; ?bHrTdQXadfF}dQj/q rpLEVi72Z0J_ҐuT8AԒ~z*zC6Y=rb4l!.n_rRzeZ:n*[.~ XMB^"-,}y$L;7{k1%$6H__all?v1rCSPom$&@MrZ/JܷR5Q`|!^3h1VII+}p7㓒(/,r'q%4n@S_4 endstream endobj 2988 0 obj << /Length1 1144 /Length2 10998 /Length3 0 /Length 11761 /Filter /FlateDecode >> stream xuwSxe]mlٱm۶۬b'UlbbWm[Ow?ϺXsbu(HDMn ,̼Ek{SwW5yU;aGAnf/!4qvt7që[L\f^fn^?kf:]}@7Jdg 4W:]y*1G'okK+7 ?8@gst+ )O*[H[.͉ct`t1)T\/Wf&n4Ӕ7` k[2wwbpvvʈ?ܿ1Kt̬Jd 6q0urtXع-^p&@;%`nm0Z+X{Y=ZPsG;+LZtDEH2pX98"**Xߊ}XL{]\@aiSI I9ϋ5W gIw;G?ng_&vˁ 7;k3KU hlffcp0*;ZX8XS6uq?RJ89[;X__˟}Asoa@ hhjT'ɰ?6Nk֯c[Ϟϝ-Qea5" K^nqf4xٞT?ѫЌE9J5\svOXu wGQ2Ml#@$'# Lqg. vR"p/38zFmCKm=N/u-;ZZĄct>gj.cxwmN8&{88Q3+og)l2FIN!>! ;ѯ# 9Z>4AZUp Q>ȏ5!AO Hl6@Z:EaAB5 B ɋl*yC+=܉;dq]TEo'=^`ioFMdlalliHQkk8f oN; =P] Fڅqr:z `U"+̟F`$bz{P0GSH[Ct9߫G%Пꜘ+ թ7l 3[V9^Q%OV)O 9eF3bR>cD}R 2ٜ.K<~]A,jQ u${4tU z$]}lq"tBweZе'˨Ԁok6p Gw=ߎzs{Xoj㯥;II TC.'~P93WukQ)sP5Ь,%>{~TS/8kʵBZ"o/g6Z ͻD3x;ur0|-aMh^m\-sش$3ߟq¦%1Sg~o2Jh麊U' ^rH$i^ 'l2 >>] g!!{SC!?y:{wg(ϽSIy?˓SAzE7K=-ߋwBd9륂IF*DmzG23{%ZEa'5u,w|[i.cZ YX"o&&b*Щld`bA^%/RO-f\Rg,5?B}De=Ad e|:W^Qbă:#(_"xadC֭mYpI1df$gFÉzTwƛ7SqSU ]=(o]q<'~Z{_< BeDo>m- ao$[snjA\ ]SITYpNOF=";p|k i7?yXC^U\bVG,@8̖wjq/%vÒxMwN{tVӃ V eݩUV7ɐaVFb02.v׆fz^?vXY^Խ5y20t9&G ;P.S9Es=#pHqm2_T_\T2pբ^7_e;LNUdi:Ya:˘?Iy{Yu6G[51wEH;(S"-E(9^RiMR`yp KqT-I.UG7J.oXVs+21&bNޜdKIc1e|C}7XVW.B 6AastuR܄ qݢzP^$va:t[7Mm5K&!y9 荀;F7g(AGtnbtg:Lx 96}]%gABWs7qb#i[`{4د),&!s\OxOXHI]SgApo7)ļPe8T^5+ϴQHޙkYev,Dٯۤ'//0 ~tfjSgo"ݬӑzI wn[pƷh`ds-sEq}Y{gj7~2Ȉ`y  U 4DDףq=ň}\՗Ι_pCSoyo֩oȽ)mwtZ3f%ghu* h6 l_#I?? كϩ F%"ġ_bb%w]qs$EBM}հ)L*A@\ƫ ;PhZ"HF{ZAυCŦ0!†8_bcpřX?^XOv̛X)"&TQ&D[!ŗpd@OkԚ)"Pe7!Q`@M:& G);W 획^8QNiO|q0vӲ*գD}tmTwYi˱h={sP 0ousi"{[P$ߛ ~s?Dn L*W9gt<]Pkᚯf-U$EG,.mU# qo~EJK0Nce?}2E1Uc妷_]8pjֿrb{cwscrT-TBdž=|vtrl?~/J$Z#lýיb&%-[5*_v)7+ޡp3PbiA { ,۩;c EX Lh{JjzJ<Ggyg,DBmm ==ls>6BHP8 7148)#e|juyFGgcߏ=g_(2AhX-1pTlOb끱s_5`oRw ?M'6DM&wg41S3 Ƽ+c2!X4|r1se){8]=\xs:l -tVJ岚s*­d},}m9I^)+,N-4𩘓!so FzF 3^;--U욽@ \%uh>4^𦨺7d<5G׽<)Ѹ滑q?vsih@n"87 Hf-xnwzA5Luh6USvtɘ1*I;F.C:vQ U ^<96jQ_Zx?O8aiRJtsyOs)?Yb DC-lw S}$4uAYN.9^?4 ձPXV;M\b'n+lfC6Ǿ rX4eǀt]]m,iJH&2jT4]&ɚ%knP 靕߹%'t3unSW[2]ݵ(pSHX;E2Xʓ|C5(6 ?AGЋ%5#B Q?p.VcpmC*04ު!8ÙrBp^[Wï1Kc/n;I"Z.}Ȏ&{P+&QE!@b=i%'x74-js׹9n)NOX=ΎD-+APe3M;@{|ۅhF6ίH߂jA[0zc㌟1@U@NGXOHNͲ>+8Ϲ6/' WYTWd^|ɹ_jkBa̬Gf2;9)n0׋-FATE$ܹ'b^!k#Vǧ,n$Kz\,V|2pUS{i8|Uq{Wȑ>| ox PoOHL|Ph!w7l_L۔r|"Z ;N+C (իݏ .UM@atYi 5|L`*ˡAuP5xSkpOwA.֒%J3%H[fͩM}=`C_%8Ωv8)T8+*լ;ݳɼj`Vw~k,UHD.$nPJִi39'7E~#u_ Z;>_&x?#jтi> X4huV9rbG~pj>7{RnoV hIm@$dBa=3Ճ֛ʓՒgIHc2"o )u-#pEt +0{ ^PLj<пhA:lqtFY(ϢxOZ"Zm&i3p# )?sr㠂} GϧdǡdTy6 L,XUn{ Oaej@ -Wq?+2n3nA xkjgPotM*p@FL~K{u?NQR3e s_7x{TUbnUE%#UJbw% iJx[O aG_ h7FUh x%$όL7L|+b{tQhO/Cʵ@B416卆1},]s 38j+MtAy0}Y(6*T`<0rX)k~YX|wsJiY!fI^zo]¢@w4UNǧkɌ-NA4?A%-U?ƻ- bm)7.XܖVV "~eK~h?<$qƹs Uҋ()oJ64`;.zÓ76'aȧeז`1(T(Y0mP)#{w,W{q[gQKk zNOIyl֌3F)=< bealXrv[w H}~ɳ:8X7 S\"){Q v'lnR\Ntf5ӑ֋DƢI2E%kz!Sxf m2@JQ#|]4V.!؉Вk \*bvVaLqn `/R߂ݪZFj5߁BYk?!ܾ zU~+8oؾ! )ӻLa-ꌥ:CUcX(ϡ_HAt|Y#њΘފэ(61E~Q3BٮDn^\Ӑ}N 1$tC9In6Үٻ\Hí=KR b܄:B/bH.ӻ w],"Fb@0P1flg 3W^{:SأCFC.p$3_=4\Z-aKFKi}!٢JQVo(ƩeV&܅[|tMsJ(m_ۓtE /"|3fqA[]-Z\\HXkCvvN~qx%І'x:2a"RmJTt9impmKo!| _-h'h4"ͳ[umƦu\MeWC6JH&.#cM nJpTkʚُdy<{=4t~_}=zfp#9]3GS]`3JӂlX^VU@4?:mQP˯>&hYP*dNC}rY4[z(*5m x_}C;_^}J RZ.u}R ~+Ӵež4?7s]Aj˪h܆ rh6>CzQNM{²`2Q7q"]n7÷K10cU*V֗i\ o*eFx_ib~\߻Ts>=DT~htec~aȨ'%?@Z-s׺N uPrx6rl>.cL`@'p.ٙ&QpXUF߼~Q! [IZ^]$K^d*|}H0.B :/g가\!hN U^O"NtSa/bw`/"֦1З2L&#dg|̶w O+IDʤbRRg&Q_[ u}\8gt~Z+,[5xA#"Z$)SZaRtfvPTkӡ28&5!#rL &Kib{fՀQL0hM"%2&yԱIA{W%MЮ@8bop#εN7xop>K/w ѧ ~dOU-+WI05.dbkdi-d K)uۅ yk񡖭Pu zpmKcls "%뗻h叕a+ "ɝe:m_aN3ϘSW=}D^i;VWq8I$GL0r_Klb,BF3ɹF dױ⨭) !%sCk >:Z-lU8~WeQ/A}(@q&9hʣ]SG:[poxwhZsB\`E벙d\??jrؚWV-ZT3BwLFmΪMZz(c6wh~ ٬.X/aG7͞w-6$CiAjb-~+NYޜj#8mnJdyPw3] (H5'#ݵzJI+W ̌Y߀I3rxF^$Ŵ(֜1h}_9RISnj*j.bv~7Su[>+w~WI8Ѐus J|E]+rw3X3*˯J߸P8L5Rk{ŤP,e/q(aoju*R.(C-l"ÝQ5YAwF OI9{JZ[D3fP-A(f+PӍ=t3shj&W5L~ϋ u"CPIkl!XN*q2[688`kU76Ƴ4\YGNe”u~/yNV_vaw1\dm,B"{ _($Q&֢ 1e@Z֒B_C=~]a5o.$3Ȗql6 ِ_gN5-|t# E-k-Iq\"vk"gnr 6#筳d.6FcJu =&”=6?^'ztqJfp6dֲz˂}qOj>&`Q78|bHY]knZ_@B&nq/VHeƅ>}cup$"L=Jm;zQOmDn<ƆABCWM_'P+@ÁI"dߝXFљ;e6 :%Txn*Z4# [oQ}Ë cLe-/!a~ÃTҾposxdv:LWX1c{!Ɍ6祚+8iZ@&6DUah0XfO ;l mOa"օNZ0>FHU2ZQQD=v YfR* c~n߻n;d~x/ E)(lz `t,Ӓ~@;oCQJ E7jsRBtz\+@͛V8G%uRXk,3?=9/KHbrFk4y fG6Ct\Pii>?<WK.py\W+k ?eOg ml7WiIforsjА#2b8$/t> `[d;@Ê'cτ}͈phȊ k;?$KNw&-3 :hqrhn~N6=zǃ:u# 'uT4y|w{fclѫb 7/evtHiuW4#Q%=Qn/ֽǡh~z1]۱R&e GиNy jH_V~_jeaD'2P)~=#Ԉ! Zl>2gʍ ϒ럿ՈL> stream xmteX]I-ww;];8!$݂C=GwLߙQUk^6{U &1 3ؕ 7ss0+2\Mo)"&&o34u}Ѵv(:Ylo{V:8TAU+~$`W 7GG;BltXUϙ^ +kW6 @6@;?o[aji*erm#? ) cvd]Yފ[H8Ioy m`,A`?۳psd܀rrxƬ.VvV>V^ 4f##Ol4s,o ;>!,@3ە ZuV2uuyYYY|]oseS{ EEYAQ^[X&6^;/'O>.j WU;ˁ-|67tvyS%O;+[0\oZy[QH7ݟ3y[.E۽=?f2LAv^pK] le0\A@ U_* [.? p s[0MR@$;XV 71:[6wsv~ӟ7%D h`.jS~_'F?ǭuFƉgW߶7-WRuZFJ 20e|wDHB#Sp,#<_?&:SX) ;(d CIJd9SDŽB2fPP.ʮ6e*_kc.MwL} }դLgSz BI#ve*\*xͫD^AiZp0;1 T6~ (sǕmljgJ%(3@70g0:&9X0zb;&-R*([8,k;%{ )!1VƵB>DMn3c!z43it]* 1lH=7J ?i.|as` E:^5~d.W|jR"3VGQ^hƬ ?RIڨH`xlơuqYT9}Z)Mr&y]n@mRthFJf{dSl/Ʊ|4X+2leH6&sxd5P*Il[ݹ-[zT5:z6)dnȷ^QZ} , qY_c\_|Զ,@J!$% [\ Zr)S"tH`?(U\å4lGb`+˥1-p旸h%r* 萁@Cz ;K^ \mB:!!ʻZ0U9h}mwzȥ v;^m{ww. 2}mYK_|)0)o.US`HlFO{G~|q'ܕ.Ы4,>iH:WO'1 d&W kEǥP*H=>')͈@~9&, iO墆1RuhVqKv|gB.0׹a ,>R`YG֔\A˾a,:H9lx59E>.|Y NbyƬUja>mwilHA&c㙓Š1p?jf``5Ars-21HR}&׍~NdndWUB& Cw'Ȏ+cA-MeRp}mr9.G*m&)w NQ)&Fs(ac(-yb;]vUGkj9dG%b4IC>TQ,Nkl`tw+4햼uڲS_.b,IIWR(_L2u x! lr|#dH!߼OeΕo| =ŕn$ckYB&!Wt: '#^5iKl)]]O F)3 طqn0S+GqtҤzt)NXQpcRDP "BpH)JH -K[dp]:mm3ZYx03,2[G+M0qxb R*qNMjaR|i(Уwt)7 3{uh a|YL9O#-vv;XgJ-r/ژ۩ b}ƃ$)x6 $Y*zNӉ3qf 3#uA]mW/RRk6Ͼ'–l3qNGJ$M(g0Xl611wjt$DK<V-^Cr?w'PXdW_j? ڵJd ~خm[:&2ҦH71-BT~ĐBFtǼkY\SD.: DQiXw^"gA,~J5wo;}>mܴ :0?tz.lrVepEP,34@xVCqd6VF-\I2}¸T3[?5W-lHsASfiiVEh v7R5kDs˩:#3x,g%Y\<u*8[X8+1hHPeҬ&(82.rQc&M GtXb\v˖(p/Ą;&?y~rˑh=:Lifhy ՟~'=pDCV#nP\VL^V|[$Gsm̂UE C ໤_# <7y")V˗[5m dHbLi_?Bmz6t­0G`}E}:aϪFKnɸ}YW-Yxsiv:F)C3Ä*dYsɽ|  W= UFQ#ٻeɇ={ b3.Hs|+뙧]*"sةM'tSS(зuk'.(m`#>Mz}+sqZK%Yֲ h/a籴]<[Pkx??+](3Sma bJbaNn'|7Ze{nZ6C<10ѹ۸dV#-6yrp~$ph|%fs#Mj[k(ZrXF@Ti:,>l""]jb(})#-p|TLHRuU5Gdbͪ< 1\qXP8}P % 򮡀E=c^ww.UJ<8$]UsTǶM%0ճBJ(8];0qȧU' +"z(كx0yǟUV[Ow6#p9@Sz -kokizJOYk5ϟx<F´rWozצO"jR_#UwžUd_F~0c8aP}V6쭚ݽCb.τJ[;7Cb.}Yu_m U>I1@, ŕO^涆E:6֯NAP -Y-ӛQ&Ѣ橉([v4H dY73UڣGq/>fH >$h&n]\8 M=mOaoKrQa R'"X`~4wZ3_$-~Ǭn;*j/O*5hG%FQ%^"5ՇU y!C]{;!~njpخ3$jfnM㢾cR#&"TKiMI΁B9?> ;mOZzw\;XĨUn,v06kdcu=UlEn!.ѷ\e&|-& e7NnJ"]T$:¯V,>KRžb 4*>Ko[t{puK2 qWWR{iGk 2YWbJ0iٌ5}p< p4Oby 26S8 z O.«ՎJbWx'憭NdvQGDnM ]iB*f n,+z;ƛm1s,3&dw^)~E,YĘs+;mOf[b/"mhG)Zyp^+y+v崑cމnQL¡`~ri!>#M9-Dx3k+ 5GDž)g)d}L(BS?(~~<(bU 򉜉p>PS^}($6yʆE<# 9Ho{W2k[ SQZ}ʲALh-L1%F@F;sZw%ŕvxhq$}6f~ݞ4GP.П^I<+ ]^wmkE Վ  6dT%&;x˵nGwj*T60[vD8q-2|Pϐ= i.! s~.&"H-Vܷ9nZp?Fl`&;NgeeF:O Aj7FNZ[1|yL#3}jsSN 7JÐf::_\r@mqǑ`&)l8C,~w$Xɟ>l!~>|q[O=~jmk GeN,V|//weG=*^If9Ѩd6nU4>hqPr>h5ekQjxgiP5C9LM E~j`O ე[,D-.Q$SUCBql_l^ oSğYK%=i`dAlh4ETW7;xd9gIeP CjF%H<6͹:lǃ +ypGUYEsKѧck; 7D+M@+&FxThv8%&gPd/Jod,l|\Đ[ 'k~}³27DA6u5'M2TMn}C;u[Fxir.73.蘾xD$33MFz] 3'Yߣ(Zp8wܾ(leΙ"}%(< QE#8aPwL-Vin2G-~Ʉ_@TÍ7`9KVC.9+ |M VwfD{u]iaaNN g+Ŝiz PR?dի<}JLS質CN)/  'AFioxk;iýB;#7&Fy&VMUrEEZ= 1¾텑L) QNS?ӑjWqXu6bp(Fd#A7bKYN̚{${ |=Jrps΅Xki4"Y&,*!=!]>UePE#v 2qTBpp=슮{=,&KR|VL߈a*fO:hȩNz;[P HefaGѨ0(1g5$bJrʇZmy%`&" fi|A 8 N!SڀlcΑ$jn.cZä[Q\׸cA$Z\aũtl{zTɮ1dk0óaVA+xP"Z3%R`XI0tPpQJC-,Baňpvl0 `/\A!: rk`qwRxi.m~I)>}DmվDֽٌdjyhDx iSt|Pfl)Xfisf> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 2993 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 2994 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS'K}v}tƾ`R\ws*pWl:*;m_Ű=EB.=]6E%‡hWvE;^N ƣՊU ٟweӟQ?OIz^UU|ڕߵ6ZrbˢXEIS:.trA&TH>4"PX H BM@5*08WfH AX v.2I## .zӘˈ0Qa8tcpN0A2 @݆s>^l>^wo_j4Rrtsľ x[%QLuQ.ݢT ܂PKߗp#}߂pMAM37CB2>*R{@8񩎤3 }c$f O#z  ) spW)9N{=g-_Z ~YK/t:/~e}Y%៍-t:UEk nmGkp\x{)ނ endstream endobj 2995 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 2996 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw7{>oaI> ѲH8U/RǾ0ñ_x0ӅxBiE.͏S=/b_ixމbc4fi|8EXD_R4.GRQhV̪xvqڎXJfUıkM;rͭSlҏ֋jU,N2@ ",   T[<5 1"àcvG@mg K | +T|5flxZ1YP^ꠦdb}[ה_Q>kUbw88]k|'%Ǿjց{ g䈏rsqk:n87xIue.Aft0!?4ɳ4mFtӔ^z1?z .~lP}L endstream endobj 2997 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vz|N8}No)e0&h?q:P_ X}ac1+a  jҢ~]ߏ{_r)4i_px`!dZ>i]<U_cr%ͪcךv[\٤ժX*be-@E-X@-꩖xkM PY@ ,#bEA 5rEqIb>,彐A$ G#e"&c D`%rE*s(Ǩ5ثCI*=ǔ^pk+ ܛbVLbX+@8:13Jp3<|6 ^ΜANVjRy9cpסAM}Ė)|֪,+pp70h8J+NK}Eլk)up >o U^g{_e{]*?`CBhgiیtV;۳ѝ)(ZK7bA;E^]|sQ endstream endobj 2998 0 obj << /Length 699 /Filter /FlateDecode >> stream xmTn0CƆ@LE"h.R$Λ1iZ)Ayo7?^$ŝPIs77EW]=?:Wz==硫nMi%oR1I+ִ)Q;{W` 4vo)ZZq/7}P^kMݧ`tTshz+&TuSՑ @tvM{BM_ht>X]0}j74훺"t{wJ˥݁ѬSC]wS!ڝ}}悅K(e۞0&xYF\20/0b# !ڇ\)&q)% 1ϹN"ۂ%481`rH%Dd#C k Ю%"l %RQ F'b=:SuX$Q:\CAfpGR~m%^!N%$h&՚R #ƿp'XϾ>AI }3Nh25gNE'bkkؿs %|V !3?fc91ӊ9|u 6ZcWCab d1׮eF-9Ag깐3Z=I= 6-7p?)pegT> stream xmTn0CƆ@LE"j.RC~8M])A̼7W?^$ɍi$냫N]}~;ީǡMi %oTsVi/)QÄ~S 8ƦkZn;@L=훶E UTGgu P}i]X;k C톦}UYoO} A`TS7~wpjmS!詺ڍrî}uBZ2pm;KPaffIq XMJ0LfhrdĥP_E OB%? 2;::k+ q*qx%1D뜝5!֌jD01;zi+&f.pdk_ ΜN0VG9m9t~h18kg?l(9L&XN e1FA͸ؕ``{B?Y̵kyKgЙz.~`R˸?Bsܦs's.: ]|-i5w= Rt endstream endobj 3000 0 obj << /Length 700 /Filter /FlateDecode >> stream xmTn0+Jb'$8B 8l[jWHL$Q;o.Z ̼7/o~:W{xPCWQb6;J^ǩv'-[~Gݾߣ#i6ڿRV_n84]֚̽e[sYͮi P[ L:?=v8|`4nh7u{QE sU5Y7{C]_?{B^QSu; 3jV՞d;&xD\20-0b# !ڇ\)&q)% 1ON"ۂ%480`rH%Dd#C K .%"l %RQ NLHI($ux-LJ@J!^H :ggM597F7FN|[{}&Ff*pdk_ΜN0VG9ʱwDK4X=CaCɁg2)4X(rb0/s4lƵ.b]ʌ[r> stream xmTn0CƆ@LE"jD;oi@yoW?ףnji(郫N{]}=ܩǡUj %Tsi/)QC;H#9Q·=Et2Zkmw{H?cOgAAm(0Wۯ]fjDnPi_ES߿9HP:Uvԍcw*=UWCܰi_\0zfe9\[gb)ι )^fb, L ؤ dB@!i @F\ ` H Sn4ȶ` $(N' 2R0zd9#Cb*K(@,0[Bzr aà>;Sn:,Rx( =.k2X ĩsvքZ3Ca~ata'ɧg4D 7Sᄋ&X3Bp]t(:ʹV7;'Zbg%ΠJ&OsRfdޒ t n|0SessOpnB|W\q9WVo|FCӇ}P ߴUvDz(t~ endstream endobj 3002 0 obj << /Length 700 /Filter /FlateDecode >> stream xmTn0CƆ@LE"jD;oƤjgy_xN{qV'wC&]\]]u>t\qxں7ŦmN7isƬ'k~G]?ߓ` 4;RV_n86]{̭֚u[sfߴ L:?v>4|`0nhWu}QE KU=5Yw߇l?N6jwwv Z/բ,ko{&PaffIq XMJ0LfhrdĥP> stream xmTn@Cx ^"#&W R ە7iSFyo.{a;M[ݱ;w}puUtjWowa読;|SltCɛz;nʽ4%<i$>57JN.n86]{̭֚u[ҏӫ(hߴ5g( L:?yv>ixgm7~д/"$(,v{F~{Tk#zv~Wa׾`R-r睉y?&xYF\20/0b# !ڇ\)&q)% 1ϹN"ۂ%481`rH%Dd#C k Ю%"l %RQ F'b=:S:,Rx( y]eѱԁ_[WS3+!Z af> stream x[nG}Wc 7Xk[V,W䁒cIq{/ 9 ,{zzzNUWU82(SJe+U\%TT Q+k UD傧TQk] j$%Q m$*aB+$18j  3jF@UBcyD4'ʘHӨJ MYMf*m F ٺXJImxZsM9SYpr`AlI cZBxՠ챗ɢ 2th!0s{Pݿ_4}5أY=0տg*2'(c"!.@(xL2`=10&gm(*(YJˁ4; @j/H?PZ|_${Aہ{fp V<Q,v&]Ī@KXb`΃ 8V@( w0_)&Sߍ 9Av 9n.ou]_p 9@J}WjdB" s!/PF {MA`h{="2䰕tDQOP&FgӓU㊽.H |phU#yZ,_7Qb; tf:%rcM%6<^h2͉ȍdP^K,9ݢR%w'yu)#T&\,b$HHX #ذ* 7t>'E)OB>mk(x2* r1(R&E2(]eC5ᮔQsLZ/U ; Xt.(o"i*;J:=%Mh!2ȡ` K`2%h?ddWOsbJbiKz!7S)2O /"+ =MɌ&@YNi*h8R/Z6 Ӛ s,Q*eِ8zڔ(}F*n6%Ԧi6+!d4 hwhifS^`"n{1i6I1$"IExI]pU,,lV||Xb duCltұo=>χϟ?/óyS=%{?\kOɂ6{ztvi4Ol\ G5pco(gt;E=cz>G%W/L{WGo`[.NܑX^lk8M8N?m[0wo޿n.߲Fa~drry^<}kRѻma;4+ |氿pqΎ36]ٚz!?|OQmh #ES@F{2~s|W|1x*īQd^W[)bWSpq2 }e_l61k۷&x<63+Y- 44a@CIC*ϡ-i D(ݢ 0)\<qpx1:t2t牿בP|\"$Ŷ(+(yx\95C$qߗǥ-'.lyˣ'zz8lӕ IWЊ7TE-*9~i5w }Sp(c{Y‹-"7 ٥ӀSl8!DlZHI4H#w-^<}uc!n3OCg`ivs)-њ[0k舧?NNP$}XC' M]cw\,mRn8,"t2oIFl!8QpdShޢEͻd1͘ RAc]di7mTk°ZSn)w=$Q˵p%,̓~Dx;!ms5~XBy˱qZsdAh6_Wݞ Û|~:NnVxZ;XgɉuiDK`I)K%Dtwgi `'Γj$mœٝ}Kn%I4q'{յ7O[HR6dTJeQA%n9r=$.UWb,pVh'ix9@nZK4Y5ZFet@|8h%!uҲRhuUjӒŗT591^M/T|ZR-uzrLVjE[&-ej^W]E. {ًha/+E/^؋@ {žb[؋. {އ -y|}δja;h^ZMm][߇E{饥ZD-Ջkb_\bLVn޵w]دBnWw endstream endobj 3009 0 obj << /Type /ObjStm /N 100 /First 884 /Length 1849 /Filter /FlateDecode >> stream x}Y $GW,Δ"`|2,>xvodC:TM+CRTS]kVnn[.¿&w4ahvA7e&ijǫJ֕#&-'՜TEe޷(;HhʲXS Jcp#Fi n YpIJMJIʫXQ[3/(+?/, nFzg=<);)9_%M31 Լ l /F!ykҢaZ3cؠV66>bE_`MLA( olCAA 0489DĨ`ω lqefwyǿRaBRz;I#k\=S1Ey6|9^ nWc *qP8;$ic0RJ^ "9^T: úke8c٥}eB62\`QFa 1[}-*,l5߿tn?^r\/]:~{Aw|1+,n+X-vc+?*',V `c=%=ܫ0uɽ:qƽ.WǽFܫq/?OGl-3ge?oVϿ]SqyO5gw̒$&IhJXGsOrf.{$Jw6k8C`2)|V#a*~a.$*%K W7KV԰ܷ'Wm}Êo}qEl7cNlWqQwv9ʧ)K5*,g՘iMj.⫁w75gӓLDcWL"N TL :udXNinۺd[: Z5uɽ:5^{Yr/{^>pc[&?W7]COIɐk(Q"ekς/f>li6}R_Lɦ;C4c.1pKΰ7K+)5"̼1"7&FsD& kLv gЈ fИ => ?̹Qd_b)"m8&G~~sG5fl|:];3&\a]֘zrs5̭1[X[Xr[޹5"5tɽskDn skȒ{ֈ֐%λy7̻!?NKĶ26*_\<Ϗk,Zrv}}x|]ckڢ4.O?_ G ե{7rDa ?_\UNX{mUVK{5,]b=5fܷ%MV}3ےo͸KEW~8]#]&ǚb߅-C)qƈb̗zlxW|Syba~Nh`@@ K:uɠeDA$(cF ƯzIKCgS2%A4Nr(b}1u⟵Ž`? }9u^ٟ hyu:sO6}R[bTXW2&c()ŌY&cgW]dŷ1=%0ub-{Kȕ\Y&W/Ǐw73ԉ?~Gv-f2s{~!9_ٺYG5s}O_"3n{>G̸. endstream endobj 3010 0 obj << /Type /ObjStm /N 100 /First 912 /Length 4803 /Filter /FlateDecode >> stream xڵ[M$qϯ F0H@l0` '‚hd~duu&3܃ad|ƋȬ%/7s#ooo$zBnDFo0~lc{c>7qx? `[pg-YwLY!ZNcnو p8` LDᓿ >M |ŧpS *gaAaiuH&E~|BDzGtZC"1fҙKC:8B&7fd dyWFX;99 m! NmNe6 .d}@?YS Ar#&oh#p3o?/?$߷w[dѫ,W,9%a%"Mq/7̫,KYrxÞ/{>ž7%nw{`Gػ {w=-ػ#݆=]bO {ڰKi {{]#톽.v^bov\bofХ,e7! <|!kP^6&/e"r,s%+_e)Yt$K6Yt)k76{,>z"{ݰKa7 /~Eސo˟nvcopo3- & 9rP6/O/#e^̕,^?7_Z Ga- L磤 mw[mػ_N69O<%FL{io]<#_i%tB`Å(D*ED: aͅ(=}m6Kۣ7 j6 {@}هf #(6^n.^Y7b 8/zD FzyEQY J_Ԕ)Wuׇqj]O o<1ȚF߰*fn @1 }F|œGĹ&Ct_O5}~+hnݭB+n"c%SIǾ?my~C^G+|_)L?m_n]uixлζǟ0*S0{~վT>ac矿~Dm@%r5ǡ:1v;3߹NB栥 FB4,HG̉?Uso]4KsnLlL JjҜ(=G!lk%S h[|gvj-d#^FgeO G)%I=0i6y꥓Y+]#$C R }:}+~fȒUBuV0i헁@{sR N*'I*S!y֟M6&l#3;/E;q!didƭ$W4Ʊ8S$Tj0P-)Q%3T'6Q9Ĺ,ܐ,~l9W4WjqO|w"9ptu 9U%.9Ti#Z˸gpv61Q X+i0ޝͭT4*kʦVuցlޓ̥&9kl>{Zxi=I1B )yE5|w$al7TZ"Q>Etxfn5s77HXc1߳H$n6~hCwNnTj(A (™A90cI$՜"Id3B^H{ȍ\bPC{AZ(f,aF|5GtǃƬhuIp-? s?iSpWM!cҹ{tNBEIpEEL6:W ^z&v!&Y MH^E"GZʖ@lVJI*Tń^_[+Dy9W4%fhh,YJ<:0yU΁Тw0 R |h|On鮡SYLFlg9UF"t%ggAE-(>*)btoN*PErA͊8Wԑx ͳ0?G㊟R}ţO`”hc2W (َ#^*I0vC%n !S3SIAl B 2J nGNlƕE oDz_0 iTD%F¡I(tY#q|N(&2rX(cH89C:D6fͤCsٺYUUz0kԇVX2r`~3zd՛wcʀ :{V>{T\7\4%#OcLLGkh>e@eNY"0y?P40c7jPr> k kaCLBތ/GD3>H2mLh6 HLnp{ҋLM%pVzD]F]1ND36MMRrlj5 U@5oc!:JGӧln %axXgd'Ra:OByl]nvlESc')]n -R{e8'_[')] 4h> vYH^,N xCcDjwuKT\nHE*HYя/н y>3n|dSd^jJKˮ8t|{GǑMʿ/ٱݘŽq:pbߝ1lei.bW232UItQAJ\h7> ?$ꝟaߌƎ]cXEMl#3qK-S\},F' !Ǹbkk,e,18-+b+n50 zW?>]r?"=j,T N>E:&(La|{XnƇ澨d}@I}m`*,)`p9k} ѥcjT-Ɔypwl*LMBoF)<ƀӶ9ߓf ҫӛQu*|1kf3*VAsrΘq8Kݞt-Ќi-qGڼ}@utzc@1iW˱)C6ijJFLa q"cZoj5q4"ՍI^l]@7t"|19wqi*6'=|1u&E[ĔaM\ kPL>14JXk8~<ǷCBWU= avZDf:8V1cATiMdҬ,kK.j1=gGm{]/suݟR-%:pXH3Ҵ}pʼn33 &*h6VypكKڨ2 /zk;ˉLxQa sԖSxi9{p Nvq<[*/cckN)w 7PN!L?n endstream endobj 3046 0 obj << /Type /ObjStm /N 100 /First 1068 /Length 7532 /Filter /FlateDecode >> stream xڵ]K$qƀW$ "] m>|fza@_D5{3+gd2IFF0d>xF~-ZllLIZ9bi=uYZ1HqZA NLyZYGI8!D'aZƃFdB#H[!Y 6RHB̈!$@x.pE(Ndc.ԑʄ:K*t}1RwQ8ԇ,+vhy J5bs;zHzAt{LJQmLDL}Xyi (m7 +n5x^8 4}cs4%VJjKvzJU-<\r0<ǍbL+>!:ۂg KʃH&Ljx,r1 #6(54 R ԞkK>iYȝ/4fns/ rBj؋/bnZ,tVtr3&%dfൡL8sXf ,MTmVtW_.+ dFv-f׏>e+ӐOg߉ԯ2a-=tcpg껍ȝoΌ;)|%zI&h*SO ど1Q؍F}\*!{,B[N4br$zk* jd15MaԕɸwڂF]ZRs쪾i†j&t{ w7;S_E IٌL9:'[uL 6 B8]!]ʬuZ{eDt(D{TEaj mh%i2Ng껉ȝa)!<$g$T]!d:MкJQG"j@fIY-N(S3NC\goJӑyѢ|+pZ r {!:F24ث;US(HBEÜ").23)Rs7nc&rg'*dbܜGFҝKm0pn* ;yl JKݫo<2@>yS_;%y5"IL%a-ƀLU/mlTG-b( !+:[`0d͢@E)NH[m4wۘܙѭdVEi8ֺhEzw钁T@ŊYhs%v &:f1 -,~ӏjVR&f]@PN3h!Q\hocҢ(#ͣF,G'*Yw7;Q珿|jKMᯟhg~m>"܀D=-}(ǫ39aWƆhw`D6Wg82Eq!cc˭QafƁh,Պt!(Nq<X(u=n@DkTlkUkbD>DB7,j[-QVϬ>N\gqRx]i:*`B`-ә;l^U`r8#an-"_S9]ٽT 'զ,lrJqoDDRҀϣ=~?}~]՗^I¢mݒĕqj!]C,崝4_zYHIM{1,-{-WZ'_/eN:'.8ciY [~# v_|mv!'_(@phWIKѵp:{5u֕uw#ӈ8U<::k'tK'mJ|߳߸Ʌfv4P;fJ^9I H1~^ ?FCRQ$0 ޸A m{!{tyxz!AaGKﲁO(O(ţHe rnvuWWS_cTlter/:G&LQXu(%F& SLn=WVٰg˨aWJ`P"FN: YYF2r_Fc%m]N{P|~5ԂǟوC8hf_ boA44wFk(Ra]:jWǰ+gHdֶ*M}) s>CR=Tey䚤Gu1KVH|&(X#.F]0S>ǟ {F/.:a:iG[;9Ow> |ʷ8-ܹV#N_srk 3?_X5T.4͌dflHDf`UWIV3g%!0g6Օ[Q w"7\4Aq1 [=ltә'ǥ.{v60zlQ#>澕2E?Qsv ?Lȩb@*k-k%l3ZgFEr掕 CoԷu<׻1&01T9bKٷ/ 9֜Q+r*ONc81+d18#5=H7WA N*6O8KfSh]v̿ Y{&/y02T8w "}hmrHԇy8nB%#}ȣ5d\RR)ÛyV`oO^">t+yڛxX)33ȶQɁ|+[`%Cqqbkpn[#F U.ӹS[̦v,.ŌܖP+zVOFJ[98#jjdV*@᛫t1Kx|I |5nƊyҭ2܊Cc.*%oOHw:j >TI[#7LR7TD֮WjBprH `$9P1;/w13(7J F#_Lk&a/UyL[8|=>:FJu=$"=!pFG۬ewjK67ڰehaY9j@rz}PM!f: X|=\hwTlw9Ts _BFOwI4GkQ#gligH1'4I"6r5KN:fZر=_3m0Y a}f(RtT&CCA:&&(Vs(2\KeLPEqmSUfdzA4ƥ`]@4$9F aP"VFqm_xLﵸu){H.p^!>u>_ezrK}="]zr/U!z)kzL()T:? {U0's@bǏaǏaݜ^qxM+2,pjP\d^<[Ao+rvd \/]hEVi:a|xOAa48` HztẋPJNb 1!;Z N'*dž@ '۪t -z};ܹ|7lO1g [n&wel+dh%ƻ׸J=aFd(8|h%a +k9Z>@ יq1ϥ8\G&?#o,]XwGK܄$NIR ERo?IRo!AqS> #) bZ*XFw\7b s]`V AQH(D,/'{wG+BUm:@X dXEܝ<'y{9š[X,a |NO q?T>'ftooOp𤲣4=1rץ|6'eiI=#s\p3RִּJ?8e[a#xho^rr1qº4:tÉ~FnðDaPz>}XI;7PgG_}f_?t chՠ+~˧GP_~~oO~~CAEM (X^351 3qJOvc 6QrƵQ͑)s$fipM~EWJ\n\O:K ?o'YˈGGԛM>&v_Db a4ksaFgvI NZp?-eݸ({%<-i OK*̈x?mm 3Li0P~ P~i/F^ж`xVpwl_q/Lxi`(8/xiyIskx`[PXPXjpo%gJK°$ K°7DxIqq!׏[gqAi)<-梚pipi)?-RɭE9/./Rk^e:䗘yO2dxwy2wB}XZhȠ!FXWZ{ k+5+5>-VA.+Z7O_=5j,O^->PZg2++ɲnҜ_< e{\?OIr]+Yq}x;JؕYZ(|Ǯ|Ǯ|R'J)*/tV*dW*dס_ʚ1L&J#? endstream endobj 3148 0 obj << /Producer (pdfTeX-1.40.25) /Author()/Title(\376\377\000Q\000A\000T\000z\000i\000p)/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240202094050-05'00') /ModDate (D:20240202094050-05'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) kpathsea version 6.3.5) >> endobj 3147 0 obj << /Type /ObjStm /N 1 /First 7 /Length 139 /Filter /FlateDecode >> stream x3641S0ಱ,HUwN,IOHLO-V0600W0P/-̃Y@sA|CS7?%U?8,蓘SlcW[md'Evv`]Ц<<ssc@a֕/ endstream endobj 3149 0 obj << /Type /XRef /Index [0 3150] /Size 3150 /W [1 3 1] /Root 3146 0 R /Info 3148 0 R /ID [<49391678931F7DADED841C377A7EC2E0> <49391678931F7DADED841C377A7EC2E0>] /Length 7402 /Filter /FlateDecode >> stream x%i#vqg}}LϾӳ KYDn(Y ]@L#EXEso]yV_VגZmXM5\&wU8r|r `!),;,wIȽ(\ 5aE6orJX%Tp5[.wNɭ;+r7Fr`ܤ)*Upl18!;r ^rG`i#pPa!8,w^.8GũM{#_xZ.>F Yr{1>%( Tn0)=@..?pYnBn0tUn\ ]\h]xnʅ1;pWn\Hv,|Ʌ܏u'T\XLݒ[/|/ʅ^+r넯\UX-}^{{ B.>m[% M"wLnp4kd 0&{.Lhwș];_](YΜErQP + qHt\\Ba!}Q.N&`|샸xkFkƅT), vM=]}0-C9]}Vr]dS펬<z!ww1,=fJw1 Ͳ~9Eu]3{Pn'=,Ad;#Ahw1,uMI92NhwO]㿮=+gfMy9ew&{!wUd^#]{YN}!4ٻW˙3]{]ܴdޔ{,guMm9ldޕ۬5ٻtdN?5ϻr<9P'x*@O˅_J]a 9,vc`- >mK ?m) r l S\xpd[ɾ'kkr |^\p̗k].r䦄H%bX"(\ n5a\p% 5rasµN. rV8 g`\plSgO V/r'`\L` w>'wLLap5rGd;,<&P06هQ< C -w CP}Sr6.?`LB;C&4ه>Xf o>|$~ L;`Ʌddd,|#,xȅ܏\]n < *`Z. zsx!P.l^2NEwrAF>:P~T. EL&|BB8rghoX_DTr v-GK`\L%P.[,.$^$'k82 V$ӯUr1 W:rIX/l\(^.>Őlr>gkm]n4ċ[1;`"[87.rLJ`Ӵ> A9i}r> QerผoKpRn;)8-43pViZo^ /@CΧK"\z)r>XZ/W u9_M[pS73--wDܕ Dx˝{,|#a`ZCa\/^|exqEqڪ r)ጁ}V/ =BP0 ᒰHcS~mO%7e=5Z~EOMS/橥wrX+a5$ 6f[a'lN%5oۖn7 v `?p8 8IO)8 g,pp.\+pu7܆;p}x`GR۱51< 9 ^x =| >C M|PĪ |PA|PA|PA|PA|PP3[9< }f3Cg>3Ofߕ}9> ~H:ka)_&ƀiߙԞ|,g>#H}IjOwqpZbG8|>_O>_W}U|g>KYR}T,g>KYR}T,g>KYR}T,[(Q$P1y0BEP}'18g>UV,%ZXI [-4xthG<3Ų[|OI6IIk/i(9MirN3c&G_bGŊnR9)MRk(N`ěKaUR^/rIߦhOj̀5-6 q\I^CB(s(MUIf4͗VΘ6q N3 Fy)8V*:<4Lh<@Oj|~lԚT6wCe3 QrM懤o/ųJnSmFSc/x& VJX:ƹRG)b¶9^ ,ߦ[mO&ӨM6M6?'ɲ_̊Ў3wmcޟ$~'6A196INO$}qOOOѦe8ms}͵Jm o%ɩ8mţM6i64jG[qxYm"DA&I~oI4FuD3" Ѿ$qhK9c8g 猾Z33}fU?/!03Fw;ctg ٝ$v \0W= 03o3?}0RďIpFü'fFhhFC7\ q䐕s2IToH!=EJ!03Fwh8IqiC M!0fQ!07FhDc4`z +c؇ы9 軐b* ͊NPKrW9F`Eb쇆xhxQqhaa { 1$~'w0r܋NC z ` Xk`=lͰ*x6KzSU8[Cv^Cpq8'3pb9<\\K [܄[p@4AC4^BѤpI\xֳ;|I<A b_C4BC4>B>C4$YK@רgG<0=3I}񟍗kc"zK`),% V&}zzz  v>cYY GsCsFsZLs+Ash.:5=h=IS>{l; '8lj=Nqb{'8lj=Nqb{'8lj=Nqb{,ջ >pXO{=M8oc{8a=qXz8a=qXz#-l^^csc hl*4/Kc0Tm"7Šk^e-: rw$+;ҍ]@0%,k!`0Mǀ'@ۮq 4g@q4@;q4Sָnkָk[ָi }PALCi<'4<^kxoAjo|3ԫF԰ tbC:$됬C:$됬-guLNI։rHd XB *tСB *tСB'[OTh9sg'ى2wv̝h%sg'҉/~K'J8t32ߡ~wߡ~wߡ~wߡ~wH֡`PR8s!,<މ[qbIi4smR"gpX~.}+1+F+++V+79mcW4b~1?EcsE~9~91sqg5VsL=sL=sL=sL=sL=sL=#SOkЄ:4MCЄ:4MCЄ:4MCЄ:4MCЄZ7X k`-IX`#lͰ6;`'ݰBWI ד_Z80p 8 4phESpU ad?^- w.܃#x O)C M,2X c2X c2X c2X c2X c2gQ?~F3gaX c2"gDΈ9#rFc@UpΥ1'Os  w% |F3g>#|F3g>#|F3g3g>#|F3g>#|FK- _$|I%K—/ _$|I%K—/ _$|I%K—/ _R O'_xCx% ,P@% ,P@% ,P@% ,P@% ,P*IR)٢~I%K/_R~I%K/_R~I%K/_R~I%K/_R~I%Kr/7'b8dJ(Yd.~N6V&T;-4uAj3h FoWNy@ endstream endobj startxref 343983 %%EOF QATzip-1.2.1/include/000077500000000000000000000000001465165016500143175ustar00rootroot00000000000000QATzip-1.2.1/include/qatzip.h000077500000000000000000002712541465165016500160160ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /** ***************************************************************************** * @file qatzip.h * * @defgroup qatZip Data Compression API * * @description * These functions specify the API for data compression operations. * * @remarks * * *****************************************************************************/ #ifndef _QATZIP_H #define _QATZIP_H #ifdef __cplusplus extern"C" { #endif #include #include /** ***************************************************************************** * @ingroup qatZip * QATzip Major Version Number * @description * The QATzip API major version number. This number will be incremented * when significant changes to the API have occurred. * The combination of the major and minor number definitions represent * the complete version number for this interface. * *****************************************************************************/ #define QATZIP_API_VERSION_NUM_MAJOR (2) /** ***************************************************************************** * @ingroup qatZip * QATzip Minor Version Number * @description * The QATzip API minor version number. This number will be incremented * when minor changes to the API have occurred. The combination of the major * and minor number definitions represent the complete version number for * this interface. *****************************************************************************/ #define QATZIP_API_VERSION_NUM_MINOR (3) /* Define a macro as an integer to test */ #define QATZIP_API_VERSION (QATZIP_API_VERSION_NUM_MAJOR * 10000 + \ QATZIP_API_VERSION_NUM_MINOR * 100) /** * These macros define how the project will be built * QATZIP_LINK_DLL must be defined if linking the DLL * QATZIP_BUILD_DLL must be defined when building a DLL * No definition required if building the project as static library */ #if defined QATZIP_LINK_DLL #define QATZIP_API __declspec(dllimport) #elif defined QATZIP_BUILD_DLL #define QATZIP_API __declspec(dllexport) #else #define QATZIP_API #endif /** ***************************************************************************** * * This API provides access to underlying compression functions in QAT * hardware. The API supports an implementation that provides compression * service in software if all of the required resources are not available * to execute the compression service in hardware. * * The API supports threaded applications. * Applications can create threads and each of these threads can invoke the * API defined herein. * * For simplicity, initializations and setup function calls are not * required to obtain compression services. If the initialization and setup * functions are not called before compression or decompression requests, then * they will be called with default arguments from within the compression or * decompression functions. This results in several legal calling scenarios, * described below. * * Scenario 1 - All functions explicitly invoked by caller, with all arguments provided. * * qzInit(&sess, sw_backup); * qzSetupSession(&sess, ¶ms); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * qzDecompress(&sess, src, &src_len, dest, &dest_len); * qzTeardownSession(&sess); * qzClose(&sess); * * * Scenario 2 - Initialization function called, setup function not invoked by caller. * This scenario can be used to specify the sw_backup argument to * qzInit. * * qzInit(&sess, sw_backup); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * calls qzSetupSession(sess, NULL); * qzTeardownSession(&sess); * qzClose(&sess); * * * Scenario 3 - Calling application simply invokes the actual qzCompress functions. * * qzCompress(&sess, src, &src_len, dest, &dest_len, 0); * calls qzInit(sess, 1); * calls qzSetupSession(sess, NULL); * qzCompress(&sess, src, &src_len, dest, &dest_len, 1); * * Notes: Invoking qzSetupSession with NULL for params sets up a session with * default session attributed, detailed in the function description below. * * If an application terminates without invoking tear down and close * functions, process termination will invoke memory and hardware instance * cleanup. * * If a thread terminates without invoking tear down and close functions, * memory and hardware are not cleaned up until the application exits. * * Additions for QAT 2.0 and beyond platforms though Extending * QzSessionParamsGen3_T, QzDataFormatGen3_T and Using qzSetupSessionGen3 * to setup session. * 1. Addition of LZ4 and LZ4s * 2. Addition of post processing functions for out of LZ4s * 3. Compression level up to 12 for LZ4 and LZ4s * 4. Support for gzip header with additional compression algorithms * *****************************************************************************/ /** ***************************************************************************** * @ingroup qatZip * Supported Huffman Headers * * @description * This enumerated list identifies the Huffman header types * supported by QATzip. * *****************************************************************************/ typedef enum QzHuffmanHdr_E { QZ_DYNAMIC_HDR = 0, /**< Full Dynamic Huffman Trees */ QZ_STATIC_HDR /**< Static Huffman Trees */ } QzHuffmanHdr_T; /** ***************************************************************************** * @ingroup qatZip * Supported memory types * * @description * This enumerated list identifies memory types supported * by QATzip. * *****************************************************************************/ typedef enum PinMem_E { COMMON_MEM = 0, /**< Allocate non-contiguous memory */ PINNED_MEM /**< Allocate contiguous memory */ } PinMem_T; /** ***************************************************************************** * @ingroup qatZip * Compress or decompress setting * * @description * This enumerated list identifies the session directions * supported by QATzip. A session can be compress, decompress * or both. * *****************************************************************************/ typedef enum QzDirection_E { QZ_DIR_COMPRESS = 0, /**< Session will be used for compression */ QZ_DIR_DECOMPRESS, /**< Session will be used for decompression */ QZ_DIR_BOTH /**< Session will be used for both compression and decompression */ } QzDirection_T; /** ***************************************************************************** * @ingroup qatZip * Streaming API input and output format * * @description * This enumerated list identifies the data format supported by * QATzip streaming API. A format can be raw deflate data block, deflate * block wrapped by GZip header and footer, or deflate data block wrapped * by GZip extension header and footer. * *****************************************************************************/ typedef enum QzDataFormat_E { QZ_DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ QZ_DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ QZ_DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ QZ_DEFLATE_RAW, /**< Data is in raw deflate format */ QZ_FMT_NUM } QzDataFormat_T; /** ***************************************************************************** * @ingroup qatZip * Supported polling mode * * @description * Specifies whether the instance must be busy polling, * or be periodical polling. * *****************************************************************************/ typedef enum QzPollingMode_E { QZ_PERIODICAL_POLLING = 0, /**< No busy polling */ QZ_BUSY_POLLING, /**< busy polling */ } QzPollingMode_T; /** ***************************************************************************** * @ingroup qatZip * Supported checksum type * * @description * This enumerated list identifies the checksum type for input/output * data. The format can be CRC32, Adler or none. * *****************************************************************************/ typedef enum QzCrcType_E { QZ_CRC32 = 0, /**< CRC32 checksum */ QZ_ADLER, /**< Adler checksum */ NONE /**< No checksum */ } QzCrcType_T; /** ***************************************************************************** * @ingroup qatZip * Software Component type * * @description * This enumerated list specifies the type of software that is being * described. * *****************************************************************************/ typedef enum QzSoftwareComponentType_E { QZ_COMPONENT_FIRMWARE = 0, QZ_COMPONENT_KERNEL_DRIVER, QZ_COMPONENT_USER_DRIVER, QZ_COMPONENT_QATZIP_API, QZ_COMPONENT_SOFTWARE_PROVIDER } QzSoftwareComponentType_T; /** ***************************************************************************** * @ingroup qatZip * QATzip Session Status definitions and function return codes * * @description * This list identifies valid values for session status and function * return codes. * *****************************************************************************/ #define QZ_OK (0) /**< Success */ #define QZ_DUPLICATE (1) /**< Can not process function again. No failure */ #define QZ_FORCE_SW (2) /**< Using SW: Switch to software because of previous block */ #define QZ_PARAMS (-1) /**< Invalid parameter in function call */ #define QZ_FAIL (-2) /**< Unspecified error */ #define QZ_BUF_ERROR (-3) /**< Insufficient buffer error */ #define QZ_DATA_ERROR (-4) /**< Input data was corrupted */ #define QZ_TIMEOUT (-5) /**< Operation timed out */ #define QZ_INTEG (-100) /**< Integrity checked failed */ #define QZ_NO_HW (11) /**< Using SW: No QAT HW detected */ #define QZ_NO_MDRV (12) /**< Using SW: No memory driver detected */ #define QZ_NO_INST_ATTACH (13) /**< Using SW: Could not attach to an instance */ #define QZ_LOW_MEM (14) /**< Using SW: Not enough pinned memory */ #define QZ_LOW_DEST_MEM (15) /**< Using SW: Not enough pinned memory for dest buffer */ #define QZ_UNSUPPORTED_FMT (16) /**< Using SW: QAT device does not support data format */ #define QZ_NONE (100) /**< Device uninitialized */ #define QZ_NOSW_NO_HW (-101) /**< Not using SW: No QAT HW detected */ #define QZ_NOSW_NO_MDRV (-102) /**< Not using SW: No memory driver detected */ #define QZ_NOSW_NO_INST_ATTACH (-103) /**< Not using SW: Could not attach to instance */ #define QZ_NOSW_LOW_MEM (-104) /**< Not using SW: not enough pinned memory */ #define QZ_NO_SW_AVAIL (-105) /**sw_backup that is set to 1. * * Before this function is called, the hardware must have been * successfully started via qzInit. * * If *sess includes an existing hardware or software session, then * QZ_DUPLICATE will be returned without modifying the existing session. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] params Parameters for session * * * @retval QZ_OK Function executed successfully. A hardware * or software based compression session has been * created * @retval QZ_DUPLICATE *sess includes an existing hardware or * software session * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @retval QZ_NOSW_NO_HW No hardware and no sw session being * established * @retval QZ_NOSW_NO_MDRV No memory driver. No software session * established * @retval QZ_NOSW_NO_INST_ATTACH No instance available * No software session established * @retval QZ_NO_LOW_MEM Not enough pinned memory available * No software session established * @retval QZ_UNSUPPORTED_FMT No support for requested algorithm; * using software * @retval QZ_NOSW_UNSUPPORTED_FMT No support for requested algorithm; * No software session established * @retval QZ_NO_SW_AVAIL No software is available. This may returned * when sw_backup is set to 1 but the session * does not support software backup or software * backup is unavailable to the application. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetupSession(QzSession_T *sess, QzSessionParams_T *params); QATZIP_API int qzSetupSessionDeflate(QzSession_T *sess, QzSessionParamsDeflate_T *params); QATZIP_API int qzSetupSessionLZ4(QzSession_T *sess, QzSessionParamsLZ4_T *params); QATZIP_API int qzSetupSessionLZ4S(QzSession_T *sess, QzSessionParamsLZ4S_T *params); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has * been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * * The resulting compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * This function will place completed compression blocks in the output * buffer. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in,out] src_len Length of source buffer. Modified to number * of bytes consumed * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] ext_rc qzCompressExt only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last); QATZIP_API int qzCompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer and return the CRC checksum * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * The resulting compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * This function will place completed compression blocks in the output * buffer and put CRC32 or CRC64 checksum for compressed input data in * the user provided buffer *crc. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in,out] src_len Length of source buffer. Modified to number * of bytes consumed * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] crc Pointer to CRC32 or CRC64 checksum buffer * @param[in,out] ext_rc qzCompressCrcExt or qzCompressCrc64Ext only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc); QATZIP_API int qzCompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc, uint64_t *ext_rc); QATZIP_API int qzCompressCrc64(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *crc); QATZIP_API int qzCompressCrc64Ext(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *crc, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Compress a buffer and write metadata for each compressed block into * the opaque metadata structure. * * @description * This function will compress a buffer if either a hardware based * session or a software based session is available. If no session has * been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and * qzSetupSession. * * This function will place completed compression blocks in the output * buffer. * * The caller must check the updated src_len. This value will be the * number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter dest_len will be set to the number of bytes produced in * the destination buffer. This value may be zero if no data was produced * which may occur if the consumed data is retained internally. A * possible reason for this may be small amounts of data in the src * buffer. * * The metadata for each compressed block will be written into the opaque * metadata structure specified as function param metadata. * * comp_thrshold specifies compression threshold of a block. * If compressed size of the block is > comp_thrshold, the * compression function shall copy the uncompressed data to the output * buffer and set the size of the block in the metadata to the size of the * uncompressed block. If the compressed size of the block is <= * comp_thrshold, the compressed data will be copied to the output buffer * and the compressed size will be set in the metadata. * * hw_buff_sz_override specifies the data size to be used for the each * compression operation. It overrides the hw_buff_sz parameter specified * at session creation. If 0 is provided for this parameter, then the * hw_buff_sz specified at session creation will be used. Memory for the * opaque metadata structure should be allocated based on the hw_buff_sz * or the hw_buff_sz_override that is used for the compression operation. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and * session data) * @param[in] src Point to source buffer. * @param[in,out] src_len Length of source buffer. Modified to * number of bytes consumed. * @param[in] dest Point to destination buffer. * @param[in,out] dest_len Length of destination buffer. Modified * to length of compressed data when * function returns. * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * @param[in,out] ext_rc If not NULL, ext_rc point to a location * where extended return codes may be * returned. See extended return code * section for details. if NULL, no * extended information will be provided. * @param[in,out] metadata Pointer to opaque metadata. * @param[in] hw_buff_sz_override Data size to be used for compression. * @param[in] comp_thrshold Compressed block threshold. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess or metadata is NULL or Member of * params is invalid, hw_buff_sz_override * is invalid data size. * @retval QZ_METADATA_OVERFLOW Unable to populate metadata due to * insufficient memory allocated. * @retval QZ_NOT_SUPPORTED Compression with metadata is not * supported with given algorithm * or format. * @retval QZ_NOSW_NO_HW Function did not find an installed * kernel driver or software provider. * @retval QZ_NOSW_NO_INST_ATTACH No instance available. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressWithMetadataExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc, QzMetadataBlob_T *metadata, uint32_t hw_buff_sz_override, uint32_t comp_thrshold); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * The input compressed block of data will be composed of one or more * gzip blocks, as per RFC 1952. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] ext_rc qzDecompressExt only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len); QATZIP_API int qzDecompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer and return the CRC checksum * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. If no session has been * established - as indicated by the contents of *sess - then this function * will attempt to set up a session using qzInit and qzSetupSession. * * This function will place completed decompression chunks in the output * buffer and put the CRC32 or CRC64 checksum for compressed input data in * the user provided buffer *crc. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] crc Pointer to CRC32 or CRC64 checksum buffer * @param[in,out] ext_rc qzDecompressCrcExt or qzDecompressCrc64Ext only. * If not NULL, ext_rc point to a location where * extended return codes may be returned. See * extended return code section for details. * if NULL, no extended information will be * provided. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc); QATZIP_API int qzDecompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned long *crc, uint64_t *ext_rc); QATZIP_API int qzDecompressCrc64(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *crc); QATZIP_API int qzDecompressCrc64Ext(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *crc, uint64_t *ext_rc); /** ***************************************************************************** * @ingroup qatZip * Decompress a buffer with metadata. * * @description * This function will decompress a buffer if either a hardware based * session or a software based session is available. * If no session has been established - as indicated by the content * of *sess - then this function will attempt to set up a session using * qzInit and qzSetupSession. * * The metadata function parameter specifies metadata of compressed file * which can be used for regular or parallel decompression. * * hw_buff_sz_override specifies the data size to be used for the each * decompression operation. It overrides the hw_buff_sz parameter specified * at session creation. If 0 is provided for this parameter, then the * hw_buff_sz specified at session creation will be used. Memory for the * opaque metadata structure should be allocated based on the hw_buff_sz * or the hw_buff_sz_override that is used for the compression operation. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] src Point to source buffer * @param[in] src_len Length of source buffer. Modified to * length of processed compressed data * when function returns * @param[in] dest Point to destination buffer * @param[in,out] dest_len Length of destination buffer. Modified * to length of decompressed data when * function returns * @param[in,out] ext_rc If not NULL, ext_rc points to a location * where extended return codes may be * returned. See extended return code * section for details. * if NULL, no extended information will be * provided. * @param[in] metadata Pointer to opaque metadata. * @param[in] hw_buff_sz_override Expected size of decompressed block. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS *sess or metadata is NULL or Member of * params is invalid, hw_buff_sz_override * is invalid data size. * @retval QZ_METADATA_OVERFLOW Unable to populate metadata due to * insufficient memory allocated. * @retval QZ_NOT_SUPPORTED Decompression with metadata is not * supported with given algorithm * or format. * @retval QZ_NOSW_NO_HW Function did not find an installed * kernel driver or software provider. * @retval QZ_NOSW_NO_INST_ATTACH No instance available. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressWithMetadataExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc, QzMetadataBlob_T *metadata, uint32_t hw_buff_sz_override); /** ***************************************************************************** * @ingroup qatZip * Uninitialize a QATzip session * * @description * This function disconnects a session from a hardware instance and * deallocates buffers. If no session has been initialized, then no * action will take place. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzTeardownSession(QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Terminates a QATzip session * * @description * This function closes the connection with QAT. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzClose(QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Get current QAT status * * @description * This function retrieves the status of QAT in the platform. * The status structure will be filled in as follows: * qat_hw_count Number of discovered QAT devices on PCU bus * qat_service_init 1 if qzInit has been successfully run, 0 otherwise * qat_mem_drvr 1 if the QAT memory driver is installed, 0 otherwise * qat_instance_attach 1 if session has attached to a hardware instance, * 0 otherwise * memory_alloced Amount of memory, in kilobytes, from kernel or huge * pages allocated by this process/thread. * using_huge_pages 1 if memory is being allocated from huge pages, 0 if * memory is being allocated from standard kernel memory * hw_session_status Hw session status: one of: * QZ_OK * QZ_FAIL * QZ_NO_HW * QZ_NO_MDRV * QZ_NO_INST_ATTACH * QZ_LOW_MEM * QZ_NOSW_NO_HW * QZ_NOSW_NO_MDRV * QZ_NOSW_NO_INST_ATTACH * QZ_NOSW_LOW_MEM * QZ_NO_SW_AVAIL * * Applications should verify the elements of the status structure are * correct for the required operations. It should be noted that some * information will be available only after qzInit has been called, either * implicitly or explicitly. The qat_service_init element of the status * structure will indicate if initialization has taken place. * * The hw_session_status will depend on the availability of hardware based * compression and software based compression. The following table indicates * what hw_session_status based on the availability of compression engines * and the sw_backup flag. * * | HW | SW Engine | sw_backup | hw_session_stat | * | avail | avail | setting | | * |-------|-----------|-----------|-------------------| * | N | N | 0 | QZ_NOSW_NO_HW | * | N | N | 1 | QZ_NOSW_NO_HW | * | N | Y | 0 | QZ_FAIL | * | N | Y | 1 | QZ_NO_HW (1) | * | Y | N | 0 | QZ_OK | * | Y | N | 1 | QZ_NO_SW_AVAIL (2)| * | Y | Y | 0 | QZ_OK | * | Y | Y | 1 | QZ_OK | * * Note 1: * If an application indicates software backup is required by setting * sw_backup=1, and a software engine is available and if no hardware based * compression engine is available then the hw_session_status will be set * to QZ_NO_HW. All compression and decompression will use the software * engine. * Note 2: * If an application indicates software backup is required by setting * sw_backup=1, and if no software based compression engine is available * then the hw_session_status will be set to QZ_NO_SW_AVAIL. In this * case, QAT based compression may be used however no software backup * will available. * If the application relies on software backup being avialable, then * this return code can be treated as an error. * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in] status Pointer to QATzip status structure * @retval QZ_OK Function executed successfully. The hardware based * compression session has been created * @retval QZ_PARAMS *status is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetStatus(QzSession_T *sess, QzStatus_T *status); /** ***************************************************************************** * @ingroup qatZip * Get the maximum compressed output length * * @description * Get the maximum compressed output length. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * src_sz Input data length in bytes * sess Session handle * (pointer to opaque instance and session data) * * @retval dest_sz Max compressed data output length in bytes. * When src_sz is equal to 0, the return value is QZ_COMPRESSED_SZ_OF_EMPTY_FILE(34). * When integer overflow happens, the return value is 0 * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ #define QZ_SKID_PAD_SZ 48 #define QZ_COMPRESSED_SZ_OF_EMPTY_FILE 34 QATZIP_API unsigned int qzMaxCompressedLength(unsigned int src_sz, QzSession_T *sess); /** ***************************************************************************** * @ingroup qatZip * Set default QzSessionParams_T value * * @description * Set default QzSessionParams_T value. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * defaults The pointer to value to be set as default * * @retval QZ_OK Success on setting default value * @retval QZ_PARAM Fail to set default value * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetDefaults(QzSessionParams_T *defaults); QATZIP_API int qzSetDefaultsDeflate(QzSessionParamsDeflate_T *defaults); QATZIP_API int qzSetDefaultsLZ4(QzSessionParamsLZ4_T *defaults); QATZIP_API int qzSetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults); /** ***************************************************************************** * @ingroup qatZip * Get default QzSessionParams_T value * * @description * Get default QzSessionParams_T value. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] defaults The pointer to default value * * @retval QZ_OK Success on getting default value * @retval QZ_PARAM Fail to get default value * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetDefaults(QzSessionParams_T *defaults); QATZIP_API int qzGetDefaultsDeflate(QzSessionParamsDeflate_T *defaults); QATZIP_API int qzGetDefaultsLZ4(QzSessionParamsLZ4_T *defaults); QATZIP_API int qzGetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults); /** ***************************************************************************** * @ingroup qatZip * Allocate different types of memory * * @description * Allocate different types of memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sz Memory size to be allocated * @param[in] numa NUMA node from which to allocate memory * @param[in] force_pinned PINNED_MEM allocate contiguous memory * COMMON_MEM allocate non-contiguous memory * * @retval NULL Fail to allocate memory * @retval address The address of allocated memory * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API void *qzMalloc(size_t sz, int numa, int force_pinned); /** ***************************************************************************** * @ingroup qatZip * Allocate memory for metadata. * * @description * Allocate memory for metadata. The function takes the size of entire * input buffer and the data size at which individual block will be * compressed. These parameters will be used to calculate and allocate * required memory for metadata. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in, out] metadata Pointer to opaque metadata. * @param[in] data_size Size of uncompressed buffer. * @param[in] hw_buff_sz Data size at which individual block * will be compressed. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *metadata is NULL, or data_size is 0, * or data_size is greater than 1GB, or * incorrect hw_buff_sz. * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzAllocateMetadata(QzMetadataBlob_T *metadata, size_t data_size, uint32_t hw_buff_sz); /** ***************************************************************************** * @ingroup qatZip * Free allocated memory * * @description * Free allocated memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] m Memory address to be freed * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API void qzFree(void *m); /** ***************************************************************************** * @ingroup qatZip * Free memory allocated for metadata. * * @description * Free memory allocated for metadata. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] metadata Pointer to opaque metadata. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS metadata is NULL. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzFreeMetadata(QzMetadataBlob_T metadata); /** ***************************************************************************** * @ingroup qatZip * Check whether the address is available * * @description * Check whether the address is available. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] * a Address to be checked * * @retval 1 The address is available * @retval 0 The address is not available * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMemFindAddr(unsigned char *a); /** ***************************************************************************** * @ingroup qatZip * QATzip Stream data storage * * @description * This structure contains metadata needed for stream operation. * *****************************************************************************/ typedef struct QzStream_S { unsigned int in_sz; /**< Set by application, reset by QATzip to indicate consumed data */ unsigned int out_sz; /**< Set by application, reset by QATzip to indicate processed data */ unsigned char *in ; /**< Input data pointer set by application */ unsigned char *out ; /**< Output data pointer set by application */ unsigned int pending_in; /**< Unprocessed bytes held in QATzip */ unsigned int pending_out; /**< Processed bytes held in QATzip */ QzCrcType_T crc_type; /**< Checksum type in Adler, CRC32 or none */ unsigned int crc_32; /**< Checksum value */ unsigned long long reserved; /**< Reserved for future use */ void *opaque; /**< Internal storage managed by QATzip */ } QzStream_T; /** ***************************************************************************** * @ingroup qatZip * Compress data in stream and return checksum * * @description * This function will compress data in stream buffer if either a hardware * based session or a software based session is available. If no session * has been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * The function will start to compress the data when receiving sufficient * number of bytes - as defined by hw_buff_sz in QzSessionParams_T - or * reaching the end of input data - as indicated by last parameter. * * The resulting compressed block of data will be composed of one or more * gzip blocks, per RFC 1952, or deflate blocks, per RFC 1951. * * This function will place completed compression blocks in the *out * of QzStream_T structure and put checksum for compressed input data * in crc32 of QzStream_T structure. * * The caller must check the updated in_sz of QzStream_T. This value will * be the number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter out_sz in QzStream_T will be set to the number of bytes * produced in the destination buffer. This value may be zero if no data * was produced which may occur if the consumed data is retained internally. * A possible reason for this may be small amounts of data in the src * buffer. * * The caller must check the updated pending_in of QzStream_T. This value * will be the number of unprocessed bytes held in QATzip. The calling API * may have to feed more input data or indicate reaching the end of input * and call again. * * The caller must check the updated pending_out of QzStream_T. This value * will be the number of processed bytes held in QATzip. The calling API * may have to process the destination buffer and call again. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in,out] strm Stream handle * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * (always set to 1 in the Microsoft(R) * Windows(TM) QATzip implementation) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzCompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last); /** ***************************************************************************** * @ingroup qatZip * Decompress data in stream and return checksum * * @description * This function will decompress data in stream buffer if either a hardware * based session or a software based session is available. If no session * has been established - as indicated by the contents of *sess - then this * function will attempt to set up a session using qzInit and qzSetupSession. * The function will start to decompress the data when receiving sufficient * number of bytes - as defined by hw_buff_sz in QzSessionParams_T - or * reaching the end of input data - as indicated by last parameter. * * The input compressed block of data will be composed of one or more * gzip blocks, per RFC 1952, or deflate blocks, per RFC 1951. * * This function will place completed decompression blocks in the *out * of QzStream_T structure and put checksum for decompressed data in * crc32 of QzStream_T structure. * * The caller must check the updated in_sz of QzStream_T. This value will * be the number of consumed bytes on exit. The calling API may have to * process the destination buffer and call again. * * The parameter out_sz in QzStream_T will be set to the number of bytes * produced in the destination buffer. This value may be zero if no data * was produced which may occur if the consumed data is retained internally. * A possible reason for this may be small amounts of data in the src * buffer. * * The caller must check the updated pending_in of QzStream_T. This value * will be the number of unprocessed bytes held in QATzip. The calling API * may have to feed more input data or indicate reaching the end of input * and call again. * * The caller must check the updated pending_out of QzStream_T. This value * will be the number of processed bytes held in QATzip. The calling API * may have to process the destination buffer and call again. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[in,out] strm Stream handle * @param[in] last 1 for 'No more data to be compressed' * 0 for 'More data to be compressed' * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * @retval QZ_NEED_MORE *last is set but end of block is absent * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzDecompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last); /** ***************************************************************************** * @ingroup qatZip * Terminates a QATzip stream * * @description * This function disconnects stream handle from session handle then reset * stream flag and release stream memory. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_PARAMS *sess is NULL or member of params is invalid * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzEndStream(QzSession_T *sess, QzStream_T *strm); /** ***************************************************************************** * @ingroup qatZip * Requests the release versions of the QATZip Library sub components. * * @description * Populate an array of pre-allocated QzSoftwareVersionInfo_T structs * with the names and versions of QATzip sub components. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in, out] api_info pointer to a QzSoftwareVersionInfo_T * structure to populate. * @param[in, out] num_elem pointer to an unsigned int expressing * how many elements are in the array * provided in api_info * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_NO_SW_AVAIL Function did not find a software provider for * fallback * @retval QZ_NO_HW Function did not find an installed kernel driver * @retval QZ_NOSW_NO_HW Functions did not find an installed kernel driver or software provider * @retval QZ_PARAMS *api_info or num_elem is NULL or not large * enough to store all QzSoftwareVersionInfo_T * structures * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSoftwareComponentVersionList(QzSoftwareVersionInfo_T *api_info, unsigned int *num_elem); /** ***************************************************************************** * @ingroup qatZip * Requests the number of Software components used by the QATZip library * * @description * This function populates num_elem variable with the number of * software components available to the library. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in, out] num_elem pointer to an unsigned int to populate * how many software componets are associated * with QATZip * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Function did not succeed * @retval QZ_NO_SW_AVAIL Function did not find a software provider for * fallback * @retval QZ_NO_HW Function did not find an installed kernel driver * @retval QZ_NOSW_NO_HW Functions did not find an installed kernel driver or software provider * @retval QZ_PARAMS *num_elem is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSoftwareComponentCount(unsigned int *num_elem); /** ***************************************************************************** * @ingroup qatZip * Requests the CRC64 configuration of the provided session * * @description * This function populates crc64_config with the CRC64 configuration * details of sess. This function has a dependency on invoking a setup * session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[out] crc64_config Configuration for CRC 64 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc64_config is NULL * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzGetSessionCrc64Config(QzSession_T *sess, QzCrc64Config_T *crc64_config); /** ***************************************************************************** * @ingroup qatZip * Sets the CRC64 configuration of the provided session with a * user defined set of parameters. * * @description * This function populates the CRC64 configuration details of sess * using the paramaters provided in crc64_config. This function has a * dependency on invoking a setup session function first. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * Yes * @threadSafe * Yes * * @param[in] sess Session handle * (pointer to opaque instance and session data) * @param[out] crc64_config Configuration for CRC 64 generation. * * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Session was not setup * @retval QZ_PARAMS *sess or *crc64_config is NULL or contains * invalid paramters. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzSetSessionCrc64Config(QzSession_T *sess, QzCrc64Config_T *crc64_config); /** ***************************************************************************** * @ingroup qatZip * Read metadata parameters. * * @description * This function reads metadata information for the block specified by the * function param block_num. * * block_offset returns offset value in bytes from the previous compressed * block of the compressed data. * * block_size returns the block size in bytes of the compressed block. * Some blocks may be uncompressed if size > threshold as specified during * compression and the size returned will reflect the same. * * block_flags returns the value 1 if the data is compressed and 0 if the * data is not compressed. * * block_hash returns the xxHash value of the plain text of the hw_buff_sz * payload sent for compression operation. * * If NULL is specified for any of the metadata parameters (block_offset, * block_size, block_flags, block_hash) reading the parameter value * will be ignored. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number of which metadata * information should be read. * @param[in] metadata Pointer to opaque metadata. * @param[in, out] block_offset Pointer to the block offset value. * @param[in, out] block_size Pointer to the block size value. * @param[in, out] block_flags Pointer to the block flags value. * @param[in, out] block_hash Pointer to the block xxHash value. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockRead(uint32_t block_num, QzMetadataBlob_T metadata, uint32_t *block_offset, uint32_t *block_size, uint32_t *block_flags, uint32_t *block_hash); /** ***************************************************************************** * @ingroup qatZip * Write metadata parameters. * * @description * This function writes metadata information for the block specified by the * function param block_num. * * block_offset writes offset value in bytes from the previous compressed * block of the compressed data. * * block_size writes the block size in bytes of the compressed block. * * block_flags causes the metadata to indicate the data is compressed if * passed a value of 1 and indicates uncompressed if value * passed is zero (0). * * block_hash writes the xxHash value of the plain text of the hw_buff_sz * payload sent for compression operation. * * If NULL is specified for any of the metadata parameters (block_offset, * block_size, block_flags, block_hash) writing the parameter value * into metadata will be ignored. * * @context * This function shall not be called in an interrupt context. * @assumptions * None * @sideEffects * None * @blocking * Yes * @reentrant * No * @threadSafe * Yes * * @param[in] block_num Block number into which metadata information * should be written. * @param[in, out] metadata Pointer to opaque metadata. * @param[in] block_offset Pointer to the block offset value. * @param[in] block_size Pointer to the block size value. * @param[in] block_flags Pointer to the block flags value. * @param[in] block_hash Pointer to the block xxHash value. * * @retval QZ_OK Function executed successfully. * @retval QZ_FAIL Function did not succeed. * @retval QZ_PARAMS Metadata is NULL. * @retval QZ_OUT_OF_RANGE block_num specified is out of range. * * @pre * None * @post * None * @note * Only a synchronous version of this function is provided. * * @see * None * *****************************************************************************/ QATZIP_API int qzMetadataBlockWrite(uint32_t block_num, QzMetadataBlob_T metadata, uint32_t *block_offset, uint32_t *block_size, uint32_t *block_flags, uint32_t *block_hash); #ifdef __cplusplus } #endif #endif QATzip-1.2.1/include/qz_utils.h000066400000000000000000000102161465165016500163420ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /** ***************************************************************************** * @file qz_utils.h * * @defgroup qatzip debug API * * @description * These functions specify the API for debug operations. * * @remarks * * *****************************************************************************/ #ifndef _QZ_UTILS_H_ #define _QZ_UTILS_H_ #include #include #include #include typedef enum SERV_E { COMPRESSION = 0, DECOMPRESSION } Serv_T; typedef enum ENGINE_E { HW = 0, SW } Engine_T; typedef struct ThreadList_S { unsigned int thread_id; unsigned int comp_hw_count; unsigned int comp_sw_count; unsigned int decomp_hw_count; unsigned int decomp_sw_count; struct ThreadList_S *next; } ThreadList_T; typedef struct QatThread_S { ThreadList_T *comp_th_list; unsigned int num_comp_th; pthread_mutex_t comp_lock; ThreadList_T *decomp_th_list; unsigned int num_decomp_th; pthread_mutex_t decomp_lock; } QatThread_T; extern void initDebugLock(void); extern void dumpThreadInfo(void); extern void insertThread(unsigned int th_id, Serv_T serv_type, Engine_T engine_type); #ifdef QATZIP_DEBUG static inline void QZ_DEBUG(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stdout, format, args); va_end(args); } #else #define QZ_DEBUG(...) #endif #ifdef ENABLE_TESTLOG #define QZ_TESTLOG(debuglevel, Readable, tag, ...) { \ FILE *fd = debuglevel > 1 ? stdout : stderr; \ fprintf(fd, "Tag: %s; ", tag); \ if (Readable) { \ fprintf(fd, "Time: %s %s; Location: %s->%s->%d; ", \ __DATE__, __TIME__, __FILE__, __func__, __LINE__); \ } else { \ struct timespec ts = { 0 }; \ clock_gettime(CLOCK_MONOTONIC_RAW, &ts); \ fprintf(fd, "Time: %ld.%06lds; ", ts.tv_sec, ts.tv_nsec / 1000); \ } \ fprintf(fd, "%s", "Info: "); \ fprintf(fd, __VA_ARGS__); \ fprintf(fd, " \n"); \ } #endif static inline void QZ_PRINT(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stdout, format, args); va_end(args); } static inline void QZ_ERROR(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); } #endif QATzip-1.2.1/man/000077500000000000000000000000001465165016500134475ustar00rootroot00000000000000QATzip-1.2.1/man/qzip.1000066400000000000000000000057201465165016500145200ustar00rootroot00000000000000.TH QZIP 1 local .SH NAME qzip \- compress or decompress with qat acceleration .SH SYNOPSIS .ll +8 .B qzip .RB [ " \-AdfhHkLCro " ] [ .I "name \&..." ] .ll -8 .br .SH DESCRIPTION QATzip is a user space library which builds on top of the Intel QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel Chipset Series. QATzip produces data using the standard gzip format (RFC1952) with extended headers. The data can be decompressed with a compliant gzip implementation. QATzip is design to take full advantage of the performance provided by Intel® QuickAssist Technology. .SH OPTIONS .TP .B \-A --algorithm set algorithm type, currently only support deflate .TP .B \-d --decompress decompress .TP .B \-f --force force overwrite of output file and compress links .TP .B \-h --help give this help .TP .B \-H --huffmanhdr set huffman header type .TP .B \-k --keep Keep (don't delete) input files during compression or decompression. .TP .B \-L --level set compression level .TP .B \-C --chunksz set chunk size .TP .B \-r set max in-flight request number .TP .B \-o set output file name .SH COPYRIGHT ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ QATzip-1.2.1/qatzip.pc.in000066400000000000000000000004551465165016500151410ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: qatzip Description: Higher level library provides access to Intel QAT compression URL: https://github.com/intel/QATzip Version: @VERSION@ Libs: -L${libdir} -lqatzip Cflags: -I${includedir} Requires: zlib, liblz4 QATzip-1.2.1/qatzip.spec.in000066400000000000000000000104241465165016500154660ustar00rootroot00000000000000# SPDX-License-Identifier: MIT %global githubname @PACKAGE@ %global libqatzip_soversion 3 Name: @PACKAGE@ Version: @VERSION@ Release: 1%{?dist} Summary: Intel QuickAssist Technology (QAT) QATzip Library License: BSD URL: https://github.com/intel/%{githubname} Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz BuildRequires: gcc >= 4.8.5 BuildRequires: zlib-devel >= 1.2.7 BuildRequires: qatlib-devel >= 22.07.0 BuildRequires: autoconf automake libtool make lz4-devel # The purpose of the package is to support hardware that only exists on x86_64 platforms # https://bugzilla.redhat.com/show_bug.cgi?id=1987280 ExclusiveArch: x86_64 %description QATzip is a user space library which builds on top of the Intel QuickAssist Technology user space library, to provide extended accelerated compression and decompression services by offloading the actual compression and decompression request(s) to the Intel Chipset Series. QATzip produces data using the standard gzip* format (RFC1952) with extended headers. The data can be decompressed with a compliant gzip* implementation. QATzip is designed to take full advantage of the performance provided by Intel QuickAssist Technology. %package libs Summary: Libraries for the qatzip package %description libs This package contains libraries for applications to use the QATzip APIs. %package devel Summary: Development components for the libqatzip package Requires: %{name}-libs%{?_isa} = %{version}-%{release} %description devel This package contains headers and libraries required to build applications that use the QATzip APIs. %prep %autosetup -p0 -n %{githubname}-%{version} %build %set_build_flags autoreconf -vif ./configure \ --bindir=%{_bindir} \ --libdir=%{_libdir} \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ --prefix=%{_prefix} \ --enable-symbol %make_build %install %make_install rm %{buildroot}/%{_libdir}/libqatzip.a rm %{buildroot}/%{_libdir}/libqatzip.la rm -vf %{buildroot}%{_mandir}/*.pdf # Check section is not available for these functional and performance tests require special hardware. %files %license LICENSE* %{_mandir}/man1/qzip.1* %{_bindir}/qzip %{_bindir}/qatzip-test %files libs %license LICENSE* %{_libdir}/libqatzip.so.%{libqatzip_soversion}* %files devel %doc docs/QATzip-man.pdf %{_includedir}/qatzip.h %{_libdir}/libqatzip.so %{_libdir}/pkgconfig/*.pc %changelog * Fri Jan 02 2024 taorong - 1.2.0-1 - Update to qatzip v1.2.0 - Add qatzip-test tool - SW fallback - Fix some bugs * Mon Mar 06 2023 xinghong - 1.1.2-1 - Update to qatzip v1.1.2 - Update README, update driver configure files - Fix some bugs * Fri Jan 20 2023 Fedora Release Engineering - 1.1.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Wed Jan 11 2023 Vladis Dronov - 1.1.1-1 - Update to qatzip v1.1.1 - Add support for pkgconfig * Thu Nov 24 2022 Vladis Dronov - 1.1.0-1 - Rebuild for qatzip v1.1.0 * Mon Aug 08 2022 Vladis Dronov - 1.0.9-1 - Rebuild for qatzip v1.0.9 - Update to require qatlib-devel >= 22.07.0 due to soversion bump * Fri Jul 22 2022 Fedora Release Engineering - 1.0.7-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild * Wed Feb 09 2022 Vladis Dronov - 1.0.7-1 - Rebuild for qatzip v1.0.7 - Fix snprintf truncation check (bz 2046925) - Add -fstack-protector-strong build option (bz 2044889) * Fri Jan 21 2022 Fedora Release Engineering - 1.0.6-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild * Mon Sep 13 2021 zm627 - 1.0.6-3 - Rebuild for qatzip v1.0.6 * Sun Sep 12 2021 zm627 - 1.0.6-2 - Upload new qatzip source package and rebuild * Sun Sep 12 2021 zm627 - 1.0.6-1 - Update to latest qatlib and qatzip upstream release * Sun Sep 12 2021 zm627 - 1.0.5-3 - Add ExcludeArch ticket number * Sun Sep 12 2021 zm627 - 1.0.5-2 - Rebuilt for qatlib v21.08 * Tue Jul 13 2021 Ma Zheng - 1.0.5-1 - Initial version of RPM Package QATzip-1.2.1/specgen.sh000077500000000000000000000042111465165016500146550ustar00rootroot00000000000000#! /bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ set -o errexit # extract version numbers from qatzip_internal.h VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < src/qatzip_internal.h` # Generate qatzip.spec echo "Generating qatzip.spec" echo "QATzip version: $VER" sed < qatzip.spec.in 's/VERSION/'"$VER"'/g'> qatzip.spec if [ -f qatzip.spec ];then echo "qatzip.spec generated" else echo "Failed to generate qatzip.spec" fi QATzip-1.2.1/src/000077500000000000000000000000001465165016500134635ustar00rootroot00000000000000QATzip-1.2.1/src/Makefile.am000066400000000000000000000051451465165016500155240ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ lib_LTLIBRARIES = libqatzip.la libqatzip_la_SOURCES = \ qatzip.c \ qatzip_counter.c \ qatzip_gzip.c \ qatzip_mem.c \ qatzip_stream.c \ qatzip_sw.c \ qatzip_utils.c \ qatzip_lz4.c \ xxhash.c libqatzip_la_CFLAGS = \ -I./ \ -I../include/ \ $(COMMON_CFLAGS) \ $(SAL_CFLAGS) \ $(ADF_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) \ $(AM_CFLAGS) libqatzip_la_LDFLAGS = \ -version-info $(LIBQATZIP_VERSION) \ $(ICP_LDFLAGS) libqatzip_la_LIBADD= $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) QATzip-1.2.1/src/qatzip.c000077500000000000000000002742661465165016500151630ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #define XXH_NAMESPACE QATZIP_ #include "xxhash.h" #ifdef HAVE_QAT_HEADERS #include #include #include #include #include #else #include #include #include #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" /* * Process address space name described in the config file for this device. */ const char *g_dev_tag = "SHIM"; const unsigned int g_polling_interval[] = { 10, 10, 20, 30, 60, 100, 200, 400, 600, 1000, 2000, 4000, 8000, 16000, 32000, 64000 }; #define INTER_SZ(src_sz) (2 * (src_sz)) #define msleep(x) usleep((x) * 1000) #define POLLING_LIST_NUM (sizeof(g_polling_interval) \ / sizeof(unsigned int)) #define MAX_GRAB_RETRY (10) #define GET_BUFFER_SLEEP_NSEC 10 #define QAT_SECTION_NAME_SIZE 32 #define POLL_EVENT_INTERVAL_TIME 1000 /****************************************************** * If enable new compression algorithm, extend new params * structure in API. please add default here. ******************************************************/ QzSessionParamsInternal_T g_sess_params_internal_default = { .huffman_hdr = QZ_HUFF_HDR_DEFAULT, .direction = QZ_DIRECTION_DEFAULT, .data_fmt = DATA_FORMAT_DEFAULT, .comp_lvl = QZ_COMP_LEVEL_DEFAULT, .comp_algorithm = QZ_COMP_ALGOL_DEFAULT, .max_forks = QZ_MAX_FORK_DEFAULT, .sw_backup = QZ_SW_BACKUP_DEFAULT, .hw_buff_sz = QZ_HW_BUFF_SZ, .strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT, .input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT, .req_cnt_thrshold = QZ_REQ_THRESHOLD_DEFAULT, .wait_cnt_thrshold = QZ_WAIT_CNT_THRESHOLD_DEFAULT, .polling_mode = QZ_PERIODICAL_POLLING, .lz4s_mini_match = 3, .qzCallback = NULL, .qzCallback_external = NULL }; pthread_mutex_t g_sess_params_lock = PTHREAD_MUTEX_INITIALIZER; processData_T g_process = { .qz_init_status = QZ_NONE, .qat_available = QZ_NONE }; pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; __thread ThreadData_T g_thread = { .ppid = 0, }; static int setInstance(unsigned int dev_id, QzInstanceList_T *new_instance, QzHardware_T *qat_hw) { if (dev_id >= QAT_MAX_DEVICES || NULL == new_instance || NULL == qat_hw || NULL != new_instance->next) { return QZ_PARAMS; } QzInstanceList_T *instances = &qat_hw->devices[dev_id]; /* first instance */ if (NULL == instances->next) { qat_hw->dev_num++; } while (instances->next) { instances = instances->next; } instances->next = new_instance; if (dev_id > qat_hw->max_dev_id) { qat_hw->max_dev_id = dev_id; } return QZ_OK; } static QzInstanceList_T *getInstance(unsigned int dev_id, QzHardware_T *qat_hw) { if (dev_id >= QAT_MAX_DEVICES || NULL == qat_hw) { return NULL; } QzInstanceList_T *instances = &qat_hw->devices[dev_id]; QzInstanceList_T *first_instance = instances->next; int i; /* no instance */ if (NULL == first_instance) { goto exit; } instances->next = first_instance->next; /* last instance */ if (NULL == instances->next && qat_hw->dev_num > 0) { qat_hw->dev_num--; if (qat_hw->max_dev_id > 0 && dev_id == qat_hw->max_dev_id) { for (i = qat_hw->max_dev_id - 1; i >= 0; i--) { if (qat_hw->devices[i].next) { qat_hw->max_dev_id = i; break; } } } } exit: return first_instance; } static void clearDevices(QzHardware_T *qat_hw) { if (NULL == qat_hw || 0 == qat_hw->dev_num) { return; } for (int i = 0; i < qat_hw->max_dev_id; i++) { QzInstanceList_T *inst = getInstance(i, qat_hw); while (inst) { free(inst); inst = getInstance(i, qat_hw); } } } static void dcCallback(void *cbtag, CpaStatus stat) { long tag, i, j; tag = (long)cbtag; j = GET_LOWER_16BITS(tag); i = tag >> 16; if (g_process.qz_inst[i].stream[j].src1 != g_process.qz_inst[i].stream[j].src2) { QZ_ERROR("FLOW ERROR IN CBi src1 != src2\n"); goto print_err; } if (g_process.qz_inst[i].stream[j].sink1 != g_process.qz_inst[i].stream[j].sink2) { QZ_ERROR("FLOW ERROR IN CBi sink1 != sink2\n"); goto print_err; } if (g_process.qz_inst[i].stream[j].src2 != (g_process.qz_inst[i].stream[j].sink1 + 1)) { QZ_ERROR("FLOW ERROR IN CBi src2 != sink1 + 1\n"); goto print_err; } g_process.qz_inst[i].stream[j].sink1++; g_process.qz_inst[i].stream[j].job_status = stat; goto done; print_err: QZ_ERROR("FLOW ERROR IN CBi %ld %ld\n", i, j); done: return; } static void dcEventCallback(const CpaInstanceHandle instanceHandle, void *pCallbackTag, const CpaInstanceEvent instanceEvent) { long i = (long)pCallbackTag; switch (instanceEvent) { case CPA_INSTANCE_EVENT_RESTARTING: QZ_DEBUG("QAT instance %ld detected Event 'restarting'\n", i); break; case CPA_INSTANCE_EVENT_RESTARTED: g_process.qz_inst[i].heartbeat = CPA_STATUS_SUCCESS; QZ_DEBUG("QAT instance %ld detected Event 'restarted'\n", i); break; case CPA_INSTANCE_EVENT_FATAL_ERROR: g_process.qz_inst[i].heartbeat = CPA_STATUS_FAIL; QZ_DEBUG("QAT instance %ld detected Event 'fatal error'\n", i); break; default: QZ_ERROR("QAT instance %ld detected Unknow Event!\n", i); } } static void *PollingHeartBeat(void *arg) { CpaStatus status = CPA_STATUS_SUCCESS; while (true) { status = icp_sal_poll_device_events(); if (CPA_STATUS_SUCCESS != status) { QZ_DEBUG("Polling device heartbeat is failure!\n"); continue; } /* This time may effect the sw fallback times */ usleep(POLL_EVENT_INTERVAL_TIME); } return ((void *)NULL); } /* * Check the capabilities of instance to ensure that it * supports the data format. For LZ4 or LZ4s if * QAT API Version is less than 3.1, will return QZ_FAIL. */ static inline int qzCheckInstCap(CpaDcInstanceCapabilities *inst_cap, const QzSessionParamsInternal_T *params) { assert(inst_cap != NULL); switch (params->data_fmt) { case LZ4_FH: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) if (!inst_cap->statelessLZ4Compression || !inst_cap->statelessLZ4Decompression || !inst_cap->checksumXXHash32) { return QZ_FAIL; } #else QZ_ERROR("QAT driver does not support lz4 algorithm\n"); return QZ_FAIL; #endif break; case LZ4S_BK: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) if (!inst_cap->checksumXXHash32 || !inst_cap->statelessLZ4SCompression) { return QZ_FAIL; } #else QZ_ERROR("QAT driver does not support lz4s algorithm\n"); return QZ_FAIL; #endif break; case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_RAW: default: if (!inst_cap->statelessDeflateCompression || !inst_cap->statelessDeflateDecompression || !inst_cap->checksumCRC32) { return QZ_FAIL; } /* check if instance support dynamic huffman */ if (!inst_cap->dynamicHuffman && (params->huffman_hdr == QZ_DYNAMIC_HDR)) { return QZ_FAIL; } /* always open the Cnv */ if (!inst_cap->compressAndVerify) { return QZ_FAIL; } /* will extend multi-type checksum check, data format check autoSelect check, Dictionary support, stateful support ..... */ break; } return QZ_OK; } static int qzGrabInstance(int hint, const QzSessionParamsInternal_T *params) { int i, j, rc, f; if (QZ_NONE == g_process.qz_init_status) { return -1; } if (hint >= g_process.num_instances || hint < 0) { hint = 0; } /*otherwise loop through all of them*/ f = 0; for (j = 0; j < MAX_GRAB_RETRY; j++) { for (i = 0; i < g_process.num_instances; i++) { if (f == 0) { i = hint; f = 1; } ; /* Before locking the instance, we need to ensure that * the instance supports the data format. */ if (QZ_OK != qzCheckInstCap(&g_process.qz_inst[i].instance_cap, params)) { continue; } if (CPA_STATUS_SUCCESS != g_process.qz_inst[i].heartbeat) { continue; } rc = __sync_lock_test_and_set(&(g_process.qz_inst[i].lock), 1); if (0 == rc) { return i; } } } return -1; } static int getUnusedBuffer(unsigned long i, int j) { int k; Cpa16U max; max = g_process.qz_inst[i].dest_count; if (j < 0) { j = 0; } else if (j >= max) { j = GET_LOWER_16BITS(max); } for (k = j; k < max; k++) { if ((g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].src2) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink1) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink2)) { return k; } } for (k = 0; k < max; k++) { if ((g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].src2) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink1) && (g_process.qz_inst[i].stream[k].src1 == g_process.qz_inst[i].stream[k].sink2)) { return k; } } return -1; } static void qzReleaseInstance(int i) { __sync_lock_release(&(g_process.qz_inst[i].lock)); } static void init_timers(void) { int i; for (i = 1; i < MAX_THREAD_TMR; i++) { g_thread.timer[i].tv_sec = 0; g_thread.timer[i].tv_usec = 0; } gettimeofday(&g_thread.timer[0], NULL); } static void stopQat(void) { int i; CpaStatus status = CPA_STATUS_SUCCESS; /* Those all show No HW, stopQAT do nothing */ if (CPA_FALSE == g_process.qat_available || QZ_NONE == g_process.qz_init_status || QZ_NO_HW == g_process.qz_init_status || QZ_NOSW_NO_HW == g_process.qz_init_status) { goto reset; } /* scenario: it's called from inside qzinit, Hw init failed */ if (QZ_NO_INST_ATTACH == g_process.qz_init_status) { if (NULL != g_process.dc_inst_handle) { free(g_process.dc_inst_handle); g_process.dc_inst_handle = NULL; } if (NULL != g_process.qz_inst) { free(g_process.qz_inst); g_process.qz_inst = NULL; } (void)icp_sal_userStop(); goto reset; } QZ_DEBUG("Call stopQat.\n"); /* scenario: qzinit succeed. outside qzinit */ if (QZ_OK == g_process.qz_init_status) { if (NULL != g_process.dc_inst_handle && NULL != g_process.qz_inst) { for (i = 0; i < g_process.num_instances; i++) { status = cpaDcStopInstance(g_process.dc_inst_handle[i]); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Stop instance failed, status=%d\n", status); } } free(g_process.dc_inst_handle); g_process.dc_inst_handle = NULL; free(g_process.qz_inst); g_process.qz_inst = NULL; } (void)icp_sal_userStop(); } else { QZ_ERROR("qz init status is invalid, status=%d\n", g_process.qz_init_status); goto reset; } reset: g_process.num_instances = (Cpa16U)0; g_process.qz_init_status = QZ_NONE; g_process.qat_available = QZ_NONE; } static void exitFunc(void) __attribute__((destructor)); static void exitFunc(void) { int i = 0; if (0 != g_process.t_poll_heartbeat) { QZ_DEBUG("cancel the thread!\n"); pthread_cancel(g_process.t_poll_heartbeat); pthread_join(g_process.t_poll_heartbeat, NULL); } for (i = 0; i < g_process.num_instances; i++) { removeSession(i); cleanUpInstMem(i); } streamBufferCleanup(); stopQat(); qzMemDestory(); #ifdef QATZIP_DEBUG dumpThreadInfo(); #endif } static unsigned int getWaitCnt(QzSession_T *sess) { QzSess_T *qz_sess; if (sess->internal != NULL) { qz_sess = (QzSess_T *)sess->internal; return qz_sess->sess_params.wait_cnt_thrshold; } else { return g_sess_params_internal_default.wait_cnt_thrshold; } } #define BACKOUT(hw_status) \ stopQat(); \ if (1 == sw_backup) { \ g_process.qz_init_status = QZ_NO_HW; \ QZ_ERROR("g_process.qz_init_status = QZ_NO_HW\n"); \ rc = QZ_OK; \ } else if (0 == sw_backup) { \ g_process.qz_init_status = QZ_NOSW_NO_HW; \ QZ_ERROR("g_process.qz_init_status = QZ_NOSW_NO_HW\n"); \ rc = hw_status; \ } \ goto done; #define QZ_HW_BACKOUT(hw_status) \ if(qat_hw) { \ clearDevices(qat_hw); \ free(qat_hw); \ } \ BACKOUT(hw_status); const char *getSectionName(void) { static char section_name[QAT_SECTION_NAME_SIZE]; int len; char *pre_section_name; #if __GLIBC_PREREQ(2, 17) pre_section_name = secure_getenv("QAT_SECTION_NAME"); #else pre_section_name = getenv("QAT_SECTION_NAME"); #endif if (!pre_section_name || !(len = strlen(pre_section_name))) { pre_section_name = (char *)g_dev_tag; } else if (len >= QAT_SECTION_NAME_SIZE) { QZ_ERROR("The length of QAT_SECTION_NAME exceeds the limit.\n"); } strncpy(section_name, pre_section_name, QAT_SECTION_NAME_SIZE - 1); section_name[QAT_SECTION_NAME_SIZE - 1] = '\0'; return section_name; } /* Initialize the QAT hardware, get the QAT instance for current * process. * Note: return value doesn't same as qz_init_status, because return * value align limitation. * * After qzInit, there only are three status to qz_init_status * 1. QZ_OK * 2. QZ_NO_HW * 3. QZ_NOSW_NO_HW */ int qzInit(QzSession_T *sess, unsigned char sw_backup) { CpaStatus status; int rc = QZ_NOSW_NO_HW, i; unsigned int dev_id = 0; QzHardware_T *qat_hw = NULL; unsigned int instance_found = 0; static atomic_int waiting = 0; static atomic_int wait_cnt = 0; #ifdef ADF_PCI_API Cpa32U pcie_count = 0; #endif if (unlikely(sess == NULL)) { return QZ_PARAMS; } if (unlikely(sw_backup > 1)) { return QZ_PARAMS; } if (CPA_FALSE == g_process.qat_available || QZ_OK == g_process.qz_init_status) { return QZ_DUPLICATE; } if (unlikely(0 != pthread_mutex_lock(&g_lock))) { return QZ_NOSW_NO_HW; } if (QZ_OK == g_process.qz_init_status) { if (unlikely(0 != pthread_mutex_unlock(&g_lock))) { return QZ_NOSW_NO_HW; } if (g_process.sw_backup != sw_backup) { g_process.sw_backup = sw_backup; } return QZ_DUPLICATE; } g_thread.pid = getpid(); g_thread.ppid = getppid(); init_timers(); g_process.sw_backup = sw_backup; if (waiting && wait_cnt > 0) { wait_cnt--; BACKOUT(QZ_NOSW_NO_HW); } waiting = 0; /* Start HW initialization. it could be first call qzinit or * Before HW init failed, which mean qz_init_status may be * QZ_NOSW_NO_HW or QZ_NO_HW */ #ifdef SAL_DEV_API g_process.qat_available = icp_sal_userIsQatAvailable(); if (CPA_FALSE == g_process.qat_available) { QZ_ERROR("Error no hardware, switch to SW if permitted\n"); BACKOUT(QZ_NOSW_NO_HW); } #else status = icp_adf_get_numDevices(&pcie_count); if (CPA_STATUS_SUCCESS != status) { g_process.qat_available = CPA_FALSE; } if (pcie_count >= 1) { g_process.qat_available = CPA_TRUE; } else { g_process.qat_available = CPA_FALSE; } if (CPA_FALSE == g_process.qat_available) { QZ_ERROR("Error no hardware, switch to SW if permitted status = %d\n", status); BACKOUT(QZ_NOSW_NO_HW); } #endif status = icp_sal_userStartMultiProcess(getSectionName(), CPA_FALSE); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error userStarMultiProcess(%d), switch to SW if permitted\n", status); waiting = 1; wait_cnt = getWaitCnt(sess); BACKOUT(QZ_NOSW_NO_HW); } /* This status only show inside qzinit. And will replace to others when qzinit finished */ g_process.qz_init_status = QZ_NO_INST_ATTACH; status = cpaDcGetNumInstances(&g_process.num_instances); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcGetNumInstances status = %d\n", status); BACKOUT(QZ_NOSW_NO_INST_ATTACH); } QZ_DEBUG("Number of instance: %u\n", g_process.num_instances); g_process.dc_inst_handle = malloc(g_process.num_instances * sizeof(CpaInstanceHandle)); g_process.qz_inst = calloc(g_process.num_instances, sizeof(QzInstance_T)); if (unlikely(NULL == g_process.dc_inst_handle || NULL == g_process.qz_inst)) { QZ_ERROR("malloc failed\n"); BACKOUT(QZ_NOSW_LOW_MEM); } status = cpaDcGetInstances(g_process.num_instances, g_process.dc_inst_handle); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcGetInstances status = %d\n", status); BACKOUT(QZ_NOSW_NO_INST_ATTACH); } qat_hw = calloc(1, sizeof(QzHardware_T)); if (unlikely(NULL == qat_hw)) { QZ_ERROR("malloc failed\n"); BACKOUT(QZ_NOSW_LOW_MEM); } for (i = 0; i < g_process.num_instances; i++) { QzInstanceList_T *new_inst = calloc(1, sizeof(QzInstanceList_T)); if (unlikely(NULL == new_inst)) { QZ_ERROR("malloc failed\n"); QZ_HW_BACKOUT(QZ_NOSW_LOW_MEM); } status = cpaDcInstanceGetInfo2(g_process.dc_inst_handle[i], &new_inst->instance.instance_info); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcInstanceGetInfo2 status = %d\n", status); free(new_inst); QZ_HW_BACKOUT(QZ_NOSW_NO_HW); } status = cpaDcQueryCapabilities(g_process.dc_inst_handle[i], &new_inst->instance.instance_cap); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcQueryCapabilities status = %d\n", status); free(new_inst); QZ_HW_BACKOUT(QZ_NOSW_NO_HW); } new_inst->instance.lock = 0; new_inst->instance.heartbeat = CPA_STATUS_SUCCESS; new_inst->instance.mem_setup = 0; new_inst->instance.cpa_sess_setup = 0; new_inst->instance.num_retries = 0; new_inst->dc_inst_handle = g_process.dc_inst_handle[i]; dev_id = new_inst->instance.instance_info.physInstId.packageId; if (unlikely(QZ_OK != setInstance(dev_id, new_inst, qat_hw))) { QZ_ERROR("Insert instance on device %d failed\n", dev_id); QZ_HW_BACKOUT(QZ_NOSW_NO_INST_ATTACH); } } /* shuffle instance */ for (i = 0; instance_found < g_process.num_instances; i++) { dev_id = i % (qat_hw->max_dev_id + 1); QzInstanceList_T *new_inst = getInstance(dev_id, qat_hw); if (NULL == new_inst) { continue; } QZ_MEMCPY(&g_process.qz_inst[instance_found], &new_inst->instance, sizeof(QzInstance_T), sizeof(QzInstance_T)); g_process.dc_inst_handle[instance_found] = new_inst->dc_inst_handle; free(new_inst); instance_found++; } /* Set EventCallback after instance shuffle */ for (long index = 0; index < instance_found; index++) { status = cpaDcInstanceSetNotificationCb(g_process.dc_inst_handle[index], dcEventCallback, (void *)index); if (CPA_STATUS_SUCCESS != status) { QZ_ERROR("Error in cpaDcInstanceSetNotificationCb status = %d\n", status); QZ_HW_BACKOUT(QZ_NOSW_NO_INST_ATTACH); } } /* Start device heartbeat event detect thread */ if (unlikely(0 != pthread_create(&g_process.t_poll_heartbeat, NULL, PollingHeartBeat, NULL))) { QZ_ERROR("Error Start polling heartbeat events thread failed!\n"); g_process.t_poll_heartbeat = 0; } QZ_DEBUG("the polling event thread id is %d\n", g_process.t_poll_heartbeat); clearDevices(qat_hw); free(qat_hw); rc = g_process.qz_init_status = QZ_OK; done: initDebugLock(); if (unlikely(0 != pthread_mutex_unlock(&g_lock))) { return QZ_NOSW_NO_HW; } return rc; } /* Free up the DMAable memory buffers used by QAT * internally, those buffers are source buffer, * intermediate buffer and destination buffer */ void cleanUpInstMem(int i) { int j; /*intermediate buffers*/ if (NULL != g_process.qz_inst[i].intermediate_buffers) { for (j = 0; j < g_process.qz_inst[i].intermediate_cnt; j++) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].intermediate_buffers[j]); g_process.qz_inst[i].intermediate_buffers[j] = NULL; } } free(g_process.qz_inst[i].intermediate_buffers); g_process.qz_inst[i].intermediate_buffers = NULL; } /*src buffers*/ if (NULL != g_process.qz_inst[i].src_buffers) { for (j = 0; j < g_process.qz_inst[i].src_count; j++) { if (NULL != g_process.qz_inst[i].src_buffers[j]) { if (NULL != g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].src_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].src_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData); g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].src_buffers[j]->pBuffers); g_process.qz_inst[i].src_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].src_buffers[j]); g_process.qz_inst[i].src_buffers[j] = NULL; } } free(g_process.qz_inst[i].src_buffers); g_process.qz_inst[i].src_buffers = NULL; } /*dest buffers*/ if (NULL != g_process.qz_inst[i].dest_buffers) { for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if (NULL != g_process.qz_inst[i].dest_buffers[j]) { if (NULL != g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData) { qzFree(g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData); g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = NULL; } if (NULL != g_process.qz_inst[i].dest_buffers[j]->pBuffers) { if (NULL != g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData) { qzFree(g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData); g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = NULL; } qzFree(g_process.qz_inst[i].dest_buffers[j]->pBuffers); g_process.qz_inst[i].dest_buffers[j]->pBuffers = NULL; } qzFree(g_process.qz_inst[i].dest_buffers[j]); g_process.qz_inst[i].dest_buffers[j] = NULL; } } free(g_process.qz_inst[i].dest_buffers); g_process.qz_inst[i].dest_buffers = NULL; } /*stream buffer*/ if (NULL != g_process.qz_inst[i].stream) { free(g_process.qz_inst[i].stream); g_process.qz_inst[i].stream = NULL; } qzFree(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].mem_setup = 0; } #define QZ_INST_MEM_CHECK(ptr, i) \ if (NULL == (ptr)) { \ cleanUpInstMem((i)); \ rc = sw_backup ? QZ_LOW_MEM : QZ_NOSW_LOW_MEM; \ goto done_inst; \ } #define QZ_INST_MEM_STATUS_CHECK(status, i) \ if (CPA_STATUS_SUCCESS != status) { \ cleanUpInstMem((i)); \ rc = sw_backup ? QZ_NO_INST_ATTACH : QZ_NOSW_NO_INST_ATTACH; \ goto done_inst; \ } /* Allocate the DMAable memory buffers used by QAT * internally, those buffers are source buffer, * intermediate buffer and destination buffer */ static int getInstMem(int i, QzSessionParamsInternal_T *params) { int j; CpaStatus status; CpaStatus rc; unsigned int src_sz; unsigned int inter_sz; unsigned int dest_sz; unsigned char sw_backup; rc = QZ_OK; /* WARN: this will mean the first sess will setup down the inst * buffer size, if it's very small, then we can't make then * any larger in the whole process. please refer test mode 17 */ src_sz = params->hw_buff_sz; inter_sz = INTER_SZ(src_sz); dest_sz = DEST_SZ(src_sz); sw_backup = params->sw_backup; QZ_DEBUG("getInstMem: Setting up memory for inst %d\n", i); status = cpaDcBufferListGetMetaSize(g_process.dc_inst_handle[i], 1, &(g_process.qz_inst[i].buff_meta_size)); QZ_INST_MEM_STATUS_CHECK(status, i); status = cpaDcGetNumIntermediateBuffers(g_process.dc_inst_handle[i], &(g_process.qz_inst[i].intermediate_cnt)); QZ_INST_MEM_STATUS_CHECK(status, i); g_process.qz_inst[i].intermediate_buffers = calloc(1, (size_t)(g_process.qz_inst[i].intermediate_cnt * sizeof( CpaBufferList *))); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers, i); for (j = 0; j < g_process.qz_inst[i].intermediate_cnt; j++) { g_process.qz_inst[i].intermediate_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = qzMalloc((size_t)(g_process.qz_inst[i].buff_meta_size), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK( g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].intermediate_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].intermediate_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers, i); g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(inter_sz, NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->pData, i); g_process.qz_inst[i].intermediate_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].intermediate_buffers[j]->pBuffers->dataLenInBytes = inter_sz; } g_process.qz_inst[i].src_count = NUM_BUFF; g_process.qz_inst[i].dest_count = NUM_BUFF; if (params->hw_buff_sz <= 8 * 1024) { g_process.qz_inst[i].src_count = NUM_BUFF_8K; g_process.qz_inst[i].dest_count = NUM_BUFF_8K; } g_process.qz_inst[i].src_buffers = calloc(1, (size_t)( g_process.qz_inst[i].src_count * sizeof(CpaBufferList *))); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers, i); g_process.qz_inst[i].dest_buffers = calloc(1, g_process.qz_inst[i].dest_count * sizeof(CpaBufferList *)); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers, i); g_process.qz_inst[i].stream = calloc(g_process.qz_inst[i].dest_count, sizeof(QzCpaStream_T)); QZ_INST_MEM_CHECK(g_process.qz_inst[i].stream, i); for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { g_process.qz_inst[i].stream[j].seq = 0; g_process.qz_inst[i].stream[j].src1 = 0; g_process.qz_inst[i].stream[j].src2 = 0; g_process.qz_inst[i].stream[j].sink1 = 0; g_process.qz_inst[i].stream[j].sink2 = 0; g_process.qz_inst[i].src_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = qzMalloc(g_process.qz_inst[i].buff_meta_size, NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].src_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].src_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers, i); g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(src_sz, NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, i); /* The orig_src points internal pre-allocated pinned buffer. */ g_process.qz_inst[i].stream[j].orig_src = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; g_process.qz_inst[i].src_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_sz; } for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { g_process.qz_inst[i].dest_buffers[j] = (CpaBufferList *) qzMalloc(sizeof(CpaBufferList), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j], i); if (0 != g_process.qz_inst[i].buff_meta_size) { g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = qzMalloc(g_process.qz_inst[i].buff_meta_size, NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData, i); } else { g_process.qz_inst[i].dest_buffers[j]->pPrivateMetaData = NULL; } g_process.qz_inst[i].dest_buffers[j]->pBuffers = (CpaFlatBuffer *) qzMalloc(sizeof(CpaFlatBuffer), NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers, i); g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = (Cpa8U *) qzMalloc(dest_sz, NODE_0, PINNED_MEM); QZ_INST_MEM_CHECK(g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, i); /* The orig_dest points internal pre-allocated pinned buffer. */ g_process.qz_inst[i].stream[j].orig_dest = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; g_process.qz_inst[i].dest_buffers[j]->numBuffers = (Cpa32U)1; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_sz; } status = cpaDcSetAddressTranslation(g_process.dc_inst_handle[i], qaeVirtToPhysNUMA); QZ_INST_MEM_STATUS_CHECK(status, i); g_process.qz_inst[i].inst_start_status = cpaDcStartInstance(g_process.dc_inst_handle[i], g_process.qz_inst[i].intermediate_cnt, g_process.qz_inst[i].intermediate_buffers); QZ_INST_MEM_STATUS_CHECK(g_process.qz_inst[i].inst_start_status, i); g_process.qz_inst[i].mem_setup = 1; done_inst: return rc; } /* Initialize the QAT session parameters associate with current * process's QAT instance, the session parameters include various * configurations for compression/decompression request */ int qzSetupSession(QzSession_T *sess, QzSessionParams_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParams_T temp = {0}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaults(&temp); params = &temp; } if (qzCheckParams(params) != QZ_OK) { return QZ_PARAMS; } sess->hw_session_stat = QZ_FAIL; if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } qz_sess = (QzSess_T *)sess->internal; qzSetParams(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionDeflate(QzSession_T *sess, QzSessionParamsDeflate_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsDeflate_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsDeflate(&temp); params = &temp; } if (qzCheckParamsDeflate(params) != QZ_OK) { return QZ_PARAMS; } sess->hw_session_stat = QZ_FAIL; if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } qz_sess = (QzSess_T *)sess->internal; qzSetParamsDeflate(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionLZ4(QzSession_T *sess, QzSessionParamsLZ4_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsLZ4_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsLZ4(&temp); params = &temp; } if (qzCheckParamsLZ4(params) != QZ_OK) { return QZ_PARAMS; } sess->hw_session_stat = QZ_FAIL; if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } qz_sess = (QzSess_T *)sess->internal; qzSetParamsLZ4(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } int qzSetupSessionLZ4S(QzSession_T *sess, QzSessionParamsLZ4S_T *params) { int rc = QZ_OK; QzSess_T *qz_sess; QzSessionParamsLZ4S_T temp = {{0}}; if (unlikely(NULL == sess)) { return QZ_PARAMS; } if (NULL == params) { rc = qzGetDefaultsLZ4S(&temp); params = &temp; } if (qzCheckParamsLZ4S(params) != QZ_OK) { return QZ_PARAMS; } sess->hw_session_stat = QZ_FAIL; if (sess->internal == NULL) { sess->internal = calloc(1, sizeof(QzSess_T)); if (unlikely(NULL == sess->internal)) { sess->hw_session_stat = QZ_NOSW_LOW_MEM; return QZ_NOSW_LOW_MEM; } } else { return QZ_DUPLICATE; } qz_sess = (QzSess_T *)sess->internal; qzSetParamsLZ4S(params, &qz_sess->sess_params); rc = qzSetupSessionInternal(sess); if (rc < 0) { free(sess->internal); sess->internal = NULL; return rc; } return rc; } /* Set up the QAT session associate with current process's * QAT instance */ int qzSetupHW(QzSession_T *sess, int i) { QzSess_T *qz_sess; int rc = QZ_OK; if (g_process.qz_init_status != QZ_OK) { /*hw not present*/ return g_process.qz_init_status; } qz_sess = (QzSess_T *)sess->internal; qz_sess->inst_hint = i; qz_sess->seq = 0; qz_sess->seq_in = 0; if (0 == g_process.qz_inst[i].mem_setup) { rc = getInstMem(i, &(qz_sess->sess_params)); if (QZ_OK != rc) { goto done_sess; } } if (0 == g_process.qz_inst[i].cpa_sess_setup) { /*setup and start DC session*/ QZ_DEBUG("setup and start DC session %d\n", i); qz_sess->sess_status = cpaDcGetSessionSize(g_process.dc_inst_handle[i], &qz_sess->session_setup_data, &qz_sess->session_size, &qz_sess->ctx_size); if (CPA_STATUS_SUCCESS == qz_sess->sess_status) { g_process.qz_inst[i].cpaSess = qzMalloc((size_t)(qz_sess->session_size), NODE_0, PINNED_MEM); if (NULL == g_process.qz_inst[i].cpaSess) { rc = qz_sess->sess_params.sw_backup ? QZ_LOW_MEM : QZ_NOSW_LOW_MEM; goto done_sess; } } else { rc = QZ_FAIL; goto done_sess; } QZ_DEBUG("cpaDcInitSession %d\n", i); qz_sess->sess_status = cpaDcInitSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, &qz_sess->session_setup_data, NULL, dcCallback); if (qz_sess->sess_status != CPA_STATUS_SUCCESS) { rc = QZ_FAIL; } g_process.qz_inst[i].session_setup_data = qz_sess->session_setup_data; } if (rc == QZ_OK) { g_process.qz_inst[i].cpa_sess_setup = 1; } done_sess: return rc; } /* * Update cpa session of instance i, it will remove cpa session first, * and reallocate memory and re-initialize cpa session based on * session setup data. */ int qzUpdateCpaSession(QzSession_T *sess, int i) { QzSess_T *qz_sess; CpaStatus ret = CPA_STATUS_SUCCESS; assert(sess); g_process.qz_inst[i].cpa_sess_setup = 0; qz_sess = (QzSess_T *)sess->internal; assert(qz_sess); /* Remove cpa session */ ret = cpaDcRemoveSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: remove session failed\n"); return QZ_FAIL; } /* free memory of capSess */ qzFree(g_process.qz_inst[i].cpaSess); /* As the session setup data has been updated, need to get the size of * session again. */ ret = cpaDcGetSessionSize(g_process.dc_inst_handle[i], &qz_sess->session_setup_data, &qz_sess->session_size, &qz_sess->ctx_size); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: get session size failed\n"); return QZ_FAIL; } g_process.qz_inst[i].cpaSess = qzMalloc((size_t)(qz_sess->session_size), NODE_0, PINNED_MEM); if (!g_process.qz_inst[i].cpaSess) { QZ_ERROR("qzUpdateCpaSession: allocate session failed\n"); return QZ_FAIL; } ret = cpaDcInitSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, &qz_sess->session_setup_data, NULL, dcCallback); if (ret != CPA_STATUS_SUCCESS) { QZ_ERROR("qzUpdateCpaSession: init session failed\n"); free(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].cpaSess = NULL; return QZ_FAIL; } g_process.qz_inst[i].session_setup_data = qz_sess->session_setup_data; g_process.qz_inst[i].cpa_sess_setup = 1; return QZ_OK; } /* The internal function to send the compression request * to the QAT hardware. * Note: * Only when request offload success, 'submitted' and 'seq' plus, * And update src_ptr, remaining and send_sz * sess->thd_sess_stat only carry QZ_OK and QZ_FAIL */ static void *doCompressIn(void *in) { unsigned long tag; int i, j; unsigned int done = 0; unsigned int src_send_sz; unsigned int remaining; unsigned char *src_ptr; unsigned int hw_buff_sz; CpaStatus rc; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; QZ_DEBUG("Always enable CnV\n"); i = qz_sess->inst_hint; j = -1; /* For offlod request, src_ptr, remaining and src_send_sz will update */ hw_buff_sz = qz_sess->sess_params.hw_buff_sz; src_ptr = qz_sess->src + qz_sess->qz_in_len; remaining = *qz_sess->src_sz - qz_sess->qz_in_len; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; QZ_DEBUG("doCompressIn: Need to g_process %u bytes\n", remaining); while (!done) { if (g_process.qz_inst[i].heartbeat != CPA_STATUS_SUCCESS) { /* Device die, Fallback to sw, don't offload request to HW */ rc = compInSWFallback(i, j, sess, src_ptr, src_send_sz); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } else { /* HW offload */ do { j = getUnusedBuffer(i, j); if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++; /*update stream src1*/ compBufferSetup(i, j, qz_sess, src_ptr, remaining, hw_buff_sz, src_send_sz); g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = ((unsigned long)i << 16) | (unsigned long)j; QZ_DEBUG("Comp Sending %u bytes ,opData.flushFlag = %d, i = %d j = %d seq = %ld tag = %ld\n", g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes, g_process.qz_inst[i].stream[j].opData.flushFlag, i, j, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcCompressData2(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].opData, &g_process.qz_inst[i].stream[j].res, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_ERROR("instance %d retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_ERROR("Inst %d, buffer %d, Error in compIn offload: %d\n", i, j, rc); compInBufferCleanUp(i, j); rc = compInSWFallback(i, j, sess, src_ptr, src_send_sz); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } } QZ_DEBUG("remaining = %u, src_send_sz = %u, seq = %ld\n", remaining, src_send_sz, qz_sess->seq); /* update the request src info status */ src_ptr += src_send_sz; remaining -= src_send_sz; src_send_sz = (remaining < hw_buff_sz) ? remaining : hw_buff_sz; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; if (unlikely(qz_sess->stop_submitting)) { remaining = 0; } if (0 == remaining) { done = 1; qz_sess->last_submitted = 1; } } return ((void *)NULL); err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; qz_sess->last_submitted = 1; sess->thd_sess_stat = QZ_FAIL; return ((void *)NULL); } /* The internal function to g_process the compression response * from the QAT hardware * sess->thd_sess_stat only carry QZ_OK and QZ_FAIL and QZ_BUF_ERROR */ static void *doCompressOut(void *in) { int i = 0, j = 0; int rc = 0; int good = -1; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; QzSession_T *sess = (QzSession_T *) in; QzSess_T *qz_sess = (QzSess_T *) sess->internal; long dest_avail_len = (long)(*qz_sess->dest_sz - qz_sess->qz_out_len); i = qz_sess->inst_hint; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; while ((qz_sess->last_submitted == 0) || (qz_sess->processed < qz_sess->submitted)) { /* Poll for responses */ good = 0; /* For this call, return error, we have to make sure all stream buffer is reset * which is not just for RestoreSrcCpastreamBuffer, but also * make src1, src2, sink1, sink2 equal, and all switch. */ sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* this will cause the in-flight request is not finished */ QZ_ERROR("Error in DcPoll: %d\n", sts); goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doCompressOut: Processing seqnumber %2.2d " "%2.2d %4.4ld, PID: %d, TID: %lu\n", i, j, g_process.qz_inst[i].stream[j].seq, getpid(), pthread_self()); if (unlikely(QZ_BUF_ERROR == sess->thd_sess_stat)) { compOutSkipErrorRespond(i, j, qz_sess); continue; } /* res.status is passed into QAT by cpaDcCompressData2, and changed in * dcCompression_ProcessCallback, it's type is CpaDcReqStatus. * job_status is from the dccallback, it's type is CpaStatus. * Generally, the res.status should have more detailed info about device error * we assume fallback feature will always call callback func, as well as * cpaDcCompressData2 return success. res.status and job_status should * all return Error status, but with different error number. */ resl = &g_process.qz_inst[i].stream[j].res; if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status || CPA_DC_OK != resl->status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); /* polled error/dummy respond , fallback to sw */ rc = compOutSWFallback(i, j, sess, &dest_avail_len); if (QZ_FAIL == rc) { QZ_ERROR("Error in SW CompOut:inst %d, buffer %d, seq %ld\n", i, j, qz_sess->seq_in); goto err_exit; } if (QZ_BUF_ERROR == rc) { continue; } } else { /* polled HW respond */ QZ_DEBUG("\tHW CompOut: consumed = %d, produced = %d, seq_in = %ld\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq); unsigned int dest_receive_sz = outputHeaderSz(data_fmt) + resl->produced + outputFooterSz(data_fmt); if (QZ_OK != compOutCheckDestLen(i, j, sess, &dest_avail_len, dest_receive_sz)) { continue; } /* Update qz_sess info and clean dest buffer */ outputHeaderGen(qz_sess->next_dest, resl, data_fmt); qz_sess->next_dest += outputHeaderSz(data_fmt); qz_sess->qz_out_len += outputHeaderSz(data_fmt); compOutValidDestBufferCleanUp(i, j, qz_sess, resl->produced); qz_sess->next_dest += resl->produced; qz_sess->qz_in_len += resl->consumed; if (likely(NULL != qz_sess->crc32 && IS_DEFLATE(data_fmt))) { if (0 == *(qz_sess->crc32)) { *(qz_sess->crc32) = resl->checksum; } else { *(qz_sess->crc32) = crc32_combine(*(qz_sess->crc32), resl->checksum, resl->consumed); } } qz_sess->qz_out_len += resl->produced; outputFooterGen(qz_sess, resl, data_fmt); qz_sess->next_dest += outputFooterSz(data_fmt); qz_sess->qz_out_len += outputFooterSz(data_fmt); } /* process finished! */ compOutProcessedRespond(i, j, qz_sess); break; } } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("comp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Comp sleep_cnt: %u\n", sleep_cnt); if (qz_sess->stop_submitting || qz_sess->last_submitted) { qz_sess->last_processed = 1; } else { qz_sess->last_processed = 0; } return NULL; err_exit: sess->thd_sess_stat = QZ_FAIL; qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; /*clean stream buffer*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } return NULL; } unsigned char getSwBackup(QzSession_T *sess) { QzSess_T *qz_sess; if (sess->internal != NULL) { qz_sess = (QzSess_T *)sess->internal; return qz_sess->sess_params.sw_backup; } else { return g_sess_params_internal_default.sw_backup; } } static void resetQzsess(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, const unsigned char *dest, unsigned int *dest_len, unsigned int last) { QzSess_T *qz_sess; qz_sess = (QzSess_T *)(sess->internal); sess->thd_sess_stat = QZ_OK; qz_sess->submitted = 0; qz_sess->processed = 0; qz_sess->last_submitted = 0; qz_sess->last_processed = 0; qz_sess->stop_submitting = 0; qz_sess->qz_in_len = 0; qz_sess->qz_out_len = 0; qz_sess->force_sw = 0; qz_sess->single_thread = 0; qz_sess->seq = 0; qz_sess->seq_in = 0; qz_sess->src = (unsigned char *)src; qz_sess->src_sz = src_len; qz_sess->dest_sz = dest_len; qz_sess->next_dest = (unsigned char *)dest; qz_sess->last = last; } static int lz4sPostProcess(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc) { QzSess_T *qz_sess; qz_sess = (QzSess_T *)(sess->internal); if (sess->thd_sess_stat == QZ_OK || (sess->thd_sess_stat == QZ_BUF_ERROR && 0 != *src_len)) { int error_code = 0; int callback_status = qz_sess->sess_params.qzCallback( qz_sess->sess_params.qzCallback_external, src, src_len, dest, dest_len, &error_code); if (callback_status == QZ_OK) { qz_sess->qz_out_len = *dest_len; if (!ext_rc) { QZ_ERROR("Invalid ext_rc pointer!\n"); } else { *ext_rc = 0; } } else { QZ_ERROR("Error when call lz4s post-processing callback\n"); if (!ext_rc) { QZ_ERROR("Invalid ext_rc pointer!\n"); } else { *ext_rc = (uint64_t)error_code; } sess->thd_sess_stat = callback_status; return sess->thd_sess_stat; } } else { QZ_ERROR("Error lz4s compresse failed\n"); return QZ_FAIL; } return QZ_OK; } /* The QATzip compression API */ int qzCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { return qzCompressExt(sess, src, src_len, dest, dest_len, last, NULL); } int qzCompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, uint64_t *ext_rc) { if (NULL == sess || (last != 0 && last != 1)) { if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return QZ_PARAMS; } return qzCompressCrcExt(sess, src, src_len, dest, dest_len, last, NULL, ext_rc); } int qzCompressCrc(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc) { return qzCompressCrcExt(sess, src, src_len, dest, dest_len, last, crc, NULL); } int qzCompressCrcExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last, unsigned long *crc, uint64_t *ext_rc) { int i, reqcnt; QzSess_T *qz_sess; int rc; if (unlikely(NULL == sess || \ NULL == src || \ NULL == src_len || \ NULL == dest || \ NULL == dest_len || \ (last != 0 && last != 1))) { rc = QZ_PARAMS; goto err_exit; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { goto err_exit; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { if (g_sess_params_internal_default.data_fmt == LZ4_FH) { rc = qzSetupSessionLZ4(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == LZ4S_BK) { rc = qzSetupSessionLZ4S(sess, NULL); } else { rc = qzSetupSessionDeflate(sess, NULL); } if (unlikely(QZ_SETUP_SESSION_FAIL(rc))) { goto err_exit; } } qz_sess = (QzSess_T *)(sess->internal); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if (unlikely(data_fmt != DEFLATE_4B && data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_GZIP && data_fmt != DEFLATE_GZIP_EXT && data_fmt != LZ4_FH && data_fmt != LZ4S_BK)) { QZ_ERROR("Unknown data format: %d\n", data_fmt); rc = QZ_UNSUPPORTED_FMT; goto err_exit; } QZ_DEBUG("qzCompressCrc data_fmt: %d, input crc32 is 0x%lX\n", data_fmt, crc ? *crc : 0); qz_sess->crc32 = crc; if (*src_len < qz_sess->sess_params.input_sz_thrshold || g_process.qz_init_status == QZ_NO_HW || sess->hw_session_stat == QZ_NO_HW #if !((CPA_DC_API_VERSION_NUM_MAJOR >= 3) && (CPA_DC_API_VERSION_NUM_MINOR >= 0)) || qz_sess->sess_params.comp_lvl == 9 #endif ) { QZ_DEBUG("compression src_len=%u, sess_params.input_sz_thrshold = %u, " "process.qz_init_status = %d, sess->hw_session_stat = %ld, " " switch to software.\n", *src_len, qz_sess->sess_params.input_sz_thrshold, g_process.qz_init_status, sess->hw_session_stat); goto sw_compression; } else if (sess->hw_session_stat != QZ_OK && sess->hw_session_stat != QZ_NO_INST_ATTACH) { rc = sess->hw_session_stat; goto err_exit; } i = qzGrabInstance(qz_sess->inst_hint, &(qz_sess->sess_params)); if (unlikely(i == -1)) { if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { sess->hw_session_stat = QZ_NO_INST_ATTACH; rc = QZ_NOSW_NO_INST_ATTACH; goto err_exit; } /*Make this a s/w compression*/ } QZ_DEBUG("qzCompress: inst is %d\n", i); qz_sess->inst_hint = i; if (likely(0 == g_process.qz_inst[i].mem_setup || 0 == g_process.qz_inst[i].cpa_sess_setup)) { QZ_DEBUG("Getting HW resources for inst %d\n", i); rc = qzSetupHW(sess, i); if (unlikely(QZ_OK != rc)) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { goto err_exit; } } } else if (memcmp(&g_process.qz_inst[i].session_setup_data, &qz_sess->session_setup_data, sizeof(CpaDcSessionSetupData))) { /* session_setup_data of qz_sess is not same with instance i, need to update cpa session of instance i. */ rc = qzUpdateCpaSession(sess, i); if (QZ_OK != rc) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_compression; } else { goto err_exit; } } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), COMPRESSION, HW); #endif resetQzsess(sess, src, src_len, dest, dest_len, last); reqcnt = *src_len / qz_sess->sess_params.hw_buff_sz; if (*src_len % qz_sess->sess_params.hw_buff_sz) { reqcnt++; } if (reqcnt > qz_sess->sess_params.req_cnt_thrshold) { pthread_create(&(qz_sess->c_th_i), NULL, doCompressIn, (void *)sess); doCompressOut((void *)sess); pthread_join(qz_sess->c_th_i, NULL); } else { qz_sess->single_thread = 1; doCompressIn((void *)sess); doCompressOut((void *)sess); } qzReleaseInstance(i); rc = sess->thd_sess_stat; if (qz_sess->seq != qz_sess->seq_in) { /* this means the HW get data already error, qz_in_len and qz_out_len can't equal */ QZ_ERROR("The thread : %lu, Compress API failed! fatal error!\n", pthread_self()); goto err_exit; } /* if failure need to fallback to sw */ if (QZ_OK != sess->thd_sess_stat && QZ_BUF_ERROR != rc && qz_sess->sess_params.sw_backup == 1) { const unsigned char *sw_src = src + qz_sess->qz_in_len; unsigned int sw_src_len = *src_len - qz_sess->qz_in_len; unsigned char *sw_dest = qz_sess->next_dest; unsigned int sw_dest_len = *dest_len - (qz_sess->next_dest - dest); QZ_DEBUG("SW Comp Sending %u bytes, the rest comp all fallback to SW", sw_src_len); rc = qzSWCompress(sess, sw_src, &sw_src_len, sw_dest, &sw_dest_len, last); if (QZ_OK == rc) { qz_sess->qz_in_len += sw_src_len; qz_sess->qz_out_len += sw_dest_len; qz_sess->next_dest += sw_dest_len; sess->thd_sess_stat = rc; } else { QZ_ERROR("SW Comp fallback failure! compress fatal ERROR!\n"); } } *dest_len = qz_sess->next_dest - dest; *src_len = GET_LOWER_32BITS(qz_sess->qz_in_len); sess->total_in += qz_sess->qz_in_len; sess->total_out += qz_sess->qz_out_len; QZ_DEBUG("\n********* total_in = %lu total_out = %lu src_len = %u dest_len = %u\n", sess->total_in, sess->total_out, *src_len, *dest_len); assert(*dest_len == qz_sess->qz_out_len); //trigger post-processing if (data_fmt == LZ4S_BK && qz_sess->sess_params.qzCallback) { rc = lz4sPostProcess(sess, src, src_len, dest, dest_len, ext_rc); if (QZ_OK != rc) { goto err_exit; } } return sess->thd_sess_stat; sw_compression: QZ_DEBUG("The thread : %lu, Compress API SW fallback due to HW limitaions!\n", pthread_self()); return qzSWCompress(sess, src, src_len, dest, dest_len, last); err_exit: if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return rc; } /* The internal function to send the decompression request * to the QAT hardware * sess->thd_sess_stat carry QZ_OK && QZ_DATA_ERROR && QZ_BUF_ERROR && QZ_FAIL */ static void *doDecompressIn(void *in) { unsigned long i, tag; int rc; int j; unsigned int done = 0; unsigned int remaining; unsigned int src_avail_len, dest_avail_len; unsigned int tmp_src_avail_len, tmp_dest_avail_len; unsigned char *src_ptr; unsigned char *dest_ptr; QzGzH_T hdr = {{0}, 0}; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; struct timespec sleep_time; sleep_time.tv_sec = 0; sleep_time.tv_nsec = GET_BUFFER_SLEEP_NSEC; i = qz_sess->inst_hint; j = -1; /* For offlod request, src_ptr, dest_ptr, remaining and src_avail_len, dest_avail_len will update */ src_ptr = qz_sess->src + qz_sess->qz_in_len; dest_ptr = qz_sess->next_dest; remaining = *qz_sess->src_sz - qz_sess->qz_in_len; src_avail_len = remaining; dest_avail_len = (long)(*qz_sess->dest_sz - qz_sess->qz_out_len); QZ_DEBUG("doDecompressIn: Need to g_process %d bytes\n", remaining); /* rc will only maintain in this function, thd_sess_stat will return the error status */ while (!done) { QZ_DEBUG("src_avail_len is %u, dest_avail_len is %u\n", src_avail_len, dest_avail_len); rc = checkHeader(qz_sess, src_ptr, src_avail_len, dest_avail_len, &hdr); if (QZ_OK != rc && QZ_FORCE_SW != rc) { sess->thd_sess_stat = rc; goto err_exit; } if (g_process.qz_inst[i].heartbeat != CPA_STATUS_SUCCESS || QZ_FORCE_SW == rc) { tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } else { /*HW decompression*/ do { j = getUnusedBuffer(i, j); if (qz_sess->single_thread) { if (unlikely((-1 == j) || ((0 == qz_sess->seq % qz_sess->sess_params.req_cnt_thrshold) && (qz_sess->seq > qz_sess->seq_in)))) { return ((void *) NULL); } } else { if (unlikely(-1 == j)) { nanosleep(&sleep_time, NULL); } } } while (-1 == j); QZ_DEBUG("getUnusedBuffer returned %d\n", j); g_process.qz_inst[i].stream[j].src1++;/*this buffer is in use*/ decompBufferSetup(i, j, qz_sess, src_ptr, dest_ptr, src_avail_len, &hdr, &tmp_src_avail_len, &tmp_dest_avail_len); g_process.qz_inst[i].stream[j].src2++;/*this buffer is in use*/ do { tag = (i << 16) | j; QZ_DEBUG("Decomp Sending i = %ld j = %d src_ptr = %p dest_ptr = %p seq = %ld tag = %ld\n", i, j, src_ptr, dest_ptr, g_process.qz_inst[i].stream[j].seq, tag); rc = cpaDcDecompressData(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess, g_process.qz_inst[i].src_buffers[j], g_process.qz_inst[i].dest_buffers[j], &g_process.qz_inst[i].stream[j].res, CPA_DC_FLUSH_FINAL, (void *)(tag)); if (unlikely(CPA_STATUS_RETRY == rc)) { g_process.qz_inst[i].num_retries++; usleep(g_polling_interval[qz_sess->polling_idx]); } if (unlikely(g_process.qz_inst[i].num_retries > MAX_NUM_RETRY)) { QZ_ERROR("instance %lu retry count:%d exceed the max count: %d\n", i, g_process.qz_inst[i].num_retries, MAX_NUM_RETRY); break; } } while (rc == CPA_STATUS_RETRY); g_process.qz_inst[i].num_retries = 0; if (unlikely(CPA_STATUS_SUCCESS != rc)) { QZ_ERROR("Inst %ld, buffer %d, Error in decompIn offload: %d\n", i, j, rc); decompInBufferCleanUp(i, j); tmp_src_avail_len = src_avail_len; tmp_dest_avail_len = dest_avail_len; rc = decompInSWFallback(i, j, sess, src_ptr, dest_ptr, &tmp_src_avail_len, &tmp_dest_avail_len); if (QZ_WAIT_SW_PENDING == rc) { continue; } if (QZ_OK != rc) { goto err_exit; } } } /* update the request src info status */ src_ptr += tmp_src_avail_len; dest_ptr += tmp_dest_avail_len; src_avail_len -= tmp_src_avail_len; dest_avail_len -= tmp_dest_avail_len; remaining -= tmp_src_avail_len; /* update qz_sess status */ qz_sess->seq++; qz_sess->submitted++; if (qz_sess->stop_submitting) { remaining = 0; } QZ_DEBUG("src_ptr is %p, remaining is %d\n", src_ptr, remaining); if (0 == remaining) { done = 1; qz_sess->last_submitted = 1; } } return ((void *)NULL); err_exit: /*reset the qz_sess status*/ qz_sess->stop_submitting = 1; qz_sess->last_submitted = 1; return ((void *)NULL); } /* The internal function to g_process the decompression response * from the QAT hardware */ /* A fix for the chunksize test performance. Without the attribute * cold it will lead to a performance drop in the chunksize test. * Will root cause it and fix it in the future version * * sess->thd_sess_stat carry QZ_OK && QZ_DATA_ERROR && QZ_FAIL * QZ_DATA_ERROR it seems have conflict with decompressIn */ static void *__attribute__((cold)) doDecompressOut(void *in) { int i = 0, j = 0, good; int rc = 0; CpaDcRqResults *resl; CpaStatus sts; unsigned int sleep_cnt = 0; unsigned int done = 0; unsigned int src_send_sz; unsigned int dest_avail_len; QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; QzPollingMode_T polling_mode = qz_sess->sess_params.polling_mode; i = qz_sess->inst_hint; dest_avail_len = *qz_sess->dest_sz - qz_sess->qz_out_len; while (!done) { /* Poll for responses */ good = 0; sts = icp_sal_DcPollInstance(g_process.dc_inst_handle[i], 0); if (unlikely(CPA_STATUS_FAIL == sts)) { /* if this error, we don't know which buffer is swapped */ QZ_ERROR("Error in DcPoll: %d\n", sts); goto err_exit; } /*fake a retrieve*/ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { if ((g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in) && (g_process.qz_inst[i].stream[j].src1 == g_process.qz_inst[i].stream[j].src2) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].src1) && (g_process.qz_inst[i].stream[j].sink1 == g_process.qz_inst[i].stream[j].sink2 + 1)) { good = 1; QZ_DEBUG("doDecompressOut: Processing seqnumber %2.2d %2.2d %4.4ld\n", i, j, g_process.qz_inst[i].stream[j].seq); if (unlikely(QZ_DATA_ERROR == sess->thd_sess_stat)) { decompOutSkipErrorRespond(i, j, qz_sess); continue; } if (unlikely(CPA_STATUS_SUCCESS != g_process.qz_inst[i].stream[j].job_status)) { QZ_DEBUG("Error(%d) in callback: %d, %d, ReqStatus: %d\n", g_process.qz_inst[i].stream[j].job_status, i, j, g_process.qz_inst[i].stream[j].res.status); /* polled error/dummy respond , fallback to sw */ rc = decompOutSWFallback(i, j, sess, &dest_avail_len); if (QZ_FAIL == rc) { QZ_ERROR("Error in SW deCompOut:inst %d, buffer %d, seq %ld\n", i, j, qz_sess->seq_in); /* Need to swap buffer, even sw fallback failed */ swapDataBuffer(i, j); goto err_exit; } } else { resl = &g_process.qz_inst[i].stream[j].res; QZ_DEBUG("\tHW DecompOut: consumed = %d, produced = %d, seq_in = %ld, src_send_sz = %u\n", resl->consumed, resl->produced, g_process.qz_inst[i].stream[j].seq, g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes); /* update the qz_sess info and clean dest buffer */ decompOutValidDestBufferCleanUp(i, j, qz_sess, resl, dest_avail_len); if (QZ_OK != decompOutCheckSum(i, j, sess, resl)) { continue; } src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; qz_sess->next_dest += resl->produced; qz_sess->qz_in_len += (outputHeaderSz(data_fmt) + src_send_sz + outputFooterSz(data_fmt)); qz_sess->qz_out_len += resl->produced; dest_avail_len -= resl->produced; } decompOutProcessedRespond(i, j, qz_sess); break; } } if (qz_sess->single_thread) { done = (qz_sess->processed == qz_sess->submitted); } else { done = (qz_sess->last_submitted) && (qz_sess->processed == qz_sess->submitted); } if (QZ_PERIODICAL_POLLING == polling_mode) { if (0 == good) { qz_sess->polling_idx = (qz_sess->polling_idx >= POLLING_LIST_NUM - 1) ? (POLLING_LIST_NUM - 1) : (qz_sess->polling_idx + 1); QZ_DEBUG("decomp sleep for %d usec..., for inst %d\n", g_polling_interval[qz_sess->polling_idx], i); usleep(g_polling_interval[qz_sess->polling_idx]); sleep_cnt++; } else { qz_sess->polling_idx = (qz_sess->polling_idx == 0) ? (0) : (qz_sess->polling_idx - 1); } } } QZ_DEBUG("Decomp sleep_cnt: %u\n", sleep_cnt); qz_sess->last_processed = qz_sess->last_submitted ? 1 : 0; return NULL; err_exit: qz_sess->stop_submitting = 1; qz_sess->last_processed = 1; sess->thd_sess_stat = QZ_FAIL; /* clean stream buffer */ for (j = 0; j < g_process.qz_inst[i].dest_count; j++) { RestoreSrcCpastreamBuffer(i, j); RestoreDestCpastreamBuffer(i, j); ResetCpastreamSink(i, j); } /* need add flag for buffer swap. swapDataBuffer(i, j); */ return ((void *)NULL); } /* The internal function to process the single thread decompress * in qzDecompress() */ static void *doQzDecompressSingleThread(void *in) { QzSession_T *sess = (QzSession_T *)in; QzSess_T *qz_sess = (QzSess_T *)sess->internal; qz_sess->last_processed = 0; while (!qz_sess->last_processed) { doDecompressIn((void *)sess); doDecompressOut((void *)sess); } return NULL; } /* The QATzip decompression API */ int qzDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { return qzDecompressExt(sess, src, src_len, dest, dest_len, NULL); } int qzDecompressExt(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, uint64_t *ext_rc) { int rc; int i, reqcnt; QzSess_T *qz_sess; QzGzH_T *hdr = (QzGzH_T *)src; if (unlikely(NULL == sess || \ NULL == src || \ NULL == src_len || \ NULL == dest || \ NULL == dest_len)) { rc = QZ_PARAMS; goto err_exit; } if (0 == *src_len) { *dest_len = 0; return QZ_OK; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { goto err_exit; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { if (g_sess_params_internal_default.data_fmt == LZ4_FH) { rc = qzSetupSessionLZ4(sess, NULL); } else if (g_sess_params_internal_default.data_fmt == LZ4S_BK) { rc = qzSetupSessionLZ4S(sess, NULL); } else { rc = qzSetupSessionDeflate(sess, NULL); } if (unlikely(QZ_SETUP_SESSION_FAIL(rc))) { goto err_exit; } } qz_sess = (QzSess_T *)(sess->internal); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if (unlikely(data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_4B && data_fmt != DEFLATE_GZIP && data_fmt != LZ4_FH && data_fmt != DEFLATE_GZIP_EXT)) { QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); rc = QZ_UNSUPPORTED_FMT; goto err_exit; } QZ_DEBUG("qzDecompress data_fmt: %d\n", data_fmt); if (data_fmt == DEFLATE_RAW || (data_fmt == DEFLATE_GZIP_EXT && hdr->extra.qz_e.src_sz < qz_sess->sess_params.input_sz_thrshold) || g_process.qz_init_status == QZ_NO_HW || sess->hw_session_stat == QZ_NO_HW || !(isQATProcessable(src, src_len, qz_sess)) || qz_sess->inflate_stat == InflateOK) { QZ_DEBUG("decompression src_len=%u, hdr->extra.qz_e.src_sz = %u, " "g_process.qz_init_status = %d, sess->hw_session_stat = %ld, " "isQATProcessable = %d, switch to software.\n", *src_len, hdr->extra.qz_e.src_sz, g_process.qz_init_status, sess->hw_session_stat, isQATProcessable(src, src_len, qz_sess)); /* If sw_backup is 1, fallback to software compression. */ if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { rc = QZ_FAIL; goto err_exit; } } else if (sess->hw_session_stat != QZ_OK && sess->hw_session_stat != QZ_NO_INST_ATTACH) { rc = sess->hw_session_stat; goto err_exit; } i = qzGrabInstance(qz_sess->inst_hint, &(qz_sess->sess_params)); if (unlikely(i == -1)) { if (qz_sess->sess_params.sw_backup == 1) { QZ_DEBUG("Don't grab HW instance, fallback to sw\n"); goto sw_decompression; } else { rc = sess->hw_session_stat = QZ_NO_INST_ATTACH; goto err_exit; } /*Make this a s/w compression*/ } QZ_DEBUG("qzDecompress: inst is %d\n", i); qz_sess->inst_hint = i; if (likely(0 == g_process.qz_inst[i].mem_setup || 0 == g_process.qz_inst[i].cpa_sess_setup)) { QZ_DEBUG("Getting HW resources for inst %d\n", i); rc = qzSetupHW(sess, i); if (unlikely(QZ_OK != rc)) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { goto err_exit; } } } else if (memcmp(&g_process.qz_inst[i].session_setup_data, &qz_sess->session_setup_data, sizeof(CpaDcSessionSetupData))) { /* session_setup_data of qz_sess is not same with instance i, need to update cpa session of instance i. */ rc = qzUpdateCpaSession(sess, i); if (QZ_OK != rc) { qzReleaseInstance(i); if (qz_sess->sess_params.sw_backup == 1) { goto sw_decompression; } else { goto err_exit; } } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, HW); #endif resetQzsess(sess, src, src_len, dest, dest_len, 0); reqcnt = *src_len / (qz_sess->sess_params.hw_buff_sz / 2); if (*src_len % (qz_sess->sess_params.hw_buff_sz / 2)) { reqcnt++; } if (reqcnt > qz_sess->sess_params.req_cnt_thrshold) { qz_sess->single_thread = 0; pthread_create(&(qz_sess->c_th_i), NULL, doDecompressIn, (void *)sess); doDecompressOut((void *)sess); pthread_join(qz_sess->c_th_i, NULL); } else { qz_sess->single_thread = 1; doQzDecompressSingleThread((void *)sess); } qzReleaseInstance(i); QZ_DEBUG("PRoduced %lu bytes\n", sess->total_out); rc = sess->thd_sess_stat; if (qz_sess->seq != qz_sess->seq_in) { /* this means the HW get data already error, qz_in_len and qz_out_len can't corresponding */ QZ_ERROR("The thread : %lu, Decompress API failed! error status %d!\n", pthread_self(), rc); goto err_exit; } /* if failure need to fallback to sw */ if (QZ_OK != sess->thd_sess_stat && QZ_BUF_ERROR != sess->thd_sess_stat && QZ_DATA_ERROR != sess->thd_sess_stat && qz_sess->sess_params.sw_backup == 1) { const unsigned char *sw_src = src + qz_sess->qz_in_len; unsigned int sw_src_len = *src_len - qz_sess->qz_in_len; unsigned char *sw_dest = qz_sess->next_dest; unsigned int sw_dest_len = *dest_len - (qz_sess->next_dest - dest); QZ_DEBUG("SW deComp Sending %u bytes, the rest decomp all fallback to SW", sw_src_len); rc = qzSWDecompressMulti(sess, sw_src, &sw_src_len, sw_dest, &sw_dest_len); if (QZ_OK == rc) { qz_sess->qz_in_len += sw_src_len; qz_sess->qz_out_len += sw_dest_len; qz_sess->next_dest += sw_dest_len; sess->thd_sess_stat = rc; } else { QZ_ERROR("SW deComp fallback failure! compress fatal ERROR!\n"); } } *src_len = GET_LOWER_32BITS(qz_sess->qz_in_len); *dest_len = qz_sess->next_dest - dest; assert(*dest_len == qz_sess->qz_out_len); sess->total_in += qz_sess->qz_in_len; sess->total_out += qz_sess->qz_out_len; QZ_DEBUG("total_in=%lu total_out=%lu src_len=%u dest_len=%u rc=%d\n", sess->total_in, sess->total_out, *src_len, *dest_len, rc); return sess->thd_sess_stat; sw_decompression: QZ_DEBUG("The thread : %lu, DeCompress API SW fallback due to HW limitations!\n", pthread_self()); return qzSWDecompressMulti(sess, src, src_len, dest, dest_len); err_exit: if (NULL != src_len) { *src_len = 0; } if (NULL != dest_len) { *dest_len = 0; } return rc; } int qzTeardownSession(QzSession_T *sess) { if (unlikely(sess == NULL)) { return QZ_PARAMS; } if (likely(NULL != sess->internal)) { QzSess_T *qz_sess = (QzSess_T *) sess->internal; if (likely(NULL != qz_sess->inflate_strm)) { inflateEnd(qz_sess->inflate_strm); free(qz_sess->inflate_strm); qz_sess->inflate_strm = NULL; } if (likely(NULL != qz_sess->deflate_strm)) { deflateEnd(qz_sess->deflate_strm); free(qz_sess->deflate_strm); qz_sess->deflate_strm = NULL; } free(sess->internal); sess->internal = NULL; } return QZ_OK; } void removeSession(int i) { CpaStatus status = CPA_STATUS_SUCCESS; if (0 == g_process.qz_inst[i].cpa_sess_setup) { return; } /* Remove session */ if ((NULL != g_process.dc_inst_handle[i]) && (NULL != g_process.qz_inst[i].cpaSess)) { status = cpaDcRemoveSession(g_process.dc_inst_handle[i], g_process.qz_inst[i].cpaSess); if (CPA_STATUS_SUCCESS == status) { /* Deallocate session memory */ qzFree(g_process.qz_inst[i].cpaSess); g_process.qz_inst[i].cpaSess = NULL; g_process.qz_inst[i].cpa_sess_setup = 0; } else { QZ_ERROR("ERROR in Remove Instance %d session\n", i); } } } int qzClose(QzSession_T *sess) { if (unlikely(sess == NULL)) { return QZ_PARAMS; } return QZ_OK; } int qzGetStatus(QzSession_T *sess, QzStatus_T *status) { if (sess == NULL || status == NULL) { return QZ_PARAMS; } return QZ_OK; } int qzSetDefaults(QzSessionParams_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParams(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParams(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsDeflate(QzSessionParamsDeflate_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsDeflate(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsDeflate(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsLZ4(QzSessionParamsLZ4_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsLZ4(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsLZ4(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzSetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } if (qzCheckParamsLZ4S(defaults) != QZ_OK) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzSetParamsLZ4S(defaults, &g_sess_params_internal_default); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaults(QzSessionParams_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParams(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsDeflate(QzSessionParamsDeflate_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsDeflate(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsLZ4(QzSessionParamsLZ4_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsLZ4(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } int qzGetDefaultsLZ4S(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { return QZ_PARAMS; } pthread_mutex_lock(&g_sess_params_lock); qzGetParamsLZ4S(&g_sess_params_internal_default, defaults); pthread_mutex_unlock(&g_sess_params_lock); return QZ_OK; } static unsigned int qzDeflateBound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; unsigned int hw_buffer_sz = 0; QzSess_T *qz_sess = NULL; CpaDcHuffType huffman_type; CpaStatus status = CPA_STATUS_SUCCESS; qz_sess = (QzSess_T *)sess->internal; /* Get the Huffman Tree type. */ if (qz_sess->sess_params.huffman_hdr == QZ_DYNAMIC_HDR) { huffman_type = CPA_DC_HT_FULL_DYNAMIC; } else { huffman_type = CPA_DC_HT_STATIC; } status = cpaDcDeflateCompressBound(NULL, huffman_type, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } hw_buffer_sz = qz_sess->sess_params.hw_buff_sz; /* cpaDcDeflateCompressBound only provides the maximum output size of deflate blocks, * it does not include gzip/gzip-ext header and footer size, so we need to update dest_sz * for header and footer size. */ /* Calculate how many gzip/gzip-ext headers and footers will be generated. */ chunk_cnt = src_sz / hw_buffer_sz + src_sz % hw_buffer_sz ? 1 : 0; dest_sz += chunk_cnt * (qzGzipHeaderSz() + stdGzipFooterSz()); return dest_sz; } static unsigned int qzLZ4SBound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; CpaStatus status = CPA_STATUS_SUCCESS; #if CPA_DC_API_VERSION_AT_LEAST(3, 1) status = cpaDcLZ4SCompressBound(NULL, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } #else (void)status; return 0; #endif return dest_sz; } static unsigned int qzLZ4Bound(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; QzSess_T *qz_sess = NULL; CpaStatus status = CPA_STATUS_SUCCESS; assert(sess); assert(sess->internal); #if CPA_DC_API_VERSION_AT_LEAST(3, 1) status = cpaDcLZ4CompressBound(NULL, src_sz, &dest_sz); if (status != CPA_STATUS_SUCCESS) { return 0; } #else (void)status; return 0; #endif /* cpaDcLZ4CompressBound only provides the maximum output size of lz4 blocks, * it does not include lz4 frames header and footer size, so we need to update dest_sz * for header and footer size. */ /* Calculate how many frames header and footer will be generated */ qz_sess = (QzSess_T *)sess->internal; chunk_cnt = src_sz / qz_sess->sess_params.hw_buff_sz + src_sz % qz_sess->sess_params.hw_buff_sz ? 1 : 0; dest_sz += chunk_cnt * outputHeaderSz(qz_sess->sess_params.data_fmt) + chunk_cnt * outputFooterSz(qz_sess->sess_params.data_fmt); return dest_sz; } unsigned int qzMaxCompressedLength(unsigned int src_sz, QzSession_T *sess) { unsigned int dest_sz = 0; unsigned int chunk_cnt = 0; QzSess_T *qz_sess = NULL; if (src_sz == 0) { return QZ_COMPRESSED_SZ_OF_EMPTY_FILE; } if (sess == NULL || sess->internal == NULL || sess->hw_session_stat != QZ_OK) { uint64_t in_sz = src_sz; uint64_t out_sz = 0; out_sz = QZ_CEIL_DIV(9 * in_sz, 8) + QZ_SKID_PAD_SZ; chunk_cnt = in_sz / QZ_HW_BUFF_SZ + in_sz % QZ_HW_BUFF_SZ ? 1 : 0; out_sz += chunk_cnt * (qzGzipHeaderSz() + stdGzipFooterSz()); if (out_sz & 0xffffffff00000000UL) return 0; dest_sz = (unsigned int)out_sz; return dest_sz; } qz_sess = (QzSess_T *)sess->internal; switch (qz_sess->sess_params.data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: dest_sz = qzDeflateBound(src_sz, sess); break; case LZ4_FH: dest_sz = qzLZ4Bound(src_sz, sess); break; case LZ4S_BK: dest_sz = qzLZ4SBound(src_sz, sess); break; default: dest_sz = 0; break; } QZ_DEBUG("src_sz is %u, dest_sz is %u\n", src_sz, dest_sz); return dest_sz; } int qzGetSoftwareComponentCount(unsigned int *num_elem) { QZ_ERROR("qatzip don't support qzGetSoftwareComponentCount API yet!\n"); return QZ_FAIL; } int qzGetSoftwareComponentVersionList(QzSoftwareVersionInfo_T *api_info, unsigned int *num_elem) { QZ_ERROR("qatzip don't support qzGetSoftwareComponentVersionList API yet!\n"); return QZ_FAIL; } QATzip-1.2.1/src/qatzip_counter.c000077500000000000000000000054121465165016500167030ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" extern processData_T g_process; void dumpCounters(QzInstance_T *inst) { int i; if (inst->mem_setup == 0) { QZ_PRINT("\tNot in use\n"); return; } for (i = 0; i < inst->dest_count; i++) { QZ_PRINT("\tbuffer %d\t ses %ld\t %ld %ld %ld %ld\n", i, inst->stream[i].seq, inst->stream[i].src1, inst->stream[i].src2, inst->stream[i].sink1, inst->stream[i].sink2); } } void dumpAllCounters(void) { int i; for (i = 0; i < g_process.num_instances; i++) { QZ_PRINT("Instance %d\n", i); dumpCounters(&g_process.qz_inst[i]); QZ_PRINT("\n"); } } QATzip-1.2.1/src/qatzip_gzip.c000077500000000000000000000175561465165016500162110ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" #pragma pack(push, 1) inline unsigned long qzGzipHeaderSz(void) { return sizeof(QzGzH_T); } inline unsigned long stdGzipHeaderSz(void) { return sizeof(StdGzH_T); } inline unsigned long qz4BHeaderSz(void) { return sizeof(Qz4BH_T); } inline unsigned long stdGzipFooterSz(void) { return sizeof(StdGzF_T); } void qzGzipHeaderExtraFieldGen(unsigned char *ptr, CpaDcRqResults *res) { QzExtraField_T *extra; extra = (QzExtraField_T *)ptr; extra->st1 = 'Q'; extra->st2 = 'Z'; extra->x2_len = (uint16_t)sizeof(extra->qz_e); extra->qz_e.src_sz = res->consumed; extra->qz_e.dest_sz = res->produced; } void qzGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); QzGzH_T *hdr; hdr = (QzGzH_T *)ptr; hdr->std_hdr.id1 = 0x1f; hdr->std_hdr.id2 = 0x8b; hdr->std_hdr.cm = QZ_DEFLATE; hdr->std_hdr.flag = 0x04; /*Fextra BIT SET*/ hdr->std_hdr.mtime[0] = (char)0; hdr->std_hdr.mtime[1] = (char)0; hdr->std_hdr.mtime[2] = (char)0; hdr->std_hdr.mtime[3] = (char)0; hdr->std_hdr.xfl = 0; hdr->std_hdr.os = 255; hdr->x_len = (uint16_t)sizeof(hdr->extra); qzGzipHeaderExtraFieldGen((unsigned char *)&hdr->extra, res); } void stdGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); StdGzH_T *hdr; hdr = (StdGzH_T *)ptr; hdr->id1 = 0x1f; hdr->id2 = 0x8b; hdr->cm = QZ_DEFLATE; hdr->flag = 0x00; hdr->mtime[0] = (char)0; hdr->mtime[1] = (char)0; hdr->mtime[2] = (char)0; hdr->mtime[3] = (char)0; hdr->xfl = 0; hdr->os = 255; } void qz4BHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { Qz4BH_T *hdr; hdr = (Qz4BH_T *)ptr; hdr->blk_size = res->produced; } int isQATDeflateProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { QzGzH_T *h = (QzGzH_T *)ptr; Qz4BH_T *h_4B; StdGzF_T *qzFooter = NULL; long buff_sz = (DEST_SZ(qz_sess->sess_params.hw_buff_sz) < *src_len ? DEST_SZ( (long)(qz_sess->sess_params.hw_buff_sz)) : *src_len); if (qz_sess->sess_params.data_fmt == DEFLATE_4B) { h_4B = (Qz4BH_T *)ptr; if (h_4B->blk_size > DEST_SZ(qz_sess->sess_params.hw_buff_sz)) { return 0; } return 1; } /*check if HW can process*/ if (h->std_hdr.id1 == 0x1f && \ h->std_hdr.id2 == 0x8b && \ h->std_hdr.cm == QZ_DEFLATE && \ h->std_hdr.flag == 0x00) { qzFooter = (StdGzF_T *)(findStdGzipFooter((const unsigned char *)h, buff_sz)); if ((unsigned char *)qzFooter - ptr - stdGzipHeaderSz() > DEST_SZ( (unsigned long)(qz_sess->sess_params.hw_buff_sz)) || qzFooter->i_size > qz_sess->sess_params.hw_buff_sz) { return 0; } qz_sess->sess_params.data_fmt = DEFLATE_GZIP; return 1; } /* Besides standard GZIP header, only Gzip header with QZ extension can be processed by QAT */ if (h->std_hdr.id1 != 0x1f || \ h->std_hdr.id2 != 0x8b || \ h->std_hdr.cm != QZ_DEFLATE) { /* There are two possibilities when h is not a gzip header: */ /* 1, wrong data */ /* 2, It is the 2nd, 3rd... part of the file with the standard gzip header. */ return -1; } return (h->extra.st1 == 'Q' && \ h->extra.st2 == 'Z'); } int qzGzipHeaderExt(const unsigned char *const ptr, QzGzH_T *hdr) { QzGzH_T *h; h = (QzGzH_T *)ptr; if (h->std_hdr.id1 != 0x1f || \ h->std_hdr.id2 != 0x8b || \ h->extra.st1 != 'Q' || \ h->extra.st2 != 'Z' || \ h->std_hdr.cm != QZ_DEFLATE || \ h->std_hdr.flag != 0x04 || \ (h->std_hdr.xfl != 0 && h->std_hdr.xfl != 2 && \ h->std_hdr.xfl != 4) || \ h->std_hdr.os != 255 || \ h->x_len != sizeof(h->extra) || \ h->extra.x2_len != sizeof(h->extra.qz_e)) { QZ_DEBUG("id1: %x, id2: %x, st1: %c, st2: %c, cm: %d, flag: %d," "xfl: %d, os: %d, x_len: %d, x2_len: %d\n", h->std_hdr.id1, h->std_hdr.id2, h->extra.st1, h->extra.st2, h->std_hdr.cm, h->std_hdr.flag, h->std_hdr.xfl, h->std_hdr.os, h->x_len, h->extra.x2_len); return QZ_FAIL; } QZ_MEMCPY(hdr, ptr, sizeof(*hdr), sizeof(*hdr)); return QZ_OK; } void qzGzipFooterGen(unsigned char *ptr, CpaDcRqResults *res) { assert(NULL != ptr); assert(NULL != res); StdGzF_T *ftr; ftr = (StdGzF_T *)ptr; ftr->crc32 = res->checksum; ftr->i_size = res->consumed; } void qzGzipFooterExt(const unsigned char *const ptr, StdGzF_T *ftr) { QZ_MEMCPY(ftr, ptr, sizeof(*ftr), sizeof(*ftr)); } unsigned char *findStdGzipFooter(const unsigned char *src_ptr, long src_avail_len) { StdGzH_T *gzHeader = NULL; unsigned int offset = stdGzipHeaderSz() + stdGzipFooterSz(); while (src_avail_len >= offset + stdGzipHeaderSz()) { gzHeader = (StdGzH_T *)(src_ptr + offset); if (gzHeader->id1 == 0x1f && \ gzHeader->id2 == 0x8b && \ gzHeader->cm == QZ_DEFLATE && \ gzHeader->flag == 0x00) { return (void *)((unsigned char *)gzHeader - stdGzipFooterSz()); } offset++; } return (void *)((unsigned char *)src_ptr + src_avail_len - stdGzipFooterSz()); } #pragma pack(pop) QATzip-1.2.1/src/qatzip_internal.h000077500000000000000000000466601465165016500170570ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _QATZIPP_H #define _QATZIPP_H #ifdef __cplusplus extern"C" { #endif #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include #include #include #include /** * define release version */ #define QATZIP_VERSION "1.2.0" #define SUCCESS 1 #define FAILURE 0 #define QZ_WAIT_SW_PENDING 10 #define NODE_0 0 #define NUM_BUFF (32) /** * For less than 8K hardware buffer size, it needs more in-flight buffers * to reach peak performance */ #define NUM_BUFF_8K (128) #define MAX_NUM_RETRY ((int)500) #define MAX_BUFFERS ((int)100) #define MAX_THREAD_TMR ((int)100) #define GET_LOWER_32BITS(v) ((v) & 0xFFFFFFFF) #define GET_LOWER_16BITS(v) ((v) & 0xFFFF) #define GET_LOWER_8BITS(v) ((v) & 0xFF) /*For Sync mode, request counts must less than NUM_BUFF. *If then the request can't get adequate unused buffer and will be hanged * */ #if QZ_REQ_THRESHOLD_MAXIMUM > NUM_BUFF #error QZ_REQ_THRESHOLD_MAXIMUM should not be larger than NUM_BUFF #endif #define QAT_MAX_DEVICES (32 * 32) #define STORED_BLK_MAX_LEN 65535 #define STORED_BLK_HDR_SZ 5 #define QZ_INIT_FAIL(rc) (QZ_OK != rc && \ QZ_DUPLICATE != rc) #define QZ_SETUP_SESSION_FAIL(rc) (QZ_PARAMS == rc || \ QZ_NOSW_NO_HW == rc || \ QZ_NOSW_LOW_MEM == rc) #define likely(x) __builtin_expect (!!(x), 1) #define unlikely(x) __builtin_expect (!!(x), 0) #define DEST_SZ(src_sz) (((9U * (src_sz)) / 8U) + 1024U) /* The minimal supported CAP_DC API version */ #ifndef CPA_DC_API_VERSION_AT_LEAST #define CPA_DC_API_VERSION_AT_LEAST(major, minor) \ (CPA_DC_API_VERSION_NUM_MAJOR > major || \ (CPA_DC_API_VERSION_NUM_MAJOR == major && \ CPA_DC_API_VERSION_NUM_MINOR >= minor)) #endif #define QZ_CEIL_DIV(x, y) (((x) + (y)-1) / (y)) /* macros for lz4 */ #define QZ_LZ4_MAGIC 0x184D2204U #define QZ_LZ4_MAGIC_SKIPPABLE 0x184D2A50U #define QZ_LZ4_VERSION 0x1 #define QZ_LZ4_BLK_INDEP 0x0 #define QZ_LZ4_BLK_CKS_FLAG 0x0 #define QZ_LZ4_DICT_ID_FLAG 0x0 #define QZ_LZ4_CNT_SIZE_FLAG 0x1 #define QZ_LZ4_CNT_CKS_FLAG 0x1 #define QZ_LZ4_ENDMARK 0x0 #define QZ_LZ4_MAX_BLK_SIZE 0x4 #define QZ_LZ4_MAGIC_SIZE 4 //lz4 magic number length #define QZ_LZ4_FD_SIZE 11 //lz4 frame descriptor length #define QZ_LZ4_HEADER_SIZE (QZ_LZ4_MAGIC_SIZE + \ QZ_LZ4_FD_SIZE) //lz4 frame header length #define QZ_LZ4_CHECKSUM_SIZE 4 //lz4 checksum length #define QZ_LZ4_ENDMARK_SIZE 4 //lz4 endmark length #define QZ_LZ4_FOOTER_SIZE (QZ_LZ4_CHECKSUM_SIZE + \ QZ_LZ4_ENDMARK_SIZE) //lz4 frame footer length #define QZ_LZ4_BLK_HEADER_SIZE 4 //lz4 block header length #define QZ_LZ4_STOREDBLOCK_FLAG 0x80000000U #define QZ_LZ4_STORED_HEADER_SIZE 4 #define DATA_FORMAT_DEFAULT DEFLATE_GZIP_EXT #define IS_DEFLATE_RAW(fmt) (DEFLATE_RAW == (fmt)) #define IS_DEFLATE(fmt) \ (DEFLATE_RAW == (fmt) || DEFLATE_GZIP == (fmt) || \ DEFLATE_GZIP_EXT == (fmt) || DEFLATE_4B == (fmt)) typedef struct QzCpaStream_S { signed long seq; signed long src1; signed long src2; signed long sink1; signed long sink2; CpaDcRqResults res; CpaStatus job_status; unsigned char *orig_src; unsigned char *orig_dest; int src_need_reset; int dest_need_reset; unsigned int checksum; unsigned int orgdatalen; CpaDcOpData opData; } QzCpaStream_T; typedef struct QzInstance_S { CpaInstanceInfo2 instance_info; CpaDcInstanceCapabilities instance_cap; CpaBufferList **intermediate_buffers; Cpa32U buff_meta_size; /* Tracks memory where the intermediate buffers reside. */ Cpa16U intermediate_cnt; CpaBufferList **src_buffers; CpaBufferList **dest_buffers; Cpa16U src_count; Cpa16U dest_count; QzCpaStream_T *stream; unsigned int lock; /*heartbeat represent device status, which will be changed by polling events thread*/ CpaStatus heartbeat; unsigned char mem_setup; unsigned char cpa_sess_setup; CpaStatus inst_start_status; unsigned int num_retries; CpaDcSessionHandle cpaSess; CpaDcSessionSetupData session_setup_data; } QzInstance_T; typedef struct QzInstanceList_S { QzInstance_T instance; CpaInstanceHandle dc_inst_handle; struct QzInstanceList_S *next; } QzInstanceList_T; typedef struct QzHardware_S { QzInstanceList_T devices[QAT_MAX_DEVICES]; unsigned int dev_num; unsigned int max_dev_id; } QzHardware_T; typedef struct ProccesData_S { char qz_init_status; unsigned char sw_backup; CpaInstanceHandle *dc_inst_handle; QzInstance_T *qz_inst; Cpa16U num_instances; atomic_char qat_available; /* this thread handler is for keep polling device fatal events.*/ pthread_t t_poll_heartbeat; } processData_T; typedef enum { InflateError = -1, InflateNull = 0, InflateInited, InflateOK, InflateEnd } InflateState_T; typedef enum { DeflateNull = 0, DeflateInited } DeflateState_T; // Include all support data format typedef enum DataFormatInternal_E { DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ DEFLATE_RAW, /**< Data is in raw deflate format */ LZ4_FH, /**< Data is in LZ4 format with frame headers */ LZ4S_BK, /**< Data is in LZ4s sequences with block header, it's only for post processed */ } DataFormatInternal_T; // Include all support session parameters typedef struct QzSessionParamsInternal_S { QzHuffmanHdr_T huffman_hdr; /**< Dynamic or Static Huffman headers */ QzDirection_T direction; /**< Compress or decompress */ DataFormatInternal_T data_fmt; /**< Deflate, deflate with GZip or deflate with GZip ext */ unsigned int comp_lvl; /**< Compression level 1 to 12 for QAT CPM2.0. */ /**< If the comp_algorithm is deflate, values > max will be set to max */ unsigned char comp_algorithm; /**< Compress/decompression algorithms */ unsigned int max_forks; /**< Maximum forks permitted in the current thread */ /**< 0 means no forking permitted */ unsigned char sw_backup; /**< bit field defining SW configuration (see QZ_SW_* definitions) */ unsigned int hw_buff_sz; /**< Default buffer size, must be a power of 2k */ /**< 4K,8K,16K,32K,64K,128K */ unsigned int strm_buff_sz; /**< Stream buffer size between [1K .. 2M - 5K] */ /**< Default strm_buf_sz equals to hw_buff_sz */ unsigned int input_sz_thrshold; /**< Default threshold of compression service's input size */ /**< for sw failover, if the size of input request is less */ /**< than the threshold, QATzip will route the request */ /**< to software */ unsigned int req_cnt_thrshold; /**< Set between 1 and NUM_BUFF, default NUM_BUFF */ /**< NUM_BUFF is defined in qatzip_internal.h */ unsigned int wait_cnt_thrshold; /**< When previous try failed, wait for specific number of calls */ /**< before retrying to open device. Default threshold is 8 */ qzLZ4SCallbackFn qzCallback; /**< post processing callback for zstd compression*/ void *qzCallback_external; /**< An opaque pointer provided by the user to be passed */ /**< into qzCallback during post processing*/ QzPollingMode_T polling_mode; /**< 0 means no busy polling, 1 means busy polling */ unsigned int is_sensitive_mode; /**< 0 means disable sensitive mode, 1 means enable sensitive mode*/ unsigned int lz4s_mini_match; /**< Set lz4s dictionary mini match, which would be 3 or 4 */ } QzSessionParamsInternal_T; typedef struct QzSess_S { int inst_hint; /*which instance we last used*/ QzSessionParamsInternal_T sess_params; CpaDcSessionSetupData session_setup_data; Cpa32U session_size; Cpa32U ctx_size; CpaStatus sess_status; int submitted; int processed; int last_submitted; int last_processed; int stop_submitting; signed long seq; signed long seq_in; pthread_t c_th_i; pthread_t c_th_o; unsigned char *src; unsigned int *src_sz; unsigned int *dest_sz; unsigned char *next_dest; int force_sw; InflateState_T inflate_stat; void *strm; z_stream *inflate_strm; unsigned long qz_in_len; unsigned long qz_out_len; unsigned long *crc32; unsigned int last; unsigned int single_thread; unsigned int polling_idx; z_stream *deflate_strm; DeflateState_T deflate_stat; LZ4F_dctx *dctx; } QzSess_T; typedef struct QzStreamBuf_S { unsigned int buf_len; unsigned char *in_buf; unsigned char *out_buf; unsigned int out_offset; unsigned int in_offset; unsigned int flush_more; } QzStreamBuf_T; typedef struct ThreadData_S { pid_t ppid; pid_t pid; struct timeval timer[MAX_THREAD_TMR]; } ThreadData_T; typedef struct QzExtraHeader_S { uint32_t src_sz; uint32_t dest_sz; } QzExtraHeader_T; typedef struct QzExtraField_S { unsigned char st1; unsigned char st2; uint16_t x2_len; QzExtraHeader_T qz_e; } QzExtraField_T; typedef struct StdGzH_S { unsigned char id1; unsigned char id2; unsigned char cm; unsigned char flag; unsigned char mtime[4]; unsigned char xfl; unsigned char os; } StdGzH_T; typedef struct QzGzH_S { StdGzH_T std_hdr; uint16_t x_len; QzExtraField_T extra; } QzGzH_T; typedef struct Qz4BH_S { uint32_t blk_size; } Qz4BH_T; typedef struct StdGzF_S { uint32_t crc32; uint32_t i_size; } StdGzF_T; typedef struct QzMem_S { int flag; unsigned char *addr; int sz; int numa; } QzMem_T; #pragma pack(push, 1) /* lz4 frame header */ typedef struct QzLZ4H_S { uint32_t magic; /* LZ4 magic number */ uint8_t flag_desc; uint8_t block_desc; uint64_t cnt_size; uint8_t hdr_cksum; /* header checksum */ } QzLZ4H_T; /* lz4 frame footer */ typedef struct QzLZ4F_S { uint32_t end_mark; /* LZ4 end mark */ uint32_t cnt_cksum; /* content checksum */ } QzLZ4F_T; #pragma pack(pop) void dumpAllCounters(void); int qzSetupHW(QzSession_T *sess, int i); unsigned long qzGzipHeaderSz(void); unsigned long qz4BHeaderSz(void); unsigned long stdGzipHeaderSz(void); unsigned long stdGzipFooterSz(void); unsigned long outputHeaderSz(DataFormatInternal_T data_fmt); unsigned long outputFooterSz(DataFormatInternal_T data_fmt); void qzGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res); void qz4BHeaderGen(unsigned char *ptr, CpaDcRqResults *res); void stdGzipHeaderGen(unsigned char *ptr, CpaDcRqResults *res); int qzGzipHeaderExt(const unsigned char *const ptr, QzGzH_T *hdr); void outputHeaderGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt); void qzGzipFooterGen(unsigned char *ptr, CpaDcRqResults *res); void outputFooterGen(QzSess_T *qz_sess, CpaDcRqResults *res, DataFormatInternal_T data_fmt); void qzGzipFooterExt(const unsigned char *const ptr, StdGzF_T *ftr); int isQATProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); int qzSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last); int qzSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *uncompressed_buf_len, unsigned char *dest, unsigned int *compressed_buffer_len); int qzSWDecompressMulti(QzSession_T *sess, const unsigned char *src, unsigned int *uncompressed_buf_len, unsigned char *dest, unsigned int *compressed_buffer_len); unsigned char getSwBackup(QzSession_T *sess); #ifdef ADF_PCI_API extern CpaStatus icp_adf_get_numDevices(Cpa32U *); #endif int initStream(QzSession_T *sess, QzStream_T *strm); void *qzMemSet(void *ptr, unsigned char filler, unsigned int count); unsigned char *findStdGzipFooter(const unsigned char *src_ptr, long src_avail_len); void removeSession(int i); void cleanUpInstMem(int i); void qzMemDestory(void); void streamBufferCleanup(); //lz4 functions unsigned long qzLZ4HeaderSz(void); unsigned long qzLZ4FooterSz(void); void qzLZ4HeaderGen(unsigned char *ptr, CpaDcRqResults *res); void qzLZ4FooterGen(unsigned char *ptr, CpaDcRqResults *res); unsigned char *findLZ4Footer(const unsigned char *src_ptr, long src_avail_len); int qzVerifyLZ4FrameHeader(const unsigned char *const ptr, uint32_t len); int isQATLZ4Processable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); int isQATDeflateProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess); unsigned long qzLZ4SBlockHeaderSz(void); void qzLZ4SBlockHeaderGen(unsigned char *ptr, CpaDcRqResults *res); int qzSetupSessionInternal(QzSession_T *sess); int qzCheckParams(QzSessionParams_T *params); int qzCheckParamsDeflate(QzSessionParamsDeflate_T *params); int qzCheckParamsLZ4(QzSessionParamsLZ4_T *params); int qzCheckParamsLZ4S(QzSessionParamsLZ4S_T *params); void qzGetParams(QzSessionParamsInternal_T *internal_params, QzSessionParams_T *params); void qzGetParamsDeflate(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflate_T *params); void qzGetParamsLZ4(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4_T *params); void qzGetParamsLZ4S(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4S_T *params); void qzSetParamsLZ4S(QzSessionParamsLZ4S_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParamsLZ4(QzSessionParamsLZ4_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParamsDeflate(QzSessionParamsDeflate_T *params, QzSessionParamsInternal_T *internal_params); void qzSetParams(QzSessionParams_T *params, QzSessionParamsInternal_T *internal_params); /* SW Fallback for HW request offload failed or HW respond in Error status */ int compInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned int src_send_sz); int compOutSWFallback(int i, int j, QzSession_T *sess, long *dest_avail_len); int decompInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len); int decompOutSWFallback(int i, int j, QzSession_T *sess, unsigned int *dest_avail_len); /* Stream pData may need reset, which is caused by driver API params limitation, when setup buffer, may feed pinned pointer or common pointer to pBuffer. */ void RestoreDestCpastreamBuffer(int i, int j); void RestoreSrcCpastreamBuffer(int i, int j); void ResetCpastreamSink(int i, int j); /* compression stream/src/dest buffer setup, and cleanup */ void compBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned int src_remaining, unsigned int hw_buff_sz, unsigned int src_send_sz); void compInBufferCleanUp(int i, int j); void compOutSrcBufferCleanUp(int i, int j); void compOutErrorDestBufferCleanUp(int i, int j); void compOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, unsigned int dest_receive_sz); /* docompressOut successful respond process, or error respond process */ void compOutProcessedRespond(int i, int j, QzSess_T *qz_sess); void compOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess); int compOutCheckDestLen(int i, int j, QzSession_T *sess, long *dest_avail_len, long dest_receive_sz); int checkHeader(QzSess_T *qz_sess, unsigned char *src, unsigned int src_avail_len, unsigned int dest_avail_len, QzGzH_T *hdr); /* decompression stream/src/dest buffer setup, and cleanup */ void swapDataBuffer(unsigned long i, int j); void decompBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int src_avail_len, QzGzH_T *hdr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len); void decompInBufferCleanUp(int i, int j); void decompOutSrcBufferCleanUp(int i, int j); void decompOutErrorDestBufferCleanUp(int i, int j); void decompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, unsigned int dest_avail_len); /* dodecompressOut successful respond process, or error respond process */ void decompOutProcessedRespond(int i, int j, QzSess_T *qz_sess); void decompOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess); int decompOutCheckSum(int i, int j, QzSession_T *sess, CpaDcRqResults *resl); #endif //_QATZIPP_H QATzip-1.2.1/src/qatzip_lz4.c000066400000000000000000000164651465165016500157440ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #define XXH_NAMESPACE QATZIP_ #include "xxhash.h" #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" inline unsigned long qzLZ4HeaderSz() { return QZ_LZ4_HEADER_SIZE; } inline unsigned long qzLZ4FooterSz() { return QZ_LZ4_FOOTER_SIZE; } int qzVerifyLZ4FrameHeader(const unsigned char *const ptr, uint32_t len) { QzLZ4H_T *hdr = NULL; assert(ptr != NULL); assert(len >= QZ_LZ4_HEADER_SIZE); QZ_DEBUG("qzVerifyLZ4FrameHeader\n"); hdr = (QzLZ4H_T *)ptr; //Skippable frames if ((hdr->magic & 0xFFFFFFF0U) == QZ_LZ4_MAGIC_SKIPPABLE) { /*for skippalbe frames, fallback to software decompression */ QZ_DEBUG("qzVerifyLZ4FrameHeader: skip frames, switch to software.\n"); return QZ_FORCE_SW; } //Unknown magic number if (hdr->magic != QZ_LZ4_MAGIC) { QZ_DEBUG("qzVerifyLZ4FrameHeader: unknown lz4 frame magic number %x.\n", hdr->magic); return QZ_FAIL; } //No support for unknown lz4 version if ((hdr->flag_desc >> 6 & 0x3) != QZ_LZ4_VERSION) { QZ_DEBUG("qzVerifyLZ4FrameHeader: unknown lz4 frame version number.\n"); return QZ_FAIL; } if ((hdr->flag_desc & 0x1) != QZ_LZ4_DICT_ID_FLAG || (hdr->flag_desc >> 4 & 0x1) != QZ_LZ4_BLK_CKS_FLAG || (hdr->flag_desc >> 2 & 0x1) != QZ_LZ4_CNT_CKS_FLAG || (hdr->flag_desc >> 3 & 0x1) != QZ_LZ4_CNT_SIZE_FLAG) { QZ_DEBUG("qzVerifyLZ4FrameHeader: unsupported lz4 frame header \ switch to software.\n"); return QZ_FORCE_SW; } return QZ_OK; } void qzLZ4HeaderGen(unsigned char *ptr, CpaDcRqResults *res) { QzLZ4H_T *hdr = NULL; unsigned char *hc_start = NULL; assert(ptr != NULL); assert(res != NULL); hdr = (QzLZ4H_T *)ptr; hdr->magic = QZ_LZ4_MAGIC; //flag descriptor hdr->flag_desc = (unsigned char)(((QZ_LZ4_VERSION & 0x03) << 6) + ((QZ_LZ4_BLK_INDEP & 0x01) << 5) + ((QZ_LZ4_BLK_CKS_FLAG & 0x01) << 4) + ((QZ_LZ4_CNT_SIZE_FLAG & 0x01) << 3) + ((QZ_LZ4_CNT_CKS_FLAG & 0x01) << 2) + (QZ_LZ4_DICT_ID_FLAG & 0x01)); //block descriptor hdr->block_desc = (unsigned char)((QZ_LZ4_MAX_BLK_SIZE & 0x07) << 4); //content size hdr->cnt_size = res->consumed; //header checksum hc_start = ptr + QZ_LZ4_MAGIC_SIZE; hdr->hdr_cksum = (unsigned char)((XXH32(hc_start, QZ_LZ4_FD_SIZE - 1, 0) >> 8) & 0xff); } void qzLZ4FooterGen(unsigned char *ptr, CpaDcRqResults *res) { QzLZ4F_T *footer = NULL; assert(ptr != NULL); footer = (QzLZ4F_T *)ptr; footer->end_mark = QZ_LZ4_ENDMARK; footer->cnt_cksum = res->checksum; } unsigned char *findLZ4Footer(const unsigned char *src_ptr, long src_avail_len) { const unsigned char *lz4_footer = NULL; unsigned int block_sz = 0; unsigned int frame_sz = 0; assert(src_ptr != NULL); //the src_avail_len should be equal or greater than minimum of frame size if (src_avail_len < (QZ_LZ4_HEADER_SIZE + QZ_LZ4_BLK_HEADER_SIZE + QZ_LZ4_FOOTER_SIZE)) { return NULL; } block_sz = (*(unsigned int *)(src_ptr + QZ_LZ4_HEADER_SIZE)) & 0x7fffffff; frame_sz = block_sz + QZ_LZ4_HEADER_SIZE + QZ_LZ4_BLK_HEADER_SIZE + QZ_LZ4_FOOTER_SIZE; while (src_avail_len >= frame_sz) { lz4_footer = (src_ptr + frame_sz - QZ_LZ4_FOOTER_SIZE); if (*(unsigned int *)lz4_footer == (unsigned int)0x0) { return (unsigned char *)lz4_footer; } block_sz = (*(unsigned int *)lz4_footer) & 0x7fffffff; frame_sz += block_sz + QZ_LZ4_BLK_HEADER_SIZE; } return NULL; } int isQATLZ4Processable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { QzLZ4H_T *hdr = (QzLZ4H_T *)ptr; QzLZ4F_T *footer = NULL; if (*src_len < QZ_LZ4_HEADER_SIZE) { return 0; } //Skippable frames if ((hdr->magic & 0xFFFFFFF0U) == QZ_LZ4_MAGIC_SKIPPABLE) { /*for skippalbe frames, fallback to software decompression */ return 0; } //Unknown magic number if (hdr->magic != QZ_LZ4_MAGIC) { return 0; } //No support for unknown lz4 version if ((hdr->flag_desc >> 6 & 0x3) != QZ_LZ4_VERSION) { return 0; } if ((hdr->flag_desc & 0x1) != QZ_LZ4_DICT_ID_FLAG || (hdr->flag_desc >> 4 & 0x1) != QZ_LZ4_BLK_CKS_FLAG || (hdr->flag_desc >> 2 & 0x1) != QZ_LZ4_CNT_CKS_FLAG || (hdr->flag_desc >> 3 & 0x1) != QZ_LZ4_CNT_SIZE_FLAG) { return 0; } footer = (QzLZ4F_T *)findLZ4Footer(ptr, *src_len); if (footer == NULL || ((unsigned int)((unsigned char *)footer - ptr - QZ_LZ4_HEADER_SIZE)) > DEST_SZ( qz_sess->sess_params.hw_buff_sz)) { return 0; } return 1; } inline unsigned long qzLZ4SBlockHeaderSz(void) { return QZ_LZ4_BLK_HEADER_SIZE; } void qzLZ4SBlockHeaderGen(unsigned char *ptr, CpaDcRqResults *res) { assert(ptr != NULL); assert(res != NULL); //block header contains block size unsigned int *blk_size = (unsigned int *)(ptr); *blk_size = (unsigned int)res->produced; } QATzip-1.2.1/src/qatzip_mem.c000077500000000000000000000140401465165016500157770ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #include #else #include #include #include #endif #include "qatzip.h" #include "qz_utils.h" #include "qatzip_internal.h" #include "qatzip_page_table.h" #define __STDC_WANT_LIB_EXT1__ 1 #include static QzPageTable_T g_qz_page_table = {{{0}}}; static pthread_mutex_t g_qz_table_lock = PTHREAD_MUTEX_INITIALIZER; static atomic_int g_table_init = 0; static __thread unsigned char *g_a; extern processData_T g_process; void *doUserMemset(void *const ptr, unsigned char filler, const unsigned int count) { unsigned int lim = 0; volatile unsigned char *volatile dstPtr = ptr; while (lim < count) { dstPtr[lim++] = filler; } return (void *)dstPtr; } /* * * Fills a memory zone with a given constant byte, * * returns pointer to the memory zone. * */ void *qzMemSet(void *ptr, unsigned char filler, unsigned int count) { if (ptr == NULL) { QZ_ERROR("Invalid input memory pointer!"); return NULL; } #ifdef __STDC_LIB_EXT1__ errno_t result = memset_s( ptr, sizeof(ptr), filler, count) /* Supported on C11 standard */ if (result != 0) { QZ_ERROR("memset failed by the reason of %d", result); } return ptr; #else return doUserMemset( ptr, filler, count); /* Platform-independent secure memset */ #endif /* __STDC_LIB_EXT1__ */ } int qzMemFindAddr(unsigned char *a) { int rc = 0; unsigned long al, b; al = (unsigned long)a; b = (al & PAGE_MASK); rc = (PINNED == loadAddr(&g_qz_page_table, (void *)b)) ? PINNED_MEM : COMMON_MEM; if (0 != rc) { QZ_DEBUG("Find 0x%lx in page table\n", b); } return rc; } static void qzMemUnRegAddr(unsigned char *a) { return; } static int qzMemRegAddr(unsigned char *a, size_t sz) { int rc; unsigned long al, b; if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return -1; } /*addr already registered*/ if ((1 == qzMemFindAddr(a)) && (1 == qzMemFindAddr(a + sz - 1))) { pthread_mutex_unlock(&g_qz_table_lock); return 0; } al = (unsigned long)a; b = (al & PAGE_MASK); sz += (al - b); QZ_DEBUG("4 KB page is 0x%lx\n", b); QZ_DEBUG("Inserting 0x%lx size %lx to page table\n", b, sz); rc = storeMmapRange(&g_qz_page_table, (void *)b, PINNED, sz); pthread_mutex_unlock(&g_qz_table_lock); return rc; } void qzMemDestory(void) { if (0 == g_table_init) { return; } if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return; } freePageTable(&g_qz_page_table); g_table_init = 0; if (0 != pthread_mutex_unlock(&g_qz_table_lock)) { return; } } void *qzMalloc(size_t sz, int numa, int pinned) { int status; QzSession_T temp_sess; qzMemSet(&temp_sess, 0, sizeof(QzSession_T)); if (0 == g_table_init) { if (0 != pthread_mutex_lock(&g_qz_table_lock)) { return NULL; } if (0 == g_table_init) { qzMemSet(&g_qz_page_table, 0, sizeof(QzPageTable_T)); g_table_init = 1; } if (0 != pthread_mutex_unlock(&g_qz_table_lock)) { return NULL; } } if (1 == pinned && QZ_NONE == g_process.qz_init_status) { status = qzInit(&temp_sess, 1); if (QZ_INIT_FAIL(status)) { QZ_ERROR("QAT init failed with error: %d\n", status); return NULL; } } g_a = qaeMemAllocNUMA(sz, numa, 64); if (NULL == g_a) { if (0 == pinned) { QZ_DEBUG("regular malloc\n"); g_a = malloc(sz); } } else { if (0 != qzMemRegAddr(g_a, sz)) { qaeMemFreeNUMA((void **)&g_a); return NULL; } } return g_a; } void qzFree(void *m) { if (NULL == m) { return; } QZ_DEBUG("\t\tfreeing 0x%lx\n", (unsigned long)m); if (1 == qzMemFindAddr(m)) { qaeMemFreeNUMA((void **)&m); qzMemUnRegAddr(m); } else { free(m); } m = NULL; } QATzip-1.2.1/src/qatzip_page_table.h000066400000000000000000000122251465165016500173110ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _QATZIP_PAGE_TABLE_H #define _QATZIP_PAGE_TABLE_H #include #include #include #define PAGE_SHIFT (12) #define PAGE_SIZE (0x1000) #define PAGE_MASK (~(PAGE_SIZE - 1)) #define LEVEL_SIZE (PAGE_SIZE / sizeof(uint64_t)) #define PINNED (-1) typedef struct __attribute__((__packed__)) { uint32_t offset : 12; uint32_t idxl0 : 9; uint32_t idxl1 : 9; uint32_t idxl2 : 9; uint32_t idxl3 : 9; } QzPageEntry_T; typedef union { uint64_t addr; QzPageEntry_T pg_entry; } QzPageIndex_T; typedef struct QzPageTable_T { union { uint64_t mt; struct QzPageTable_T *pt; } next[LEVEL_SIZE]; } QzPageTable_T; static inline void *nextLevel(QzPageTable_T *volatile *ptr) { QzPageTable_T *old_ptr = *ptr; QzPageTable_T *new_ptr; if (NULL != old_ptr) return old_ptr; new_ptr = mmap(NULL, sizeof(QzPageTable_T), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if ((void *) - 1 == new_ptr) { QZ_ERROR("nextLevel: mmap error\n"); return NULL; } if (!__sync_bool_compare_and_swap(ptr, NULL, new_ptr)) munmap(new_ptr, sizeof(QzPageTable_T)); return *ptr; } static inline void freePageLevel(QzPageTable_T *const level, const size_t iter) { size_t i = 0; if (0 == iter) return; for (i = 0; i < LEVEL_SIZE; ++i) { QzPageTable_T *pt = level->next[i].pt; if (NULL != pt) { freePageLevel(pt, iter - 1); munmap(pt, sizeof(QzPageTable_T)); } } } static inline void freePageTable(QzPageTable_T *const table) { /* There are 1+3 levels in 48-bit page table for 4KB pages. */ freePageLevel(table, 3); /* Reset global root table. */ qzMemSet(table, 0, sizeof(QzPageTable_T)); } static inline int storeAddr(QzPageTable_T *level, uintptr_t virt, uint64_t type) { QzPageIndex_T id; id.addr = virt; level = nextLevel(&level->next[id.pg_entry.idxl3].pt); if (NULL == level) { return -1; } level = nextLevel(&level->next[id.pg_entry.idxl2].pt); if (NULL == level) { return -1; } level = nextLevel(&level->next[id.pg_entry.idxl1].pt); if (NULL == level) { return -1; } level->next[id.pg_entry.idxl0].mt = type; return 0; } static inline int storeMmapRange(QzPageTable_T *p_level, void *p_virt, uint64_t type, size_t p_size) { size_t offset; size_t page_size = PAGE_SIZE; const uintptr_t virt = (uintptr_t)p_virt; for (offset = 0; offset < p_size; offset += page_size) { if (0 != storeAddr(p_level, virt + offset, type)) { return -1; } } return 0; } static inline uint64_t loadAddr(QzPageTable_T *level, void *virt) { QzPageIndex_T id; id.addr = (uintptr_t)virt; level = level->next[id.pg_entry.idxl3].pt; if (NULL == level) return 0; level = level->next[id.pg_entry.idxl2].pt; if (NULL == level) return 0; level = level->next[id.pg_entry.idxl1].pt; if (NULL == level) return 0; return level->next[id.pg_entry.idxl0].mt; } #endif QATzip-1.2.1/src/qatzip_stream.c000066400000000000000000000562601465165016500165230ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifdef HAVE_QAT_HEADERS #include #include #include #include #include #else #include #include #include #include #include #endif #include #include #include #include #include #define STREAM_BUFF_LIST_SZ 8 typedef struct StreamBuffNode_S { void *buffer; size_t size; int pinned; struct StreamBuffNode_S *next; struct StreamBuffNode_S *prev; } StreamBuffNode_T; typedef struct StreamBuffNodeList_S { StreamBuffNode_T *head; StreamBuffNode_T *tail; unsigned int size; pthread_mutex_t mutex; } StreamBuffNodeList_T; StreamBuffNodeList_T g_strm_buff_list_free = { .head = NULL, .tail = NULL, .size = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; StreamBuffNodeList_T g_strm_buff_list_used = { .head = NULL, .tail = NULL, .size = 0, .mutex = PTHREAD_MUTEX_INITIALIZER }; static inline int addNodeToList(StreamBuffNode_T *node, StreamBuffNodeList_T *buff_list) { buff_list->size += 1; node->next = NULL; if (NULL == buff_list->tail) { buff_list->head = node; node->prev = NULL; } else { node->prev = buff_list->tail; buff_list->tail->next = node; } buff_list->tail = node; return SUCCESS; } static inline int removeNodeFromList(StreamBuffNode_T *node, StreamBuffNodeList_T *buff_list) { buff_list->size -= 1; if (NULL != node->prev) { node->prev->next = node->next; if (NULL != node->next) { node->next->prev = node->prev; } else { buff_list->tail = node->prev; } } else { if (NULL != node->next) { node->next->prev = NULL; buff_list->head = node->next; } else { buff_list->head = NULL; buff_list->tail = NULL; } } return SUCCESS; } void streamBufferCleanup() { StreamBuffNode_T *node; StreamBuffNode_T *next; if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_used.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); return; } node = g_strm_buff_list_used.head; while (node != NULL) { next = node->next; removeNodeFromList(node, &g_strm_buff_list_used); qzFree(node->buffer); free(node); node = next; } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_used.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); return; } node = g_strm_buff_list_free.head; while (node != NULL) { next = node->next; removeNodeFromList(node, &g_strm_buff_list_free); qzFree(node->buffer); free(node); node = next; } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } } static void *getNodeBuffFromFreeList(size_t sz, int pinned) { pthread_mutex_lock(&g_strm_buff_list_free.mutex); pthread_mutex_lock(&g_strm_buff_list_used.mutex); void *retval = NULL; StreamBuffNode_T *node; for (node = g_strm_buff_list_free.head; node != NULL; node = node->next) { if (pinned == node->pinned && sz <= node->size) { if (!removeNodeFromList(node, &g_strm_buff_list_free)) { retval = NULL; goto done; } if (!addNodeToList(node, &g_strm_buff_list_used)) { retval = NULL; goto done; } retval = node->buffer; goto done; } } done: pthread_mutex_unlock(&g_strm_buff_list_used.mutex); pthread_mutex_unlock(&g_strm_buff_list_free.mutex); return retval; } static void allocSomeNodesForFreeList(size_t sz, int numa, int pinned) { StreamBuffNode_T *node; int i; for (i = 0; i < STREAM_BUFF_LIST_SZ; ++i) { node = malloc(sizeof(StreamBuffNode_T)); if (NULL == node) { break; } node->buffer = qzMalloc(sz, numa, pinned); if (NULL == node->buffer) { free(node); break; } node->pinned = pinned; node->size = sz; if (unlikely(0 != pthread_mutex_lock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to get Mutex Lock.\n"); free(node); return; } if (!addNodeToList(node, &g_strm_buff_list_free)) { free(node); if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); return; } } if (unlikely(0 != pthread_mutex_unlock(&g_strm_buff_list_free.mutex))) { QZ_ERROR("Failed to release Mutex Lock.\n"); free(node); return; } } } static void *streamBufferAlloc(size_t sz, int numa, int pinned) { StreamBuffNode_T *node = getNodeBuffFromFreeList(sz, pinned); if (NULL == node) { //try to add some nodes to free list allocSomeNodesForFreeList(sz, numa, pinned); node = getNodeBuffFromFreeList(sz, pinned); } return node; } static void streamBufferFree(void *addr) { StreamBuffNode_T *node; pthread_mutex_lock(&g_strm_buff_list_free.mutex); pthread_mutex_lock(&g_strm_buff_list_used.mutex); for (node = g_strm_buff_list_used.head; node != NULL; node = node->next) { if (addr == node->buffer) { if (removeNodeFromList(node, &g_strm_buff_list_used) == FAILURE) { QZ_ERROR("Fail to remove Node for streamBufferFree"); goto done; } if (STREAM_BUFF_LIST_SZ <= g_strm_buff_list_free.size) { qzFree(node->buffer); free(node); } else { addNodeToList(node, &g_strm_buff_list_free); } addr = NULL; goto done; } } done: pthread_mutex_unlock(&g_strm_buff_list_used.mutex); pthread_mutex_unlock(&g_strm_buff_list_free.mutex); } int initStream(QzSession_T *sess, QzStream_T *strm) { int rc = QZ_FAIL; QzSess_T *qz_sess = NULL; QzStreamBuf_T *stream_buf = NULL; if (NULL != strm->opaque) { return QZ_DUPLICATE; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { return QZ_FAIL; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { rc = qzSetupSessionDeflate(sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { return QZ_FAIL; } } qz_sess = (QzSess_T *)(sess->internal); qz_sess->strm = strm; strm->opaque = malloc(sizeof(QzStreamBuf_T)); stream_buf = (QzStreamBuf_T *) strm->opaque; if (NULL == stream_buf) { QZ_ERROR("Fail to allocate memory for QzStreamBuf"); return QZ_FAIL; } stream_buf->out_offset = 0; stream_buf->in_offset = 0; stream_buf->flush_more = 0; stream_buf->buf_len = qz_sess->sess_params.strm_buff_sz; stream_buf->in_buf = streamBufferAlloc(stream_buf->buf_len, NODE_0, PINNED_MEM); stream_buf->out_buf = streamBufferAlloc(stream_buf->buf_len, NODE_0, PINNED_MEM); if (NULL == stream_buf->in_buf) { QZ_DEBUG("stream_buf->in_buf : PINNED_MEM failed, try COMMON_MEM\n"); stream_buf->in_buf = streamBufferAlloc(stream_buf->buf_len, NODE_0, COMMON_MEM); } if (NULL == stream_buf->out_buf) { QZ_DEBUG("stream_buf->out_buf : PINNED_MEM failed, try COMMON_MEM\n"); stream_buf->out_buf = streamBufferAlloc(stream_buf->buf_len, NODE_0, COMMON_MEM); } if (NULL == stream_buf->in_buf || NULL == stream_buf->out_buf) { goto clear; } QZ_DEBUG("Allocate stream buf %u\n", stream_buf->buf_len); strm->pending_in = 0; strm->pending_out = 0; strm->crc_32 = 0; return QZ_OK; clear: if (NULL == stream_buf->in_buf) { QZ_ERROR("Fail to allocate memory for in_buf of QzStreamBuf"); } else { qzFree(stream_buf->in_buf); } if (NULL == stream_buf->out_buf) { QZ_ERROR("Fail to allocate memory for out_buf of QzStreamBuf"); } else { qzFree(stream_buf->out_buf); } free(stream_buf); stream_buf = NULL; strm->opaque = NULL; return QZ_FAIL; } static unsigned int copyStreamInput(QzStream_T *strm, unsigned char *in) { unsigned int cpy_cnt = 0; unsigned int avail_in = 0; QzStreamBuf_T *stream_buf = strm->opaque; avail_in = stream_buf->buf_len - strm->pending_in; cpy_cnt = (strm->in_sz > avail_in) ? avail_in : strm->in_sz; QZ_MEMCPY(stream_buf->in_buf + strm->pending_in, in, cpy_cnt, strm->in_sz); QZ_DEBUG("Copy to input from %p, to %p, count %u\n", in, stream_buf->in_buf + strm->pending_in, cpy_cnt); strm->pending_in += cpy_cnt; strm->in_sz -= cpy_cnt; return cpy_cnt; } static unsigned int copyStreamOutput(QzStream_T *strm, unsigned char *out) { unsigned int cpy_cnt = 0; unsigned int avail_out = 0; QzStreamBuf_T *stream_buf = strm->opaque; avail_out = strm->out_sz; cpy_cnt = (strm->pending_out > avail_out) ? avail_out : strm->pending_out; QZ_MEMCPY(out, stream_buf->out_buf + stream_buf->out_offset, avail_out, cpy_cnt); QZ_DEBUG("copy %u to user output\n", cpy_cnt); strm->out_sz -= cpy_cnt; strm->pending_out -= cpy_cnt; stream_buf->out_offset += cpy_cnt; if (strm->pending_out == 0) { stream_buf->out_offset = 0; } return cpy_cnt; } int qzCompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last) { int rc = QZ_FAIL; unsigned long *strm_crc = NULL; unsigned int input_len = 0; unsigned int output_len = 0; unsigned int copied_output = 0; unsigned int copied_input = 0; unsigned int copied_input_last = 0; unsigned int copy_more = 1; unsigned int inbuf_offset = 0; unsigned int consumed = 0; unsigned int produced = 0; unsigned int strm_last = 0; QzStreamBuf_T *stream_buf = NULL; QzSess_T *qz_sess = NULL; DataFormatInternal_T data_fmt = DEFLATE_GZIP_EXT; if (NULL == sess || \ NULL == strm || \ (last != 0 && last != 1)) { rc = QZ_PARAMS; if (NULL != strm) { strm->in_sz = 0; strm->out_sz = 0; } goto end; } if (NULL == strm->out) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->in && \ strm->in_sz > 0) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->opaque) { rc = initStream(sess, strm); if (QZ_OK != rc) { goto done; } } switch (strm->crc_type) { case QZ_CRC32: case QZ_ADLER: default: strm_crc = (unsigned long *)&strm->crc_32; break; } /*check if init called*/ rc = qzInit(sess, getSwBackup(sess)); if (QZ_INIT_FAIL(rc)) { return QZ_FAIL; } /*check if setupSession called*/ if (NULL == sess->internal || QZ_NONE == sess->hw_session_stat) { rc = qzSetupSessionDeflate(sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { strm->in_sz = 0; strm->out_sz = 0; return QZ_FAIL; } } qz_sess = (QzSess_T *)(sess->internal); data_fmt = qz_sess->sess_params.data_fmt; if (data_fmt != DEFLATE_RAW && data_fmt != DEFLATE_GZIP_EXT) { QZ_ERROR("Invalid data format: %d\n", data_fmt); strm->in_sz = 0; strm->out_sz = 0; return QZ_PARAMS; } stream_buf = (QzStreamBuf_T *) strm->opaque; while (strm->pending_out > 0) { copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; if (0 == copied_output || (0 == strm->pending_out && 0 == strm->pending_in && 0 == strm->in_sz)) { rc = QZ_OK; /* When pending_out and pending_in are all greater than zero, we * set the flush_more flag to indicate that we should not copy more * input and should do the process(compression or decompression) */ if (strm->pending_in > 0) { stream_buf->flush_more = 1; } goto done; } } while (0 == strm->pending_out) { if (copy_more == 1 && stream_buf->flush_more != 1) { copied_input_last = copied_input; // Note, strm->in == NULL and strm->in_sz == 0, will not cause // copyStreamInput failed, but it's Dangerous behavior. if (NULL != strm->in) { copied_input += copyStreamInput(strm, strm->in + consumed); } if (strm->pending_in < stream_buf->buf_len && last != 1) { rc = QZ_OK; goto done; } else { copy_more = 0; } } input_len = strm->pending_in; output_len = stream_buf->buf_len; if (stream_buf->flush_more == 1) { inbuf_offset = stream_buf->in_offset; stream_buf->flush_more = 0; } strm_last = (0 == strm->in_sz && last) ? 1 : 0; QZ_DEBUG("Before Call qzCompressCrc input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); rc = qzCompressCrc(sess, stream_buf->in_buf + inbuf_offset, &input_len, stream_buf->out_buf, &output_len, strm_last, strm_crc); strm->pending_in -= input_len; strm->pending_out = output_len; copied_output = copyStreamOutput(strm, strm->out + produced); consumed = copied_input; produced += copied_output; inbuf_offset += input_len; stream_buf->in_offset = inbuf_offset; QZ_DEBUG("After Call qzCompressCrc input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); if (QZ_BUF_ERROR == rc) { if (0 == input_len) { QZ_ERROR("ERROR in copy stream output, stream buf size = %u\n", stream_buf->buf_len); copied_input = copied_input_last; rc = QZ_FAIL; goto done; } else { rc = QZ_OK; } } if (QZ_OK != rc) { copied_input = copied_input_last; rc = QZ_FAIL; goto done; } if (0 == strm->pending_in) { copy_more = 1; inbuf_offset = 0; } if (0 == strm->pending_in && 0 == strm->in_sz) { rc = QZ_OK; goto done; } } done: strm->in_sz = copied_input; strm->out_sz = produced; QZ_DEBUG("Exit Compress Stream input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); end: return rc; } int qzDecompressStream(QzSession_T *sess, QzStream_T *strm, unsigned int last) { int rc = QZ_FAIL; unsigned int input_len = 0; unsigned int output_len = 0; unsigned int copied_output = 0; unsigned int copied_input = 0; unsigned int copied_input_last = 0; unsigned int consumed = 0; unsigned int produced = 0; unsigned int copy_more = 1; unsigned int inbuf_offset = 0; QzStreamBuf_T *stream_buf = NULL; if (NULL == sess || \ NULL == strm || \ (last != 0 && last != 1)) { rc = QZ_PARAMS; if (NULL != strm) { strm->in_sz = 0; strm->out_sz = 0; } goto end; } if (NULL == strm->in || \ NULL == strm->out) { rc = QZ_PARAMS; strm->in_sz = 0; strm->out_sz = 0; goto end; } if (NULL == strm->opaque) { rc = initStream(sess, strm); if (QZ_OK != rc) { goto done; } } stream_buf = (QzStreamBuf_T *) strm->opaque; QZ_DEBUG("Decompress Stream Start...\n"); while (strm->pending_out > 0) { copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; if (0 == copied_output) { rc = QZ_OK; if (strm->pending_in > 0) { /* We need to handle all the input that has left pending in the input buffer next time we are called. * Otherwise we'd append additional bits to the pending data, violate the buffer's boundary and * corrupt the memory behind the boundary. */ stream_buf->flush_more = 1; } QZ_DEBUG("No space for pending output...\n"); goto done; } QZ_DEBUG("Copy output %u bytes\n", copied_output); } while (0 == strm->pending_out) { if (1 == copy_more && stream_buf->flush_more != 1) { copied_input_last = copied_input; copied_input += copyStreamInput(strm, strm->in + consumed); if (strm->pending_in < stream_buf->buf_len && last != 1) { rc = QZ_OK; QZ_DEBUG("Batch more input data...\n"); goto done; } else { copy_more = 0; } } if (stream_buf->flush_more == 1) { /* We need to flush all the input that has left pending in the input buffer since the previous call to this function. * Otherwise we'd append additional bits to the pending data, violate the buffer's boundary and * corrupt the memory behind the boundary. */ stream_buf->flush_more = 0; inbuf_offset = stream_buf->in_offset; } input_len = strm->pending_in; output_len = stream_buf->buf_len; QZ_DEBUG("Before Call qzDecompress input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); rc = qzDecompress(sess, stream_buf->in_buf + inbuf_offset, &input_len, stream_buf->out_buf, &output_len); QZ_DEBUG("Return code = %d\n", rc); if (QZ_OK != rc && QZ_BUF_ERROR != rc) { copied_input = copied_input_last; goto done; } inbuf_offset += input_len; stream_buf->in_offset = inbuf_offset; consumed = copied_input; strm->pending_in -= input_len; strm->pending_out = output_len; copied_output = copyStreamOutput(strm, strm->out + produced); produced += copied_output; QZ_DEBUG("Copy output %u bytes\n", copied_output); QZ_DEBUG("After Call qzDecompress input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); if (QZ_BUF_ERROR == rc) { if (0 == input_len) { QZ_ERROR("Error in qzDecompressStream, stream buf size = %u\n", stream_buf->buf_len); copied_input = copied_input_last; rc = QZ_FAIL; goto done; } else { QZ_DEBUG("Recoverable buffer error occurs... \n"); rc = QZ_OK; } } if (0 == strm->pending_in) { copy_more = 1; inbuf_offset = 0; } if (0 == strm->pending_in && 0 == strm->in_sz) { rc = QZ_OK; goto done; } } done: strm->in_sz = copied_input; strm->out_sz = produced; QZ_DEBUG("Exit Decompress Stream input_len %u output_len %u " "stream->pending_in %u stream->pending_out %u " "stream->in_sz %d stream->out_sz %d\n", input_len, output_len, strm->pending_in, strm->pending_out, strm->in_sz, strm->out_sz); end: return rc; } int qzEndStream(QzSession_T *sess, QzStream_T *strm) { int rc = QZ_FAIL; QzStreamBuf_T *stream_buf = NULL; if (NULL == sess || \ NULL == strm) { rc = QZ_PARAMS; goto exit; } if (NULL == strm->opaque) { rc = QZ_OK; goto done; } stream_buf = (QzStreamBuf_T *)strm->opaque; streamBufferFree(stream_buf->out_buf); streamBufferFree(stream_buf->in_buf); free(stream_buf); strm->opaque = NULL; rc = QZ_OK; done: strm->pending_in = 0; strm->pending_out = 0; strm->in_sz = 0; strm->out_sz = 0; exit: return rc; } QATzip-1.2.1/src/qatzip_sw.c000077500000000000000000000700331465165016500156560ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include "qatzip.h" #include "qatzip_internal.h" #include "qz_utils.h" #define GZIP_WRAPPER 16 extern processData_T g_process; static const QzExtraField_T g_extra_field = { .st1 = 'Q', .st2 = 'Z', .x2_len = (uint16_t)sizeof(g_extra_field.qz_e), .qz_e.src_sz = 0, .qz_e.dest_sz = 0, }; static void gen_qatzip_hdr(gz_header *hdr) { qzMemSet(hdr, 0, sizeof(gz_header)); hdr->extra = (Bytef *)&g_extra_field; hdr->extra_len = (uInt)sizeof(g_extra_field); hdr->os = 255; } int qzDeflateSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { int ret; z_stream *stream = NULL; int flush_flag; int last_loop_in; int last_loop_out; int current_loop_in; int current_loop_out; gz_header hdr; unsigned int left_input_sz = *src_len; unsigned int left_output_sz = *dest_len; unsigned int send_sz; unsigned int total_in = 0, total_out = 0; QzSess_T *qz_sess = NULL; int windows_bits = 0; int comp_level = Z_DEFAULT_COMPRESSION; DataFormatInternal_T data_fmt = DATA_FORMAT_DEFAULT; unsigned int chunk_sz = QZ_HW_BUFF_SZ; QzGzH_T *qz_hdr = NULL; Qz4BH_T *qz4B_header = NULL; *src_len = 0; *dest_len = 0; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; qz_sess->force_sw = 1; comp_level = qz_sess->sess_params.comp_lvl; data_fmt = qz_sess->sess_params.data_fmt; chunk_sz = qz_sess->sess_params.hw_buff_sz; stream = qz_sess->deflate_strm; if (DeflateNull == qz_sess->deflate_stat) { if (NULL == stream) { stream = calloc(1, sizeof(z_stream)); if (NULL == stream) { return QZ_FAIL; } qz_sess->deflate_strm = stream; } stream->zalloc = (alloc_func)0; stream->zfree = (free_func)0; stream->opaque = (voidpf)0; stream->total_in = 0; stream->total_out = 0; switch (data_fmt) { case DEFLATE_4B: case DEFLATE_RAW: windows_bits = -MAX_WBITS; break; case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: default: windows_bits = MAX_WBITS + GZIP_WRAPPER; break; } /*Gzip header*/ if (Z_OK != deflateInit2(stream, comp_level, Z_DEFLATED, windows_bits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY)) { qz_sess->deflate_stat = DeflateNull; return QZ_FAIL; } qz_sess->deflate_stat = DeflateInited; if (DEFLATE_GZIP_EXT == data_fmt) { gen_qatzip_hdr(&hdr); if (Z_OK != deflateSetHeader(stream, &hdr)) { qz_sess->deflate_stat = DeflateNull; stream->total_in = 0; stream->total_out = 0; return QZ_FAIL; } qz_hdr = (QzGzH_T *)dest; } else if (DEFLATE_4B == data_fmt) { /* Need to reserve 4 bytes to fill the compressed length. */ qz4B_header = (Qz4BH_T *)dest; dest = dest + sizeof(Qz4BH_T); } } #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), COMPRESSION, SW); #endif do { send_sz = left_input_sz > chunk_sz ? chunk_sz : left_input_sz; left_input_sz -= send_sz; if (0 == left_input_sz && 1 == last) { flush_flag = Z_FINISH; } else { flush_flag = Z_FULL_FLUSH; } stream->next_in = (z_const Bytef *)src + total_in; stream->avail_in = send_sz; stream->next_out = (Bytef *)dest + total_out; stream->avail_out = left_output_sz; last_loop_in = GET_LOWER_32BITS(stream->total_in); last_loop_out = GET_LOWER_32BITS(stream->total_out); ret = deflate(stream, flush_flag); if ((Z_STREAM_END != ret && Z_FINISH == flush_flag) || (Z_OK != ret && Z_FULL_FLUSH == flush_flag)) { QZ_ERROR("ERR: deflate failed with return code: %d flush_flag: %d\n", ret, flush_flag); stream->total_in = 0; stream->total_out = 0; qz_sess->deflate_stat = DeflateNull; return QZ_FAIL; } current_loop_in = GET_LOWER_32BITS(stream->total_in) - last_loop_in; current_loop_out = GET_LOWER_32BITS(stream->total_out) - last_loop_out; left_output_sz -= current_loop_out; total_out += current_loop_out; total_in += current_loop_in; *src_len = total_in; *dest_len = total_out; if (NULL != qz_sess->crc32) { if (DEFLATE_RAW == data_fmt) { *qz_sess->crc32 = crc32(*qz_sess->crc32, src + total_in - current_loop_in, current_loop_in); } else { if (0 == *qz_sess->crc32) { *qz_sess->crc32 = stream->adler; } else { *qz_sess->crc32 = crc32_combine(*qz_sess->crc32, stream->adler, *src_len); } } } } while (left_input_sz); if (1 == last) { /* * When data_fmt is DEFLATE_GZIP_EXT, * we should fill src_sz & dest_sz in gzipext header field. */ if (DEFLATE_GZIP_EXT == data_fmt && qz_hdr) { qz_hdr->extra.qz_e.src_sz = stream->total_in; qz_hdr->extra.qz_e.dest_sz = stream->total_out - outputHeaderSz(data_fmt) - outputFooterSz(data_fmt); } else if (DEFLATE_4B == data_fmt && qz4B_header) { qz4B_header->blk_size = stream->total_out; *dest_len = *dest_len + sizeof(Qz4BH_T); } ret = deflateEnd(stream); stream->total_in = 0; stream->total_out = 0; qz_sess->deflate_stat = DeflateNull; if (Z_OK != ret) { return QZ_FAIL; } } return QZ_OK; } int qzDeflateSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { z_stream *stream = NULL; int ret = QZ_OK; int zlib_ret = Z_OK; DataFormatInternal_T data_fmt; int windows_bits = 0; unsigned int total_in; unsigned int total_out; unsigned int qz4B_header_len = 0; QzSess_T *qz_sess = (QzSess_T *) sess->internal; qz_sess->force_sw = 1; stream = qz_sess->inflate_strm; data_fmt = qz_sess->sess_params.data_fmt; if (NULL == stream) { stream = calloc(1, sizeof(z_stream)); if (NULL == stream) { *src_len = 0; *dest_len = 0; return QZ_FAIL; } stream->zalloc = (alloc_func)0; stream->zfree = (free_func)0; stream->opaque = (voidpf)0; stream->total_in = 0; stream->total_out = 0; qz_sess->inflate_strm = stream; } stream->next_in = (z_const Bytef *)src; stream->avail_in = *src_len; stream->next_out = (Bytef *)dest; stream->avail_out = *dest_len; *src_len = 0; *dest_len = 0; QZ_DEBUG("decomp_sw data_fmt: %d\n", data_fmt); switch (data_fmt) { case DEFLATE_4B: case DEFLATE_RAW: windows_bits = -MAX_WBITS; break; case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: default: windows_bits = MAX_WBITS + GZIP_WRAPPER; break; } if (InflateNull == qz_sess->inflate_stat) { if (DEFLATE_4B == data_fmt) { /* For DEFLATE_4B, we need to skip the header. */ stream->next_in = (z_const Bytef *)stream->next_in + sizeof(Qz4BH_T); stream->avail_in = stream->avail_in - sizeof(Qz4BH_T); qz4B_header_len = sizeof(Qz4BH_T); } ret = inflateInit2(stream, windows_bits); if (Z_OK != ret) { ret = QZ_FAIL; goto done; } QZ_DEBUG("\n****** inflate init done with win_bits: %d *****\n", windows_bits); qz_sess->inflate_stat = InflateInited; stream->total_in = 0; total_in = 0; stream->total_out = 0; total_out = 0; } else { total_in = GET_LOWER_32BITS(stream->total_in); total_out = GET_LOWER_32BITS(stream->total_out); } zlib_ret = inflate(stream, Z_SYNC_FLUSH); switch (zlib_ret) { case Z_OK: if (QZ_LOW_DEST_MEM == sess->thd_sess_stat) { QZ_DEBUG("ERR: inflate failed with Z_DATA_ERROR\n"); ret = QZ_DATA_ERROR; qz_sess->inflate_stat = InflateError; goto done; } ret = QZ_OK; qz_sess->inflate_stat = InflateOK; break; case Z_STREAM_END: ret = QZ_OK; qz_sess->inflate_stat = InflateEnd; break; case Z_DATA_ERROR: QZ_DEBUG("ERR: inflate failed with Z_DATA_ERROR\n"); ret = QZ_DATA_ERROR; qz_sess->inflate_stat = InflateError; goto done; default: QZ_DEBUG("ERR: inflate failed with error code %d\n", ret); ret = QZ_FAIL; qz_sess->inflate_stat = InflateError; goto done; } *dest_len = GET_LOWER_32BITS(stream->total_out - total_out); /* for Deflate_4B, we need to add the length of Deflate 4B header. */ *src_len = GET_LOWER_32BITS(stream->total_in - total_in + qz4B_header_len); done: QZ_DEBUG("Exit qzSWDecompress total_in: %lu total_out: %lu " "avail_in: %u avail_out: %u msg: %s " "src_len: %u dest_len: %u\n", stream->total_in, stream->total_out, stream->avail_in, stream->avail_out, stream->msg, *src_len, *dest_len); if (zlib_ret == Z_STREAM_END || QZ_LOW_DEST_MEM == sess->thd_sess_stat) { if (Z_OK != inflateEnd(stream)) { QZ_DEBUG("inflateEnd failed.\n"); ret = QZ_FAIL; } qz_sess->inflate_stat = InflateNull; QZ_DEBUG("\n****** inflate end done *****\n"); } return ret; } int qzSWDecompressMultiGzip(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { int ret = QZ_OK; unsigned int total_in = 0; unsigned int total_out = 0; const unsigned int input_len = *src_len; const unsigned int output_len = *dest_len; unsigned int cur_input_len = input_len; unsigned int cur_output_len = output_len; #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, SW); #endif QZ_DEBUG("Start qzSWDecompressMultiGzip: src_len %u dest_len %u\n", *src_len, *dest_len); *src_len = 0; *dest_len = 0; while (total_in < input_len && total_out < output_len) { ret = qzDeflateSWDecompress(sess, src + total_in, &cur_input_len, dest + total_out, &cur_output_len); if (ret != QZ_OK) { goto out; } total_in += cur_input_len; total_out += cur_output_len; cur_input_len = input_len - total_in; cur_output_len = output_len - total_out; *src_len = total_in; *dest_len = total_out; } out: QZ_DEBUG("Exit qzSWDecompressMultiGzip: src_len %u dest_len %u\n", *src_len, *dest_len); return ret; } int qzLZ4SWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { size_t total_out = 0; assert(sess); assert(sess->internal); QzSess_T *qz_sess = (QzSess_T *)sess->internal; LZ4F_preferences_t preferences = {0}; preferences.frameInfo.contentChecksumFlag = 1; preferences.frameInfo.contentSize = *src_len; preferences.autoFlush = 1; preferences.compressionLevel = qz_sess->sess_params.comp_lvl; total_out = LZ4F_compressFrame(dest, *dest_len, src, *src_len, &preferences); if (LZ4F_isError(total_out)) { QZ_ERROR("LZ4F_compressUpdate error: %s\n", LZ4F_getErrorName(total_out)); goto lz4_compress_fail; } *dest_len = total_out; QZ_DEBUG("Exit qzLZ4SWCompress: src_len %u dest_len %u\n", *src_len, *dest_len); return QZ_OK; lz4_compress_fail: *src_len = 0; *dest_len = 0; return QZ_FAIL; } int qzLZ4SWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { size_t in_sz = 0; size_t out_sz = 0; size_t ret = QZ_OK; QzSess_T *qz_sess = NULL; QZ_DEBUG("Enter qzLZ4SWDecompress: src_len %u dest_len %u\n", *src_len, *dest_len); qz_sess = (QzSess_T *) sess->internal; if (qz_sess->dctx == NULL) { ret = LZ4F_createDecompressionContext(&(qz_sess->dctx), LZ4F_VERSION); if (LZ4F_isError(ret)) { QZ_ERROR("LZ4F_createDecompressionContext error: %s\n", LZ4F_getErrorName(ret)); goto lz4_decompress_fail; } } in_sz = *src_len; out_sz = *dest_len; ret = LZ4F_decompress(qz_sess->dctx, dest, (size_t *)&out_sz, src, (size_t *)&in_sz, NULL); if (LZ4F_isError(ret)) { QZ_ERROR("LZ4F_decompress error: %s\n", LZ4F_getErrorName(ret)); goto lz4_decompress_fail; } else if (ret == 0) { /* * when ret == 0, it means that a frame be fully decompressed, * we need to free the dctx, not reuse it to decompress another frame. */ LZ4F_freeDecompressionContext(qz_sess->dctx); qz_sess->dctx = NULL; } else { /* * when ret > 0, it means that the compressed data is not a fully frame, * it needs more compressed data to decompress. The remaining compressed data * was stored in dctx. */ QZ_DEBUG("LZ4F_decompress: incomplete compressed data, need more data\n"); } *src_len = in_sz; *dest_len = out_sz; QZ_DEBUG("Exit qzLZ4SWDecompress: src_len %u dest_len %u\n", *src_len, *dest_len); return QZ_OK; lz4_decompress_fail: if (qz_sess->dctx != NULL) { LZ4F_freeDecompressionContext(qz_sess->dctx); qz_sess->dctx = NULL; } *src_len = 0; *dest_len = 0; return QZ_FAIL; } int qzSWDecompressMultiLZ4(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { int ret = QZ_OK; unsigned int total_in = 0; unsigned int total_out = 0; const unsigned int input_len = *src_len; const unsigned int output_len = *dest_len; unsigned int cur_input_len = input_len; unsigned int cur_output_len = output_len; #ifdef QATZIP_DEBUG insertThread((unsigned int)pthread_self(), DECOMPRESSION, SW); #endif QZ_DEBUG("Start qzSWDecompressMultiLz4: src_len %u dest_len %u\n", *src_len, *dest_len); *src_len = 0; *dest_len = 0; while (total_in < input_len && total_out < output_len) { ret = qzLZ4SWDecompress(sess, src + total_in, &cur_input_len, dest + total_out, &cur_output_len); if (ret != QZ_OK) { goto out; } total_in += cur_input_len; total_out += cur_output_len; cur_input_len = input_len - total_in; cur_output_len = output_len - total_out; *src_len = total_in; *dest_len = total_out; } out: QZ_DEBUG("Exit qzSWDecompressMultiLz4: src_len %u dest_len %u\n", *src_len, *dest_len); return ret; } /* The software failover function for compression request */ int qzSWCompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, unsigned int last) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: ret = qzDeflateSWCompress(sess, src, src_len, dest, dest_len, last); break; case LZ4_FH: ret = qzLZ4SWCompress(sess, src, src_len, dest, dest_len, last); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } /* The software failover function for decompression request */ int qzSWDecompress(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: ret = qzDeflateSWDecompress(sess, src, src_len, dest, dest_len); break; case LZ4_FH: ret = qzLZ4SWDecompress(sess, src, src_len, dest, dest_len); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } int qzSWDecompressMulti(QzSession_T *sess, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len) { #ifdef ENABLE_TESTLOG QZ_TESTLOG(2, 0, "SW_FALLBACK", "sw fallback happend!"); #endif int ret = QZ_FAIL; DataFormatInternal_T data_fmt; QzSess_T *qz_sess = NULL; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *) sess->internal; data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_RAW: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_4B: ret = qzSWDecompressMultiGzip(sess, src, src_len, dest, dest_len); break; case LZ4_FH: ret = qzSWDecompressMultiLZ4(sess, src, src_len, dest, dest_len); break; default: QZ_ERROR("Unknown/unsupported data format: %d\n", data_fmt); *src_len = 0; *dest_len = 0; ret = QZ_FAIL; break; } return ret; } int compInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned int src_send_sz) { int rc; unsigned int dest_receive_sz = DEST_SZ(src_send_sz); QzSess_T *qz_sess = (QzSess_T *)sess->internal; if (!qz_sess->sess_params.sw_backup) { QZ_DEBUG("The instance %d heartbeat is failure, Don't enable sw fallback, compressIn fatal ERROR!\n", i); return QZ_FAIL; } if (qz_sess->single_thread) { QZ_DEBUG("The instance %d failure, single_thread, compressIn fatal ERROR!\n", i); return QZ_FAIL; } if (qz_sess->stop_submitting) { QZ_DEBUG("compInSWFallback stop submit\n"); return QZ_FAIL; } if (qz_sess->seq != qz_sess->seq_in) { return QZ_WAIT_SW_PENDING; } QZ_DEBUG("SW CompIn Sending %u bytes, seq = %ld, instance = %d\n", src_send_sz, qz_sess->seq, i); /* sw fallback here */ rc = qzSWCompress(sess, src_ptr, &src_send_sz, qz_sess->next_dest, &dest_receive_sz, qz_sess->last); QZ_DEBUG("SW CompIn src_ptr %p, dst_ptr %p, Sending %u bytes, seq = %ld\n", src_ptr, qz_sess->next_dest, src_send_sz, qz_sess->seq); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW CompIn fallback failure! compress fatal ERROR!\n"); return QZ_FAIL; } /* For SW compress, have to update ComputeOut status first */ qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; qz_sess->seq_in++; qz_sess->processed++; return QZ_OK; } int compOutSWFallback(int i, int j, QzSession_T *sess, long *dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; unsigned int src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; /* sw dest buffer is align with the inst hw buffer size */ unsigned int dest_receive_sz = outputHeaderSz(qz_sess->sess_params.data_fmt) + g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes; unsigned char *src_ptr = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; unsigned char *dest_ptr = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; if (!qz_sess->sess_params.sw_backup) { QZ_DEBUG("The instance %d heartbeat is failure, Don't enable sw fallback, compressOut fatal ERROR!\n", i); return QZ_FAIL; } QZ_DEBUG("The request get dummy emty respond, offload to software!\n"); QZ_DEBUG("SW CompOut src_ptr %p, dst_ptr %p, Sending %u bytes, seq = %ld\n", src_ptr, dest_ptr, src_send_sz, g_process.qz_inst[i].stream[j].seq); rc = qzSWCompress(sess, src_ptr, &src_send_sz, dest_ptr, &dest_receive_sz, qz_sess->last); if (QZ_OK != rc) { QZ_ERROR("SW CompOut fallback failure! compress fatal ERROR!\n"); return QZ_FAIL; } rc = compOutCheckDestLen(i, j, sess, dest_avail_len, dest_receive_sz); if (QZ_OK != rc) { return rc; } /* Update qz_sess info and clean dest buffer */ compOutValidDestBufferCleanUp(i, j, qz_sess, dest_receive_sz); qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; return rc; } int decompInSWFallback(int i, int j, QzSession_T *sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; if (!qz_sess->sess_params.sw_backup) { QZ_DEBUG("The instance %d heartbeat is failure, Don't enable sw fallback, decompressIn fatal ERROR!\n", i); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } if (qz_sess->single_thread) { QZ_DEBUG("The instance %d failure, single thread, decompressIn fatal ERROR!\n", i); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } if (qz_sess->stop_submitting) { QZ_DEBUG("decompInSWFallback stop submit\n"); return QZ_FAIL; } if (qz_sess->seq != qz_sess->seq_in) { return QZ_WAIT_SW_PENDING; } QZ_DEBUG("SW DecompIn src_ptr %p, dest_ptr %p, Sending %u bytes, seq = %ld, instance = %d\n", src_ptr, dest_ptr, tmp_src_avail_len, qz_sess->seq, i); rc = qzSWDecompress(sess, src_ptr, tmp_src_avail_len, dest_ptr, tmp_dest_avail_len); if (unlikely(QZ_OK != rc)) { QZ_ERROR("SW deCompIn fallback failure! decompress fatal ERROR!\n"); sess->thd_sess_stat = QZ_FAIL; return QZ_FAIL; } /* For compressIn fallback, need to update seq_in first */ qz_sess->seq_in++; qz_sess->processed++; qz_sess->qz_in_len += *tmp_src_avail_len; qz_sess->qz_out_len += *tmp_dest_avail_len; qz_sess->next_dest += *tmp_dest_avail_len; return QZ_OK; } int decompOutSWFallback(int i, int j, QzSession_T *sess, unsigned int *dest_avail_len) { int rc; QzSess_T *qz_sess = (QzSess_T *)sess->internal; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; unsigned int src_send_sz = g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes; unsigned int dest_receive_sz = g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes; /* pinned buffer ptr already strip header, need retrieve. * use original src_ptr and consumed len to get src_ptr for this request. */ unsigned char *src_ptr = qz_sess->src + qz_sess->qz_in_len; src_send_sz += (outputHeaderSz(data_fmt) + outputFooterSz(data_fmt)) ; if (!qz_sess->sess_params.sw_backup) { QZ_DEBUG("The instance %d heartbeat is failure, Don't enable sw fallback, decompressOut fatal ERROR!\n", i); return QZ_FAIL; } QZ_DEBUG("The request get dummy empty respond, offload to software!\n"); QZ_DEBUG("SW DecompOut src_ptr %p, dest_ptr %p, Sending %u bytes, receive %u bytes, seq = %ld\n", src_ptr, qz_sess->next_dest, src_send_sz, dest_receive_sz, g_process.qz_inst[i].stream[j].seq); rc = qzSWDecompress(sess, src_ptr, &src_send_sz, qz_sess->next_dest, &dest_receive_sz); if (QZ_OK != rc) { QZ_ERROR("SW deCompOut fallback failure! compress fatal ERROR!\n"); return QZ_FAIL; } /* update qz_sess info, Don't need clean dest buffer */ decompOutErrorDestBufferCleanUp(i, j); qz_sess->next_dest += dest_receive_sz; qz_sess->qz_in_len += src_send_sz; qz_sess->qz_out_len += dest_receive_sz; *dest_avail_len -= dest_receive_sz; return QZ_OK; }QATzip-1.2.1/src/qatzip_utils.c000066400000000000000000001204161465165016500163630ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #ifdef HAVE_QAT_HEADERS #include #include #else #include #include #endif #include #include "qatzip_internal.h" static QatThread_T g_qat_thread; extern processData_T g_process; #ifdef QATZIP_DEBUG static void doInsertThread(unsigned int th_id, ThreadList_T **thd_list, unsigned int *num_thd, pthread_mutex_t *lock, Serv_T serv_type, Engine_T engine_type) { ThreadList_T *node; ThreadList_T *prev_node; if (0 != pthread_mutex_lock(lock)) { return; } for (prev_node = node = *thd_list; node; node = node->next) { if (node->thread_id == th_id) { break; } prev_node = node; } if (!node) { node = (ThreadList_T *)calloc(1, sizeof(*node)); if (!node) { QZ_ERROR("[ERROR]: alloc memory failed in file(%s) line(%d)\n", __FILE__, __LINE__); goto done; } node->thread_id = th_id; ++*num_thd; if (prev_node) { prev_node->next = node; } else { *thd_list = node; } } if (SW == engine_type) { if (COMPRESSION == serv_type) { ++node->comp_sw_count; } else if (DECOMPRESSION == serv_type) { ++node->decomp_sw_count; } } else if (HW == engine_type) { if (COMPRESSION == serv_type) { ++node->comp_hw_count; } else if (DECOMPRESSION == serv_type) { ++node->decomp_hw_count; } } done: (void)pthread_mutex_unlock(lock); } void insertThread(unsigned int th_id, Serv_T serv_type, Engine_T engine_type) { QatThread_T *th_list = &g_qat_thread; if (COMPRESSION == serv_type) { doInsertThread(th_id, &th_list->comp_th_list, &th_list->num_comp_th, &th_list->comp_lock, serv_type, engine_type); } else if (DECOMPRESSION == serv_type) { doInsertThread(th_id, &th_list->decomp_th_list, &th_list->num_decomp_th, &th_list->decomp_lock, serv_type, engine_type); } } static void doDumpThreadInfo(ThreadList_T *node, unsigned int num_node, Serv_T type) { unsigned int i; char *serv_title; if (num_node > 0) { i = 0; if (COMPRESSION == type) { serv_title = "Compression"; } else { serv_title = "Decompression"; } QZ_PRINT("[INFO]: %s num_th %u\n", serv_title, num_node); while (node) { QZ_PRINT("th_id: %u comp_hw_count: %u comp_sw_count: %u " "decomp_hw_count: %u decomp_sw_count: %u\n", node->thread_id, node->comp_hw_count, node->comp_sw_count, node->decomp_hw_count, node->decomp_sw_count); i++; node = node->next; if (i == num_node) { break; } } if (node) { QZ_ERROR("[ERROR]: there's node left in the list\n"); } QZ_PRINT("\n"); } } void dumpThreadInfo(void) { QatThread_T *th_list = &g_qat_thread; doDumpThreadInfo(th_list->comp_th_list, th_list->num_comp_th, COMPRESSION); doDumpThreadInfo(th_list->decomp_th_list, th_list->num_decomp_th, DECOMPRESSION); } #endif void initDebugLock(void) { pthread_mutex_init(&g_qat_thread.comp_lock, NULL); pthread_mutex_init(&g_qat_thread.decomp_lock, NULL); } static int qzSetupDcSessionData(CpaDcSessionSetupData *session_setup_data, QzSessionParamsInternal_T *params) { assert(session_setup_data); assert(params); session_setup_data->compLevel = params->comp_lvl; switch (params->data_fmt) { case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: case DEFLATE_RAW: session_setup_data->compType = CPA_DC_DEFLATE; session_setup_data->checksum = CPA_DC_CRC32; session_setup_data->autoSelectBestHuffmanTree = CPA_DC_ASB_UNCOMP_STATIC_DYNAMIC_WITH_STORED_HDRS; if (params->huffman_hdr == QZ_DYNAMIC_HDR) { session_setup_data->huffType = CPA_DC_HT_FULL_DYNAMIC; } else { session_setup_data->huffType = CPA_DC_HT_STATIC; } break; case LZ4_FH: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->compType = CPA_DC_LZ4; session_setup_data->checksum = CPA_DC_XXHASH32; session_setup_data->lz4BlockChecksum = 0; session_setup_data->lz4BlockMaxSize = CPA_DC_LZ4_MAX_BLOCK_SIZE_64K; break; #else QZ_ERROR("QAT driver does not support lz4 algorithm\n"); return QZ_UNSUPPORTED_FMT; #endif case LZ4S_BK: #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->compType = CPA_DC_LZ4S; session_setup_data->checksum = CPA_DC_XXHASH32; if (params->lz4s_mini_match == 4) { session_setup_data->minMatch = CPA_DC_MIN_4_BYTE_MATCH; } else { session_setup_data->minMatch = CPA_DC_MIN_3_BYTE_MATCH; } break; #else QZ_ERROR("QAT driver does not support lz4s algorithm\n"); return QZ_UNSUPPORTED_FMT; #endif default: return QZ_UNSUPPORTED_FMT; } switch (params->direction) { case QZ_DIR_COMPRESS: session_setup_data->sessDirection = CPA_DC_DIR_COMPRESS; break; case QZ_DIR_DECOMPRESS: session_setup_data->sessDirection = CPA_DC_DIR_DECOMPRESS; break; default: session_setup_data->sessDirection = CPA_DC_DIR_COMBINED; } session_setup_data->sessState = CPA_DC_STATELESS; #if CPA_DC_API_VERSION_AT_LEAST(3, 1) session_setup_data->windowSize = (Cpa32U)7; #else session_setup_data->deflateWindowSize = (Cpa32U)7; session_setup_data->fileType = CPA_DC_FT_ASCII; #endif return QZ_OK; } int qzSetupSessionInternal(QzSession_T *sess) { int rc; QzSess_T *qz_sess; assert(sess); assert(sess->internal); qz_sess = (QzSess_T *)sess->internal; rc = qzSetupDcSessionData(&qz_sess->session_setup_data, &qz_sess->sess_params); if (rc != QZ_OK) { return rc; } qz_sess->inst_hint = -1; qz_sess->seq = 0; qz_sess->seq_in = 0; qz_sess->polling_idx = 0; qz_sess->force_sw = 0; qz_sess->inflate_strm = NULL; qz_sess->inflate_stat = InflateNull; qz_sess->deflate_strm = NULL; qz_sess->deflate_stat = DeflateNull; qz_sess->dctx = NULL; if (g_process.qz_init_status != QZ_OK) { /*hw not present*/ if (qz_sess->sess_params.sw_backup == 1) { sess->hw_session_stat = QZ_NO_HW; rc = QZ_OK; } else { sess->hw_session_stat = QZ_NOSW_NO_HW; rc = QZ_NOSW_NO_HW; } } else { sess->hw_session_stat = QZ_OK; rc = QZ_OK; } return rc; } int qzCheckParams(QzSessionParams_T *params) { assert(params); if (params->huffman_hdr > QZ_STATIC_HDR) { QZ_ERROR("Invalid huffman_hdr value\n"); return QZ_PARAMS; } if ((params->comp_lvl < QZ_DEFLATE_COMP_LVL_MINIMUM) || (params->comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if (params->direction > QZ_DIR_BOTH) { QZ_ERROR("Invalid direction value\n"); return QZ_PARAMS; } if (params->comp_algorithm != QZ_DEFLATE) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->sw_backup > 1) { QZ_ERROR("Invalid sw_backup value\n"); return QZ_PARAMS; } if ((params->hw_buff_sz < QZ_HW_BUFF_MIN_SZ) || (params->hw_buff_sz > QZ_HW_BUFF_MAX_SZ)) { QZ_ERROR("Invalid hw_buff_sz value\n"); return QZ_PARAMS; } if ((params->strm_buff_sz < QZ_STRM_BUFF_MIN_SZ) || (params->strm_buff_sz > QZ_STRM_BUFF_MAX_SZ)) { QZ_ERROR("Invalid strm_buff_sz value\n"); return QZ_PARAMS; } if (params->input_sz_thrshold < QZ_COMP_THRESHOLD_MINIMUM) { QZ_ERROR("Invalid input_sz_thrshold value\n"); return QZ_PARAMS; } if ((params->req_cnt_thrshold < QZ_REQ_THRESHOLD_MINIMUM) || (params->req_cnt_thrshold > QZ_REQ_THRESHOLD_MAXIMUM)) { QZ_ERROR("Invalid req_cnt_thrshold value\n"); return QZ_PARAMS; } if (params->hw_buff_sz & (params->hw_buff_sz - 1)) { QZ_ERROR("Invalid hw_buff_sz value, must be a power of 2k\n"); return QZ_PARAMS; } return QZ_OK; } static int qzCheckParamsCommon(QzSessionParamsCommon_T *params) { assert(params); if (params->direction > QZ_DIR_BOTH) { QZ_ERROR("Invalid direction value\n"); return QZ_PARAMS; } if ((params->comp_algorithm != QZ_DEFLATE) && (params->comp_algorithm != QZ_LZ4) && (params->comp_algorithm != QZ_LZ4s) && (params->comp_algorithm != QZ_ZSTD)) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->sw_backup > 1) { QZ_ERROR("Invalid sw_backup value\n"); return QZ_PARAMS; } if ((params->hw_buff_sz < QZ_HW_BUFF_MIN_SZ) || (params->hw_buff_sz > QZ_HW_BUFF_MAX_SZ)) { QZ_ERROR("Invalid hw_buff_sz value\n"); return QZ_PARAMS; } if ((params->strm_buff_sz < QZ_STRM_BUFF_MIN_SZ) || (params->strm_buff_sz > QZ_STRM_BUFF_MAX_SZ)) { QZ_ERROR("Invalid strm_buff_sz value\n"); return QZ_PARAMS; } if (params->input_sz_thrshold < QZ_COMP_THRESHOLD_MINIMUM) { QZ_ERROR("Invalid input_sz_thrshold value\n"); return QZ_PARAMS; } if ((params->req_cnt_thrshold < QZ_REQ_THRESHOLD_MINIMUM) || (params->req_cnt_thrshold > QZ_REQ_THRESHOLD_MAXIMUM)) { QZ_ERROR("Invalid req_cnt_thrshold value\n"); return QZ_PARAMS; } if (params->hw_buff_sz & (params->hw_buff_sz - 1)) { QZ_ERROR("Invalid hw_buff_sz value, must be a power of 2k\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsDeflate(QzSessionParamsDeflate_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_DEFLATE) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->huffman_hdr > QZ_STATIC_HDR) { QZ_ERROR("Invalid huffman_hdr value\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM_Gen3)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if (params->data_fmt > QZ_DEFLATE_RAW) { QZ_ERROR("Invalid data_fmt value\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsLZ4(QzSessionParamsLZ4_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_LZ4) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_LZS_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } return QZ_OK; } int qzCheckParamsLZ4S(QzSessionParamsLZ4S_T *params) { assert(params); if (qzCheckParamsCommon(¶ms->common_params) != QZ_OK) { return QZ_PARAMS; } if (params->common_params.comp_algorithm != QZ_LZ4s) { QZ_ERROR("Invalid comp_algorithm value\n"); return QZ_PARAMS; } if (params->common_params.direction != QZ_DIR_COMPRESS) { QZ_ERROR("LZ4s only support compression direction\n"); return QZ_PARAMS; } if ((params->common_params.comp_lvl < QZ_LZS_COMP_LVL_MINIMUM) || (params->common_params.comp_lvl > QZ_LZS_COMP_LVL_MAXIMUM)) { QZ_ERROR("Invalid comp_lvl value\n"); return QZ_PARAMS; } if ((params->lz4s_mini_match < 3) || (params->lz4s_mini_match > 4)) { QZ_ERROR("Invalid lz4s_mini_match value\n"); return QZ_PARAMS; } return QZ_OK; } static void qzSetParamsCommon(QzSessionParamsCommon_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); internal_params->direction = params->direction; internal_params->comp_lvl = params->comp_lvl; internal_params->comp_algorithm = params->comp_algorithm; internal_params->max_forks = params->max_forks; internal_params->sw_backup = params->sw_backup; internal_params->hw_buff_sz = params->hw_buff_sz; internal_params->strm_buff_sz = params->strm_buff_sz; internal_params->input_sz_thrshold = params->input_sz_thrshold; internal_params->req_cnt_thrshold = params->req_cnt_thrshold; internal_params->wait_cnt_thrshold = params->wait_cnt_thrshold; internal_params->polling_mode = params->polling_mode; internal_params->is_sensitive_mode = params->is_sensitive_mode; } /** * Set session params into internal params */ void qzSetParams(QzSessionParams_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); internal_params->direction = params->direction; internal_params->comp_lvl = params->comp_lvl; internal_params->comp_algorithm = params->comp_algorithm; internal_params->max_forks = params->max_forks; internal_params->sw_backup = params->sw_backup; internal_params->hw_buff_sz = params->hw_buff_sz; internal_params->strm_buff_sz = params->strm_buff_sz; internal_params->input_sz_thrshold = params->input_sz_thrshold; internal_params->req_cnt_thrshold = params->req_cnt_thrshold; internal_params->wait_cnt_thrshold = params->wait_cnt_thrshold; if (params->data_fmt == QZ_DEFLATE_4B) { internal_params->data_fmt = DEFLATE_4B; } else if (params->data_fmt == QZ_DEFLATE_GZIP) { internal_params->data_fmt = DEFLATE_GZIP; } else if (params->data_fmt == QZ_DEFLATE_RAW) { internal_params->data_fmt = DEFLATE_RAW; } else { internal_params->data_fmt = DEFLATE_GZIP_EXT; } internal_params->huffman_hdr = params->huffman_hdr; } /** * Set deflate session params into internal params */ void qzSetParamsDeflate(QzSessionParamsDeflate_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); if (params->data_fmt == QZ_DEFLATE_4B) { internal_params->data_fmt = DEFLATE_4B; } else if (params->data_fmt == QZ_DEFLATE_GZIP) { internal_params->data_fmt = DEFLATE_GZIP; } else if (params->data_fmt == QZ_DEFLATE_RAW) { internal_params->data_fmt = DEFLATE_RAW; } else { internal_params->data_fmt = DEFLATE_GZIP_EXT; } internal_params->huffman_hdr = params->huffman_hdr; } void qzSetParamsLZ4(QzSessionParamsLZ4_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); internal_params->data_fmt = LZ4_FH; } /** * Set LZ4S session params into internal params */ void qzSetParamsLZ4S(QzSessionParamsLZ4S_T *params, QzSessionParamsInternal_T *internal_params) { assert(params); assert(internal_params); qzSetParamsCommon(¶ms->common_params, internal_params); internal_params->data_fmt = LZ4S_BK; internal_params->qzCallback = params->qzCallback; internal_params->qzCallback_external = params->qzCallback_external; internal_params->lz4s_mini_match = params->lz4s_mini_match; } /** * Get session params from internal params */ void qzGetParams(QzSessionParamsInternal_T *internal_params, QzSessionParams_T *params) { assert(params); assert(internal_params); params->direction = internal_params->direction; params->comp_lvl = internal_params->comp_lvl; params->comp_algorithm = internal_params->comp_algorithm; params->max_forks = internal_params->max_forks; params->sw_backup = internal_params->sw_backup; params->hw_buff_sz = internal_params->hw_buff_sz; params->strm_buff_sz = internal_params->strm_buff_sz; params->input_sz_thrshold = internal_params->input_sz_thrshold; params->req_cnt_thrshold = internal_params->req_cnt_thrshold; params->wait_cnt_thrshold = internal_params->wait_cnt_thrshold; if (internal_params->data_fmt == DEFLATE_4B) { params->data_fmt = QZ_DEFLATE_4B; } else if (internal_params->data_fmt == DEFLATE_GZIP) { params->data_fmt = QZ_DEFLATE_GZIP; } else if (internal_params->data_fmt == DEFLATE_RAW) { params->data_fmt = QZ_DEFLATE_RAW; } else { params->data_fmt = QZ_DEFLATE_GZIP_EXT; } params->huffman_hdr = internal_params->huffman_hdr; } static void qzGetParamsCommon(QzSessionParamsInternal_T *internal_params, QzSessionParamsCommon_T *params) { assert(params); assert(internal_params); params->direction = internal_params->direction; params->comp_lvl = internal_params->comp_lvl; params->comp_algorithm = internal_params->comp_algorithm; params->max_forks = internal_params->max_forks; params->sw_backup = internal_params->sw_backup; params->hw_buff_sz = internal_params->hw_buff_sz; params->strm_buff_sz = internal_params->strm_buff_sz; params->input_sz_thrshold = internal_params->input_sz_thrshold; params->req_cnt_thrshold = internal_params->req_cnt_thrshold; params->wait_cnt_thrshold = internal_params->wait_cnt_thrshold; params->polling_mode = internal_params->polling_mode; params->is_sensitive_mode = internal_params->is_sensitive_mode; } /** * Get deflate session params from internal params */ void qzGetParamsDeflate(QzSessionParamsInternal_T *internal_params, QzSessionParamsDeflate_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); if (internal_params->data_fmt == DEFLATE_4B) { params->data_fmt = QZ_DEFLATE_4B; } else if (internal_params->data_fmt == DEFLATE_GZIP) { params->data_fmt = QZ_DEFLATE_GZIP; } else if (internal_params->data_fmt == DEFLATE_RAW) { params->data_fmt = QZ_DEFLATE_RAW; } else { params->data_fmt = QZ_DEFLATE_GZIP_EXT; } params->huffman_hdr = internal_params->huffman_hdr; params->common_params.comp_algorithm = QZ_DEFLATE; } /** * Get LZ4 session params from internal params */ void qzGetParamsLZ4(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); params->common_params.comp_algorithm = QZ_LZ4; } /** * Get LZ4S session params from internal params */ void qzGetParamsLZ4S(QzSessionParamsInternal_T *internal_params, QzSessionParamsLZ4S_T *params) { assert(params); assert(internal_params); qzGetParamsCommon(internal_params, ¶ms->common_params); params->common_params.comp_algorithm = QZ_LZ4s; /* LZ4s only support compression. */ params->common_params.direction = QZ_DIR_COMPRESS; params->qzCallback = internal_params->qzCallback; params->qzCallback_external = internal_params->qzCallback_external; params->lz4s_mini_match = internal_params->lz4s_mini_match; } inline unsigned long outputFooterSz(DataFormatInternal_T data_fmt) { unsigned long size = 0; switch (data_fmt) { case DEFLATE_4B: /* fall through */ case DEFLATE_RAW: size = 0; break; case LZ4_FH: size = qzLZ4FooterSz(); break; case LZ4S_BK: size = 0; break; case DEFLATE_GZIP_EXT: default: size = stdGzipFooterSz(); break; } return size; } unsigned long outputHeaderSz(DataFormatInternal_T data_fmt) { unsigned long size = 0; switch (data_fmt) { case DEFLATE_4B: size = qz4BHeaderSz(); break; case DEFLATE_RAW: break; case DEFLATE_GZIP: size = stdGzipHeaderSz(); break; case LZ4_FH: size = qzLZ4HeaderSz(); break; case LZ4S_BK: size = qzLZ4SBlockHeaderSz(); break; case DEFLATE_GZIP_EXT: default: size = qzGzipHeaderSz(); break; } return size; } void outputHeaderGen(unsigned char *ptr, CpaDcRqResults *res, DataFormatInternal_T data_fmt) { QZ_DEBUG("Generate header\n"); switch (data_fmt) { case DEFLATE_4B: qz4BHeaderGen(ptr, res); break; case DEFLATE_RAW: break; case DEFLATE_GZIP: stdGzipHeaderGen(ptr, res); break; case LZ4_FH: qzLZ4HeaderGen(ptr, res); break; case LZ4S_BK: qzLZ4SBlockHeaderGen(ptr, res); break; case DEFLATE_GZIP_EXT: default: qzGzipHeaderGen(ptr, res); break; } } inline void outputFooterGen(QzSess_T *qz_sess, CpaDcRqResults *res, DataFormatInternal_T data_fmt) { unsigned char *ptr = qz_sess->next_dest; switch (data_fmt) { case DEFLATE_RAW: break; case LZ4_FH: qzLZ4FooterGen(ptr, res); break; case LZ4S_BK: break; case DEFLATE_GZIP_EXT: default: qzGzipFooterGen(ptr, res); break; } } int isQATProcessable(const unsigned char *ptr, const unsigned int *const src_len, QzSess_T *const qz_sess) { uint32_t rc = 0; DataFormatInternal_T data_fmt; assert(ptr != NULL); assert(src_len != NULL); assert(qz_sess != NULL); data_fmt = qz_sess->sess_params.data_fmt; switch (data_fmt) { case DEFLATE_4B: case DEFLATE_GZIP: case DEFLATE_GZIP_EXT: rc = isQATDeflateProcessable(ptr, src_len, qz_sess); break; case LZ4_FH: rc = isQATLZ4Processable(ptr, src_len, qz_sess); break; default: rc = 0; break; } return rc; } void RestoreDestCpastreamBuffer(int i, int j) { if (g_process.qz_inst[i].stream[j].dest_need_reset) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } } void RestoreSrcCpastreamBuffer(int i, int j) { if (g_process.qz_inst[i].stream[j].src_need_reset) { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_src; g_process.qz_inst[i].stream[j].src_need_reset = 0; } } void ResetCpastreamSink(int i, int j) { g_process.qz_inst[i].stream[j].src1 = 0; g_process.qz_inst[i].stream[j].src2 = 0; g_process.qz_inst[i].stream[j].sink1 = 0; g_process.qz_inst[i].stream[j].sink2 = 0; } /* This setup function will always match with buffer clean up function * during error offload flow. */ void compBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned int src_remaining, unsigned int hw_buff_sz, unsigned int src_send_sz) { unsigned int dest_receive_sz = 0; /* Get the qz_sess status of this request */ CpaDcOpData *opData = NULL; CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; /* setup stream buffer */ g_process.qz_inst[i].stream[j].seq = qz_sess->seq; /*update stream seq*/ g_process.qz_inst[i].stream[j].res.checksum = 0; /* setup opData */ opData = &g_process.qz_inst[i].stream[j].opData; opData->inputSkipData.skipMode = CPA_DC_SKIP_DISABLED; opData->outputSkipData.skipMode = CPA_DC_SKIP_DISABLED; opData->compressAndVerify = CPA_TRUE; if (IS_DEFLATE_RAW(data_fmt) && (1 != qz_sess->last || src_remaining > hw_buff_sz)) { opData->flushFlag = CPA_DC_FLUSH_FULL; } else { opData->flushFlag = CPA_DC_FLUSH_FINAL; } QZ_DEBUG("sending seq number %d %d %ld, opData.flushFlag %d\n", i, j, qz_sess->seq, opData->flushFlag); /*Get feed src/dest buffer size*/ dest_receive_sz = *qz_sess->dest_sz > DEST_SZ(src_send_sz) ? DEST_SZ(src_send_sz) - outputHeaderSz(data_fmt) : *qz_sess->dest_sz - outputHeaderSz(data_fmt); g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_send_sz; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_receive_sz; if (!need_cont_mem) { QZ_DEBUG("Compress SVM Enabled in doCompressIn\n"); } /*Feed src/dest buffer*/ if ((COMMON_MEM == qzMemFindAddr(src_ptr)) && need_cont_mem) { QZ_MEMCPY(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, src_ptr, src_send_sz, src_remaining); g_process.qz_inst[i].stream[j].src_need_reset = 0; } else { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = src_ptr; g_process.qz_inst[i].stream[j].src_need_reset = 1; } /*using zerocopy for the first request while dest buffer is pinned*/ if (unlikely((0 == g_process.qz_inst[i].stream[j].seq) && (!need_cont_mem || qzMemFindAddr(qz_sess->next_dest)))) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = qz_sess->next_dest + outputHeaderSz(data_fmt); g_process.qz_inst[i].stream[j].dest_need_reset = 1; } } /* when offload request failed after setup the buffer. * use this function to cleanup setup buffer. */ void compInBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); RestoreSrcCpastreamBuffer(i, j); g_process.qz_inst[i].stream[j].src1 -= 1; g_process.qz_inst[i].stream[j].src2 -= 1; } /* when offload request successfully, Using below functions to process * clean up work during compressOut. There are clean up buffer function * in correct process flow or error process flow. */ void compOutSrcBufferCleanUp(int i, int j) { RestoreSrcCpastreamBuffer(i, j); } void compOutErrorDestBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); } void compOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, unsigned int dest_receive_sz) { CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; if (!need_cont_mem) { QZ_DEBUG("Compress SVM Enabled in doCompressOut\n"); } if (g_process.qz_inst[i].stream[j].dest_need_reset) { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } else { QZ_MEMCPY(qz_sess->next_dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, *qz_sess->dest_sz - qz_sess->qz_out_len, dest_receive_sz); } } /* Process respond means to reset or update sess status * And clean up buffer. */ void compOutProcessedRespond(int i, int j, QzSess_T *qz_sess) { compOutSrcBufferCleanUp(i, j); /* Update the seq_in and process, clean buffer */ assert(g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in); g_process.qz_inst[i].stream[j].sink2++; qz_sess->processed++; qz_sess->seq_in++; } void compOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess) { compOutErrorDestBufferCleanUp(i, j); compOutProcessedRespond(i, j, qz_sess); } int compOutCheckDestLen(int i, int j, QzSession_T *sess, long *dest_avail_len, long dest_receive_sz) { QzSess_T *qz_sess = (QzSess_T *)sess->internal; *dest_avail_len -= dest_receive_sz; if (unlikely(*dest_avail_len < 0)) { QZ_DEBUG("doCompressOut: inadequate output buffer length: %ld, outlen: %ld\n", (long)(*qz_sess->dest_sz), qz_sess->qz_out_len); compOutSkipErrorRespond(i, j, qz_sess); qz_sess->stop_submitting = 1; sess->thd_sess_stat = QZ_BUF_ERROR; return sess->thd_sess_stat; } return QZ_OK; } /*To handle compression expansion*/ void swapDataBuffer(unsigned long i, int j) { Cpa8U *p_tmp_data; p_tmp_data = g_process.qz_inst[i].src_buffers[j]->pBuffers->pData; g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData; g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = p_tmp_data; p_tmp_data = g_process.qz_inst[i].stream[j].orig_src; g_process.qz_inst[i].stream[j].orig_src = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].orig_dest = p_tmp_data; } /* Note: * CheckHeader return value * @retval QZ_OK Function executed successfully * @retval QZ_FAIL Decompress stop, Fatal error * @retval QZ_FORCE_SW Decompress fallback sw * @retval QZ_BUF_ERROR Return to decompress API * @retval QZ_DATA_ERROR Return to decompress API */ int checkHeader(QzSess_T *qz_sess, unsigned char *src, unsigned int src_avail_len, unsigned int dest_avail_len, QzGzH_T *hdr) { unsigned char *src_ptr = src; unsigned int compressed_sz = 0; unsigned int uncompressed_sz = 0; StdGzF_T *qzFooter = NULL; int isEndWithFooter = 0; int ret = 0; QzLZ4H_T *qzLZ4Header = NULL; QzLZ4F_T *lz4Footer = NULL; DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; if ((src_avail_len <= 0) || (dest_avail_len <= 0)) { QZ_DEBUG("checkHeader: insufficient %s buffer length\n", (dest_avail_len <= 0) ? "destation" : "source"); return QZ_BUF_ERROR; } if (src_avail_len < outputHeaderSz(data_fmt)) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } if (1 == qz_sess->force_sw) { return QZ_FORCE_SW; } switch (data_fmt) { case DEFLATE_GZIP: qzFooter = (StdGzF_T *)(findStdGzipFooter(src_ptr, src_avail_len)); compressed_sz = (unsigned char *)qzFooter - src_ptr - stdGzipHeaderSz(); uncompressed_sz = qzFooter->i_size; if ((unsigned char *)qzFooter == src_ptr + src_avail_len - stdGzipFooterSz()) { isEndWithFooter = 1; } break; case DEFLATE_GZIP_EXT: if (QZ_OK != qzGzipHeaderExt(src_ptr, hdr)) { return QZ_FAIL; } compressed_sz = (long)(hdr->extra.qz_e.dest_sz); uncompressed_sz = (long)(hdr->extra.qz_e.src_sz); break; case DEFLATE_4B: compressed_sz = *(int *)src_ptr; uncompressed_sz = (qz_sess->sess_params.hw_buff_sz > dest_avail_len) ? dest_avail_len : qz_sess->sess_params.hw_buff_sz; break; case LZ4_FH: ret = qzVerifyLZ4FrameHeader(src_ptr, src_avail_len); if (ret != QZ_OK) { return ret; } lz4Footer = (QzLZ4F_T *)findLZ4Footer(src_ptr, src_avail_len); if (NULL == lz4Footer) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } qzLZ4Header = (QzLZ4H_T *)src_ptr; compressed_sz = (unsigned char *)lz4Footer - src_ptr - qzLZ4HeaderSz(); uncompressed_sz = qzLZ4Header->cnt_size; break; default: return QZ_FAIL; } if ((compressed_sz > DEST_SZ((long)(qz_sess->sess_params.hw_buff_sz))) || (uncompressed_sz > qz_sess->sess_params.hw_buff_sz)) { if (1 == qz_sess->sess_params.sw_backup) { if (DEFLATE_GZIP == data_fmt && 1 == isEndWithFooter) { return QZ_FORCE_SW; } qz_sess->force_sw = 1; return QZ_FORCE_SW; } else { return QZ_FAIL; } } if (compressed_sz + outputHeaderSz(data_fmt) + outputFooterSz(data_fmt) > src_avail_len) { QZ_DEBUG("checkHeader: incomplete source buffer\n"); return QZ_DATA_ERROR; } else if (uncompressed_sz > dest_avail_len) { QZ_DEBUG("checkHeader: insufficient destination buffer length\n"); return QZ_BUF_ERROR; } hdr->extra.qz_e.dest_sz = compressed_sz; hdr->extra.qz_e.src_sz = uncompressed_sz; return QZ_OK; } /* Below Buffer and respond process function is exact same means with * Compression */ void decompBufferSetup(int i, int j, QzSess_T *qz_sess, unsigned char *src_ptr, unsigned char *dest_ptr, unsigned int src_avail_len, QzGzH_T *hdr, unsigned int *tmp_src_avail_len, unsigned int *tmp_dest_avail_len) { StdGzF_T *qzFooter = NULL; QzLZ4F_T *lz4Footer = NULL; unsigned int src_send_sz = 0; unsigned int dest_receive_sz = 0; int src_mem_type = qzMemFindAddr(src_ptr); int dest_mem_type = qzMemFindAddr(dest_ptr); DataFormatInternal_T data_fmt = qz_sess->sess_params.data_fmt; CpaBoolean need_cont_mem = g_process.qz_inst[i].instance_info.requiresPhysicallyContiguousMemory; if (!need_cont_mem) { QZ_DEBUG("Decompress SVM Enabled in doDecompressIn\n"); } g_process.qz_inst[i].stream[j].seq = qz_sess->seq; g_process.qz_inst[i].stream[j].res.checksum = 0; swapDataBuffer(i, j); src_ptr += outputHeaderSz(data_fmt); src_send_sz = hdr->extra.qz_e.dest_sz; dest_receive_sz = hdr->extra.qz_e.src_sz; g_process.qz_inst[i].src_buffers[j]->pBuffers->dataLenInBytes = src_send_sz; g_process.qz_inst[i].dest_buffers[j]->pBuffers->dataLenInBytes = dest_receive_sz; QZ_DEBUG("doDecompressIn: Sending %u bytes starting at 0x%lx\n", src_send_sz, (unsigned long)src_ptr); QZ_DEBUG("sending seq number %lu %d %ld\n", i, j, qz_sess->seq); if (DEFLATE_GZIP_EXT == data_fmt || DEFLATE_GZIP == data_fmt) { qzFooter = (StdGzF_T *)(src_ptr + src_send_sz); g_process.qz_inst[i].stream[j].checksum = qzFooter->crc32; g_process.qz_inst[i].stream[j].orgdatalen = qzFooter->i_size; } else if (LZ4_FH == data_fmt) { lz4Footer = (QzLZ4F_T *)(src_ptr + src_send_sz); //TODO g_process.qz_inst[i].stream[j].checksum = lz4Footer->cnt_cksum; g_process.qz_inst[i].stream[j].orgdatalen = hdr->extra.qz_e.src_sz; } /*set up src dest buffers*/ if ((COMMON_MEM == src_mem_type) && need_cont_mem) { QZ_DEBUG("memory copy in doDecompressIn\n"); QZ_MEMCPY(g_process.qz_inst[i].src_buffers[j]->pBuffers->pData, src_ptr, src_avail_len, src_send_sz); g_process.qz_inst[i].stream[j].src_need_reset = 0; } else { g_process.qz_inst[i].src_buffers[j]->pBuffers->pData = src_ptr; g_process.qz_inst[i].stream[j].src_need_reset = 1; } if ((COMMON_MEM == dest_mem_type) && need_cont_mem) { g_process.qz_inst[i].stream[j].dest_need_reset = 0; } else { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = dest_ptr; g_process.qz_inst[i].stream[j].dest_need_reset = 1; } *tmp_src_avail_len = (outputHeaderSz(data_fmt) + src_send_sz + outputFooterSz( data_fmt)); *tmp_dest_avail_len = dest_receive_sz; } void decompInBufferCleanUp(int i, int j) { /*clean stream buffer*/ g_process.qz_inst[i].stream[j].src1 -= 1; g_process.qz_inst[i].stream[j].src2 -= 1; RestoreDestCpastreamBuffer(i, j); RestoreSrcCpastreamBuffer(i, j); swapDataBuffer(i, j); } void decompOutSrcBufferCleanUp(int i, int j) { RestoreSrcCpastreamBuffer(i, j); } void decompOutErrorDestBufferCleanUp(int i, int j) { RestoreDestCpastreamBuffer(i, j); } void decompOutValidDestBufferCleanUp(int i, int j, QzSess_T *qz_sess, CpaDcRqResults *resl, unsigned int dest_avail_len) { if (!g_process.qz_inst[i].stream[j].dest_need_reset) { QZ_DEBUG("memory copy in doDecompressOut\n"); QZ_MEMCPY(qz_sess->next_dest, g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData, dest_avail_len, resl->produced); } else { g_process.qz_inst[i].dest_buffers[j]->pBuffers->pData = g_process.qz_inst[i].stream[j].orig_dest; g_process.qz_inst[i].stream[j].dest_need_reset = 0; } } void decompOutProcessedRespond(int i, int j, QzSess_T *qz_sess) { decompOutSrcBufferCleanUp(i, j); swapDataBuffer(i, j); /*swap pdata back after decompress*/ assert(g_process.qz_inst[i].stream[j].seq == qz_sess->seq_in); g_process.qz_inst[i].stream[j].sink2++; qz_sess->seq_in++; qz_sess->processed++; } void decompOutSkipErrorRespond(int i, int j, QzSess_T *qz_sess) { decompOutErrorDestBufferCleanUp(i, j); decompOutProcessedRespond(i, j, qz_sess); } int decompOutCheckSum(int i, int j, QzSession_T *sess, CpaDcRqResults *resl) { QzSess_T *qz_sess = (QzSess_T *)sess->internal; if ((qz_sess->sess_params.data_fmt != DEFLATE_4B) && unlikely(resl->checksum != g_process.qz_inst[i].stream[j].checksum || resl->produced != g_process.qz_inst[i].stream[j].orgdatalen)) { QZ_ERROR("Error in check footer, inst %d, stream %d\n", i, j); QZ_DEBUG("resp checksum: %x data checksum %x\n", resl->checksum, g_process.qz_inst[i].stream[j].checksum); QZ_DEBUG("resp produced :%d data produced: %d\n", resl->produced, g_process.qz_inst[i].stream[j].orgdatalen); decompOutProcessedRespond(i, j, qz_sess); qz_sess->stop_submitting = 1; sess->thd_sess_stat = QZ_DATA_ERROR; return sess->thd_sess_stat; } return QZ_OK; } QATzip-1.2.1/src/xxhash.c000066400000000000000000001061731465165016500151420ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /*************************************************************************** * xxHash - Fast Hash algorithm * Copyright (C) 2012-2016, Yann Collet * * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You can contact the author at : * - xxHash homepage: http://www.xxhash.com * - xxHash source repository : https://github.com/Cyan4973/xxHash ***************************************************************************/ /* ************************************* * Tuning parameters ***************************************/ /*!XXH_FORCE_MEMORY_ACCESS : * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable. * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal. * The below switch allow to select different access method for improved performance. * Method 0 (default) : use `memcpy()`. Safe and portable. * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable). * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`. * Method 2 : direct access. This method doesn't depend on compiler but violate C standard. * It can generate buggy code on targets which do not support unaligned memory accesses. * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6) * See http://stackoverflow.com/a/32095106/646947 for details. * Prefer these methods in priority order (0 > 1 > 2) */ #ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */ # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) ) # define XXH_FORCE_MEMORY_ACCESS 2 # elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || \ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7S__) )) # define XXH_FORCE_MEMORY_ACCESS 1 # endif #endif /*!XXH_ACCEPT_NULL_INPUT_POINTER : * If input pointer is NULL, xxHash default behavior is to dereference it, triggering a segfault. * When this macro is enabled, xxHash actively checks input for null pointer. * It it is, result for null input pointers is the same as a null-length input. */ #ifndef XXH_ACCEPT_NULL_INPUT_POINTER /* can be defined externally */ # define XXH_ACCEPT_NULL_INPUT_POINTER 0 #endif /*!XXH_FORCE_NATIVE_FORMAT : * By default, xxHash library provides endian-independent Hash values, based on little-endian convention. * Results are therefore identical for little-endian and big-endian CPU. * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. * Should endian-independence be of no importance for your application, you may set the #define below to 1, * to improve speed for Big-endian CPU. * This option has no impact on Little_Endian CPU. */ #ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */ # define XXH_FORCE_NATIVE_FORMAT 0 #endif /*!XXH_FORCE_ALIGN_CHECK : * This is a minor performance trick, only useful with lots of very small keys. * It means : check for aligned/unaligned input. * The check costs one initial branch per hash; * set it to 0 when the input is guaranteed to be aligned, * or when alignment doesn't matter for performance. */ #ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */ # if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) # define XXH_FORCE_ALIGN_CHECK 0 # else # define XXH_FORCE_ALIGN_CHECK 1 # endif #endif /* ************************************* * Includes & Memory related functions ***************************************/ /*! Modify the local functions below should you wish to use some other memory routines * for malloc(), free() */ #include static void *XXH_malloc(size_t s) { return malloc(s); } static void XXH_free(void *p) { free(p); } /*! and for memcpy() */ #include static void *XXH_memcpy(void *dest, const void *src, size_t size) { return memcpy(dest, src, size); } #include /* assert */ #define XXH_STATIC_LINKING_ONLY #include "xxhash.h" /* ************************************* * Compiler Specific Options ***************************************/ #ifdef _MSC_VER /* Visual Studio */ # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # define FORCE_INLINE static __forceinline #else # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */ # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif # else # define FORCE_INLINE static # endif /* __STDC_VERSION__ */ #endif /* ************************************* * Basic Types ***************************************/ #ifndef MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; # else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U32 XXH_read32(const void *memPtr) { return *(const U32 *) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; } __attribute__((packed)) unalign; static U32 XXH_read32(const void *ptr) { return ((const unalign *)ptr)->u32; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U32 XXH_read32(const void *memPtr) { U32 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ /* **************************************** * Compiler-specific Functions and Macros ******************************************/ #define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) /* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */ #if defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) # define XXH_rotl64(x,r) _rotl64(x,r) #else # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) # define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r))) #endif #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap32 _byteswap_ulong #elif XXH_GCC_VERSION >= 403 # define XXH_swap32 __builtin_bswap32 #else static U32 XXH_swap32(U32 x) { return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff); } #endif /* ************************************* * Architecture Macros ***************************************/ typedef enum { XXH_bigEndian = 0, XXH_littleEndian = 1 } XXH_endianess; /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */ #ifndef XXH_CPU_LITTLE_ENDIAN static int XXH_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ return one.c[0]; } # define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian() #endif /* *************************** * Memory reads *****************************/ typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; FORCE_INLINE U32 XXH_readLE32_align(const void *ptr, XXH_endianess endian, XXH_alignment align) { if (align == XXH_unaligned) return endian == XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32( ptr)); else return endian == XXH_littleEndian ? *(const U32 *)ptr : XXH_swap32(* (const U32 *)ptr); } FORCE_INLINE U32 XXH_readLE32(const void *ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } static U32 XXH_readBE32(const void *ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr); } /* ************************************* * Macros ***************************************/ #define XXH_STATIC_ASSERT(c) { enum { XXH_sa = 1/(int)(!!(c)) }; } /* use after variable declarations */ XXH_PUBLIC_API unsigned XXH_versionNumber(void) { return XXH_VERSION_NUMBER; } /* ******************************************************************* * 32-bit hash functions *********************************************************************/ static const U32 PRIME32_1 = 2654435761U; static const U32 PRIME32_2 = 2246822519U; static const U32 PRIME32_3 = 3266489917U; static const U32 PRIME32_4 = 668265263U; static const U32 PRIME32_5 = 374761393U; static U32 XXH32_round(U32 seed, U32 input) { seed += input * PRIME32_2; seed = XXH_rotl32(seed, 13); seed *= PRIME32_1; return seed; } /* mix all bits */ static U32 XXH32_avalanche(U32 h32) { h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return (h32); } #define XXH_get32bits(p) XXH_readLE32_align(p, endian, align) static U32 XXH32_finalize(U32 h32, const void *ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)ptr; #define PROCESS1 \ h32 += (*p++) * PRIME32_5; \ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ; #define PROCESS4 \ h32 += XXH_get32bits(p) * PRIME32_3; \ p+=4; \ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; switch (len & 15) { /* or switch(bEnd - p) */ case 12: PROCESS4; /* fallthrough */ case 8: PROCESS4; /* fallthrough */ case 4: PROCESS4; return XXH32_avalanche(h32); case 13: PROCESS4; /* fallthrough */ case 9: PROCESS4; /* fallthrough */ case 5: PROCESS4; PROCESS1; return XXH32_avalanche(h32); case 14: PROCESS4; /* fallthrough */ case 10: PROCESS4; /* fallthrough */ case 6: PROCESS4; PROCESS1; PROCESS1; return XXH32_avalanche(h32); case 15: PROCESS4; /* fallthrough */ case 11: PROCESS4; /* fallthrough */ case 7: PROCESS4; /* fallthrough */ case 3: PROCESS1; /* fallthrough */ case 2: PROCESS1; /* fallthrough */ case 1: PROCESS1; /* fallthrough */ case 0: return XXH32_avalanche(h32); } assert(0); return h32; /* reaching this point is deemed impossible */ } FORCE_INLINE U32 XXH32_endian_align(const void *input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)input; const BYTE *bEnd = p + len; U32 h32; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p == NULL) { len = 0; bEnd = p = (const BYTE *)(size_t)16; } #endif if (len >= 16) { const BYTE *const limit = bEnd - 15; U32 v1 = seed + PRIME32_1 + PRIME32_2; U32 v2 = seed + PRIME32_2; U32 v3 = seed + 0; U32 v4 = seed - PRIME32_1; do { v1 = XXH32_round(v1, XXH_get32bits(p)); p += 4; v2 = XXH32_round(v2, XXH_get32bits(p)); p += 4; v3 = XXH32_round(v3, XXH_get32bits(p)); p += 4; v4 = XXH32_round(v4, XXH_get32bits(p)); p += 4; } while (p < limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (U32)len; return XXH32_finalize(h32, p, len & 15, endian, align); } XXH_PUBLIC_API unsigned int XXH32(const void *input, size_t len, unsigned int seed) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */ if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); } /*====== Hash streaming ======*/ XXH_PUBLIC_API XXH32_state_t *XXH32_createState(void) { return (XXH32_state_t *)XXH_malloc(sizeof(XXH32_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dstState, const XXH32_state_t *srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed) { XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME32_1 + PRIME32_2; state.v2 = seed + PRIME32_2; state.v3 = seed + 0; state.v4 = seed - PRIME32_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH32_update_endian(XXH32_state_t *state, const void *input, size_t len, XXH_endianess endian) { if (input == NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif { const BYTE *p = (const BYTE *)input; const BYTE *const bEnd = p + len; state->total_len_32 += (unsigned)len; state->large_len |= (len >= 16) | (state->total_len_32 >= 16); if (state->memsize + len < 16) { /* fill in tmp buffer */ XXH_memcpy((BYTE *)(state->mem32) + state->memsize, input, len); state->memsize += (unsigned)len; return XXH_OK; } if (state->memsize) { /* some data left from previous update */ XXH_memcpy((BYTE *)(state->mem32) + state->memsize, input, 16 - state->memsize); { const U32 *p32 = state->mem32; state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++; state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++; state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++; state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); } p += 16 - state->memsize; state->memsize = 0; } if (p <= bEnd - 16) { const BYTE *const limit = bEnd - 16; U32 v1 = state->v1; U32 v2 = state->v2; U32 v3 = state->v3; U32 v4 = state->v4; do { v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p += 4; v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p += 4; v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p += 4; v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p += 4; } while (p <= limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem32, p, (size_t)(bEnd - p)); state->memsize = (unsigned)(bEnd - p); } } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *state_in, const void *input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_update_endian(state_in, input, len, XXH_littleEndian); else return XXH32_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U32 XXH32_digest_endian(const XXH32_state_t *state, XXH_endianess endian) { U32 h32; if (state->large_len) { h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); } else { h32 = state->v3 /* == seed */ + PRIME32_5; } h32 += state->total_len_32; return XXH32_finalize(h32, state->mem32, state->memsize, endian, XXH_aligned); } XXH_PUBLIC_API unsigned int XXH32_digest(const XXH32_state_t *state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_digest_endian(state_in, XXH_littleEndian); else return XXH32_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ /*! Default XXH result types are basic unsigned 32 and 64 bits. * The canonical representation follows human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file or buffer, remaining comparable across different systems. */ XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src) { return XXH_readBE32(src); } #ifndef XXH_NO_LONG_LONG /* ******************************************************************* * 64-bit hash functions *********************************************************************/ /*====== Memory access ======*/ #ifndef MEM_MODULE # define MEM_MODULE # if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include typedef uint64_t U64; # else /* if compiler doesn't support unsigned long long, replace by another 64-bit type */ typedef unsigned long long U64; # endif #endif #if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2)) /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */ static U64 XXH_read64(const void *memPtr) { return *(const U64 *) memPtr; } #elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1)) /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */ /* currently only defined for gcc and icc */ typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign64; static U64 XXH_read64(const void *ptr) { return ((const unalign64 *)ptr)->u64; } #else /* portable and safe solution. Generally efficient. * see : http://stackoverflow.com/a/32095106/646947 */ static U64 XXH_read64(const void *memPtr) { U64 val; memcpy(&val, memPtr, sizeof(val)); return val; } #endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */ #if defined(_MSC_VER) /* Visual Studio */ # define XXH_swap64 _byteswap_uint64 #elif XXH_GCC_VERSION >= 403 # define XXH_swap64 __builtin_bswap64 #else static U64 XXH_swap64(U64 x) { return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); } #endif FORCE_INLINE U64 XXH_readLE64_align(const void *ptr, XXH_endianess endian, XXH_alignment align) { if (align == XXH_unaligned) return endian == XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64( ptr)); else return endian == XXH_littleEndian ? *(const U64 *)ptr : XXH_swap64(* (const U64 *)ptr); } FORCE_INLINE U64 XXH_readLE64(const void *ptr, XXH_endianess endian) { return XXH_readLE64_align(ptr, endian, XXH_unaligned); } static U64 XXH_readBE64(const void *ptr) { return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr); } /*====== xxh64 ======*/ static const U64 PRIME64_1 = 11400714785074694791ULL; static const U64 PRIME64_2 = 14029467366897019727ULL; static const U64 PRIME64_3 = 1609587929392839161ULL; static const U64 PRIME64_4 = 9650029242287828579ULL; static const U64 PRIME64_5 = 2870177450012600261ULL; static U64 XXH64_round(U64 acc, U64 input) { acc += input * PRIME64_2; acc = XXH_rotl64(acc, 31); acc *= PRIME64_1; return acc; } static U64 XXH64_mergeRound(U64 acc, U64 val) { val = XXH64_round(0, val); acc ^= val; acc = acc * PRIME64_1 + PRIME64_4; return acc; } static U64 XXH64_avalanche(U64 h64) { h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return h64; } #define XXH_get64bits(p) XXH_readLE64_align(p, endian, align) static U64 XXH64_finalize(U64 h64, const void *ptr, size_t len, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)ptr; #define PROCESS1_64 \ h64 ^= (*p++) * PRIME64_5; \ h64 = XXH_rotl64(h64, 11) * PRIME64_1; #define PROCESS4_64 \ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1; \ p+=4; \ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; #define PROCESS8_64 { \ U64 const k1 = XXH64_round(0, XXH_get64bits(p)); \ p+=8; \ h64 ^= k1; \ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4; \ } switch (len & 31) { case 24: PROCESS8_64; /* fallthrough */ case 16: PROCESS8_64; /* fallthrough */ case 8: PROCESS8_64; return XXH64_avalanche(h64); case 28: PROCESS8_64; /* fallthrough */ case 20: PROCESS8_64; /* fallthrough */ case 12: PROCESS8_64; /* fallthrough */ case 4: PROCESS4_64; return XXH64_avalanche(h64); case 25: PROCESS8_64; /* fallthrough */ case 17: PROCESS8_64; /* fallthrough */ case 9: PROCESS8_64; PROCESS1_64; return XXH64_avalanche(h64); case 29: PROCESS8_64; /* fallthrough */ case 21: PROCESS8_64; /* fallthrough */ case 13: PROCESS8_64; /* fallthrough */ case 5: PROCESS4_64; PROCESS1_64; return XXH64_avalanche(h64); case 26: PROCESS8_64; /* fallthrough */ case 18: PROCESS8_64; /* fallthrough */ case 10: PROCESS8_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 30: PROCESS8_64; /* fallthrough */ case 22: PROCESS8_64; /* fallthrough */ case 14: PROCESS8_64; /* fallthrough */ case 6: PROCESS4_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 27: PROCESS8_64; /* fallthrough */ case 19: PROCESS8_64; /* fallthrough */ case 11: PROCESS8_64; PROCESS1_64; PROCESS1_64; PROCESS1_64; return XXH64_avalanche(h64); case 31: PROCESS8_64; /* fallthrough */ case 23: PROCESS8_64; /* fallthrough */ case 15: PROCESS8_64; /* fallthrough */ case 7: PROCESS4_64; /* fallthrough */ case 3: PROCESS1_64; /* fallthrough */ case 2: PROCESS1_64; /* fallthrough */ case 1: PROCESS1_64; /* fallthrough */ case 0: return XXH64_avalanche(h64); } /* impossible to reach */ assert(0); return 0; /* unreachable, but some compilers complain without it */ } FORCE_INLINE U64 XXH64_endian_align(const void *input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align) { const BYTE *p = (const BYTE *)input; const BYTE *bEnd = p + len; U64 h64; #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) if (p == NULL) { len = 0; bEnd = p = (const BYTE *)(size_t)32; } #endif if (len >= 32) { const BYTE *const limit = bEnd - 32; U64 v1 = seed + PRIME64_1 + PRIME64_2; U64 v2 = seed + PRIME64_2; U64 v3 = seed + 0; U64 v4 = seed - PRIME64_1; do { v1 = XXH64_round(v1, XXH_get64bits(p)); p += 8; v2 = XXH64_round(v2, XXH_get64bits(p)); p += 8; v3 = XXH64_round(v3, XXH_get64bits(p)); p += 8; v4 = XXH64_round(v4, XXH_get64bits(p)); p += 8; } while (p <= limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = seed + PRIME64_5; } h64 += (U64) len; return XXH64_finalize(h64, p, len, endian, align); } XXH_PUBLIC_API unsigned long long XXH64(const void *input, size_t len, unsigned long long seed) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if (XXH_FORCE_ALIGN_CHECK) { if ((((size_t)input) & 7) == 0) { /* Input is aligned, let's leverage the speed advantage */ if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } } if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); } /*====== Hash Streaming ======*/ XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void) { return (XXH64_state_t *)XXH_malloc(sizeof(XXH64_state_t)); } XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr) { XXH_free(statePtr); return XXH_OK; } XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dstState, const XXH64_state_t *srcState) { memcpy(dstState, srcState, sizeof(*dstState)); } XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed) { XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */ memset(&state, 0, sizeof(state)); state.v1 = seed + PRIME64_1 + PRIME64_2; state.v2 = seed + PRIME64_2; state.v3 = seed + 0; state.v4 = seed - PRIME64_1; /* do not write into reserved, planned to be removed in a future version */ memcpy(statePtr, &state, sizeof(state) - sizeof(state.reserved)); return XXH_OK; } FORCE_INLINE XXH_errorcode XXH64_update_endian(XXH64_state_t *state, const void *input, size_t len, XXH_endianess endian) { if (input == NULL) #if defined(XXH_ACCEPT_NULL_INPUT_POINTER) && (XXH_ACCEPT_NULL_INPUT_POINTER>=1) return XXH_OK; #else return XXH_ERROR; #endif { const BYTE *p = (const BYTE *)input; const BYTE *const bEnd = p + len; state->total_len += len; if (state->memsize + len < 32) { /* fill in tmp buffer */ XXH_memcpy(((BYTE *)state->mem64) + state->memsize, input, len); state->memsize += (U32)len; return XXH_OK; } if (state->memsize) { /* tmp buffer is full */ XXH_memcpy(((BYTE *)state->mem64) + state->memsize, input, 32 - state->memsize); state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64 + 0, endian)); state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64 + 1, endian)); state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64 + 2, endian)); state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64 + 3, endian)); p += 32 - state->memsize; state->memsize = 0; } if (p + 32 <= bEnd) { const BYTE *const limit = bEnd - 32; U64 v1 = state->v1; U64 v2 = state->v2; U64 v3 = state->v3; U64 v4 = state->v4; do { v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p += 8; v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p += 8; v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p += 8; v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p += 8; } while (p <= limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->mem64, p, (size_t)(bEnd - p)); state->memsize = (unsigned)(bEnd - p); } } return XXH_OK; } XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *state_in, const void *input, size_t len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_update_endian(state_in, input, len, XXH_littleEndian); else return XXH64_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U64 XXH64_digest_endian(const XXH64_state_t *state, XXH_endianess endian) { U64 h64; if (state->total_len >= 32) { U64 const v1 = state->v1; U64 const v2 = state->v2; U64 const v3 = state->v3; U64 const v4 = state->v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = state->v3 /*seed*/ + PRIME64_5; } h64 += (U64) state->total_len; return XXH64_finalize(h64, state->mem64, (size_t)state->total_len, endian, XXH_aligned); } XXH_PUBLIC_API unsigned long long XXH64_digest(const XXH64_state_t *state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected == XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH64_digest_endian(state_in, XXH_littleEndian); else return XXH64_digest_endian(state_in, XXH_bigEndian); } /*====== Canonical representation ======*/ XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash) { XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t)); if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash); memcpy(dst, &hash, sizeof(*dst)); } XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src) { return XXH_readBE64(src); } #endif /* XXH_NO_LONG_LONG */ QATzip-1.2.1/src/xxhash.h000066400000000000000000000342101465165016500151370ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /*************************************************************************** * xxHash - Fast Hash algorithm * Copyright (C) 2012-2016, Yann Collet * * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You can contact the author at : * - xxHash homepage: http://www.xxhash.com * - xxHash source repository : https://github.com/Cyan4973/xxHash ***************************************************************************/ #ifndef XXHASH_H_5627135585666179 #define XXHASH_H_5627135585666179 1 #if defined (__cplusplus) extern "C" { #endif /* **************************** * Definitions ******************************/ #include /* size_t */ typedef enum { XXH_OK = 0, XXH_ERROR } XXH_errorcode; /* **************************** * API modifier ******************************/ /** XXH_INLINE_ALL (and XXH_PRIVATE_API) * This is useful to include xxhash functions in `static` mode * in order to inline them, and remove their symbol from the public list. * Inlining can offer dramatic performance improvement on small keys. * Methodology : * #define XXH_INLINE_ALL * #include "xxhash.h" * `xxhash.c` is automatically included. * It's not useful to compile and link it as a separate module. */ #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # ifndef XXH_STATIC_LINKING_ONLY # define XXH_STATIC_LINKING_ONLY # endif # if defined(__GNUC__) # define XXH_PUBLIC_API static __inline __attribute__((unused)) # elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) # define XXH_PUBLIC_API static inline # elif defined(_MSC_VER) # define XXH_PUBLIC_API static __inline # else /* this version may generate warnings for unused static functions */ # define XXH_PUBLIC_API static # endif #else # define XXH_PUBLIC_API /* do nothing */ #endif /* XXH_INLINE_ALL || XXH_PRIVATE_API */ /*! XXH_NAMESPACE, aka Namespace Emulation : * * If you want to include _and expose_ xxHash functions from within your own library, * but also want to avoid symbol collisions with other libraries which may also include xxHash, * * you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library * with the value of XXH_NAMESPACE (therefore, avoid NULL and numeric values). * * Note that no change is required within the calling program as long as it includes `xxhash.h` : * regular symbol name will be automatically translated by this header. */ #ifdef XXH_NAMESPACE # define XXH_CAT(A,B) A##B # define XXH_NAME2(A,B) XXH_CAT(A,B) # define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber) # define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32) # define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState) # define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState) # define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset) # define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update) # define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest) # define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState) # define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash) # define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical) # define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64) # define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState) # define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState) # define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset) # define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update) # define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest) # define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState) # define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash) # define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical) #endif /* ************************************* * Version ***************************************/ #define XXH_VERSION_MAJOR 0 #define XXH_VERSION_MINOR 6 #define XXH_VERSION_RELEASE 5 #define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE) XXH_PUBLIC_API unsigned XXH_versionNumber(void); /*-********************************************************************** * 32-bit hash ************************************************************************/ typedef unsigned int XXH32_hash_t; /*! XXH32() : Calculate the 32-bit hash of sequence "length" bytes stored at memory address "input". The memory between input & input+length must be valid (allocated and read-accessible). "seed" can be used to alter the result predictably. Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s */ XXH_PUBLIC_API XXH32_hash_t XXH32(const void *input, size_t length, unsigned int seed); /*====== Streaming ======*/ typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */ XXH_PUBLIC_API XXH32_state_t *XXH32_createState(void); XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t *statePtr); XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t *dst_state, const XXH32_state_t *src_state); XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned int seed); XXH_PUBLIC_API XXH_errorcode XXH32_update(XXH32_state_t *statePtr, const void *input, size_t length); XXH_PUBLIC_API XXH32_hash_t XXH32_digest(const XXH32_state_t *statePtr); /* * Streaming functions generate the xxHash of an input provided in multiple segments. * Note that, for small input, they are slower than single-call functions, due to state management. * For small inputs, prefer `XXH32()` and `XXH64()`, which are better optimized. * * XXH state must first be allocated, using XXH*_createState() . * * Start a new hash by initializing state with a seed, using XXH*_reset(). * * Then, feed the hash state by calling XXH*_update() as many times as necessary. * The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. * * Finally, a hash value can be produced anytime, by using XXH*_digest(). * This function returns the nn-bits hash as an int or long long. * * It's still possible to continue inserting input into the hash state after a digest, * and generate some new hashes later on, by calling again XXH*_digest(). * * When done, free XXH state space if it was allocated dynamically. */ /*====== Canonical representation ======*/ typedef struct { unsigned char digest[4]; } XXH32_canonical_t; XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t *dst, XXH32_hash_t hash); XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t *src); /* Default result type for XXH functions are primitive unsigned 32 and 64 bits. * The canonical representation uses human-readable write convention, aka big-endian (large digits first). * These functions allow transformation of hash result into and from its canonical format. * This way, hash values can be written into a file / memory, and remain comparable on different systems and programs. */ #ifndef XXH_NO_LONG_LONG /*-********************************************************************** * 64-bit hash ************************************************************************/ typedef unsigned long long XXH64_hash_t; /*! XXH64() : Calculate the 64-bit hash of sequence of length "len" stored at memory address "input". "seed" can be used to alter the result predictably. This function runs faster on 64-bit systems, but slower on 32-bit systems (see benchmark). */ XXH_PUBLIC_API XXH64_hash_t XXH64(const void *input, size_t length, unsigned long long seed); /*====== Streaming ======*/ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */ XXH_PUBLIC_API XXH64_state_t *XXH64_createState(void); XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t *statePtr); XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t *dst_state, const XXH64_state_t *src_state); XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t *statePtr, unsigned long long seed); XXH_PUBLIC_API XXH_errorcode XXH64_update(XXH64_state_t *statePtr, const void *input, size_t length); XXH_PUBLIC_API XXH64_hash_t XXH64_digest(const XXH64_state_t *statePtr); /*====== Canonical representation ======*/ typedef struct { unsigned char digest[8]; } XXH64_canonical_t; XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t *dst, XXH64_hash_t hash); XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t *src); #endif /* XXH_NO_LONG_LONG */ #ifdef XXH_STATIC_LINKING_ONLY /* ================================================================================================ This section contains declarations which are not guaranteed to remain stable. They may change in future versions, becoming incompatible with a different version of the library. These declarations should only be used with static linking. Never use them in association with dynamic linking ! =================================================================================================== */ /* These definitions are only present to allow * static allocation of XXH state, on stack or in a struct for example. * Never **ever** use members directly. */ #if !defined (__VMS) \ && (defined (__cplusplus) \ || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) ) # include struct XXH32_state_s { uint32_t total_len_32; uint32_t large_len; uint32_t v1; uint32_t v2; uint32_t v3; uint32_t v4; uint32_t mem32[4]; uint32_t memsize; uint32_t reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ struct XXH64_state_s { uint64_t total_len; uint64_t v1; uint64_t v2; uint64_t v3; uint64_t v4; uint64_t mem64[4]; uint32_t memsize; uint32_t reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # else struct XXH32_state_s { unsigned total_len_32; unsigned large_len; unsigned v1; unsigned v2; unsigned v3; unsigned v4; unsigned mem32[4]; unsigned memsize; unsigned reserved; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH32_state_t */ # ifndef XXH_NO_LONG_LONG /* remove 64-bit support */ struct XXH64_state_s { unsigned long long total_len; unsigned long long v1; unsigned long long v2; unsigned long long v3; unsigned long long v4; unsigned long long mem64[4]; unsigned memsize; unsigned reserved[2]; /* never read nor write, might be removed in a future version */ }; /* typedef'd to XXH64_state_t */ # endif # endif #if defined(XXH_INLINE_ALL) || defined(XXH_PRIVATE_API) # include "xxhash.c" /* include xxhash function bodies as `static`, for inlining */ #endif #endif /* XXH_STATIC_LINKING_ONLY */ #if defined (__cplusplus) } #endif #endif /* XXHASH_H_5627135585666179 */ QATzip-1.2.1/test/000077500000000000000000000000001465165016500136535ustar00rootroot00000000000000QATzip-1.2.1/test/Makefile.am000066400000000000000000000051531465165016500157130ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ noinst_PROGRAMS = bt bin_PROGRAMS = qatzip-test qatzip_test_SOURCES = main.c qatzip_test_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qatzip_test_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) qatzip_test_LDFLAGS = \ $(ICP_LDFLAGS) bt_SOURCES = bt.c bt_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) bt_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) bt_LDFLAGS = \ $(ICP_LDFLAGS) QATzip-1.2.1/test/bt.c000077500000000000000000000136631465165016500144400ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include "qatzip.h" #define DEFAULT_BUF_LEN (256*1024) void usage() { printf("-f fit decompress buffers to size (default full buffers)\n"); printf("-s skip specific number of bytes\n"); printf("-S start test at specific position of source buffer\n"); printf("-E finish test at specific position of source buffer\n"); printf("-c corpus flag for data in source buffer: 0 - iterative, 1 - random, 2 - 'A'\n"); return; } int main(int argc, char *argv[]) { unsigned int i, j, rc, d_len, s_len, s2_len, src_sz, dest_sz; unsigned char *src, *dest, *src2; QzSession_T sess = {0}; int c; int fit = 0; int start = 1; int skip = 1; int end = DEFAULT_BUF_LEN; int corpus = 0; // 0 = iterative, 1 = random srand((time(NULL) & 0xffffffff)); while ((c = getopt(argc, argv, "fS:s:E:c:")) != -1) { switch (c) { case 'f': fit = 1; break; case 's': skip = atoi(optarg); if (skip <= 1) { usage(); return -1; } printf("Will skip by %d\n", skip); break; case 'S': start = atoi(optarg); printf("Will start at %d\n", start); break; case 'E': end = atoi(optarg); printf("Will end at %d\n", end); break; case 'c': corpus = atoi(optarg); printf("corpus = "); if (corpus == 0) { printf("iterative\n"); } else if (corpus == 1) { printf("randon\n"); } if (corpus == 2) { printf("\"A\"\n"); } break; default: usage(); return -1; } } src_sz = DEFAULT_BUF_LEN; dest_sz = (9 * src_sz / 8) + 1024; src = qzMalloc(src_sz, 0, 1); dest = qzMalloc(dest_sz, 0, 1); src2 = qzMalloc(src_sz, 0, 1); if (NULL == src || NULL == dest || NULL == src2) { return -1; } i = DEFAULT_BUF_LEN; if (corpus == 0) { for (j = 0; j < i; j++) { src[j] = (char)(j % 200); } } else if (corpus == 1) { for (j = 0; j < i; j++) { src[j] = (char)rand() % 255; } } else { for (j = 0; j < i; j++) { src[j] = (char)'A'; } } printf("src = 0x%lx, src2 = 0x%lx, dest = 0x%lx\n", (long unsigned int)src, (long unsigned int)src2, (long unsigned int)dest); printf("fit = %d\n", fit); for (i = start; i < end; i += skip) { s_len = i; d_len = dest_sz; rc = qzCompress(&sess, src, &s_len, dest, &d_len, 1); // printf( "rc = %d, src = %d, dest = %d\n", // rc, s_len, d_len ); if (rc == 0) { if (1 == fit) { s2_len = s_len; } else { s2_len = DEFAULT_BUF_LEN; } rc = qzDecompress(&sess, dest, &d_len, src2, &s2_len); // printf( "rc2 = %d, src = %d, dest = %d\n", // rc2, d_len, s2_len ); if (rc == 0) { if (s2_len != s_len) { printf("mismatch orig\t%d\tcomp %d\tdec %d\t %d\n", s_len, d_len, s2_len, (s_len - s2_len)); printf("\t\t%d\t%d\t%d\n", (s_len % (64 * 1024)), (d_len % (64 * 1024)), (s2_len % (64 * 1024))); goto error; } if (memcmp(src, src2, s_len) != 0) { printf("memcmp mismatch - len = %d\t%d\n", s_len, (s_len % (64 * 1024))); goto error; } } else { printf("return from decomress is %d\t len = %d\t%d\n", rc, s_len, (s_len % (64 * 1024))); goto error; } } else { goto error; } } return 0; error: qzTeardownSession(&sess); qzFree(src); qzFree(dest); qzFree(src2); return rc; } QATzip-1.2.1/test/code_format_tests/000077500000000000000000000000001465165016500173575ustar00rootroot00000000000000QATzip-1.2.1/test/code_format_tests/astylerc000066400000000000000000000045661465165016500211430ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # Bracket Style style=kr --keep-one-line-blocks # K&R brackets # Indentation indent=spaces # 4 white space min-conditional-indent=0 # Padding unpad-paren # Remove all spaces with parens that aren't requested below pad-oper # Put spaces around operators pad-header # Put spaces between if/while/for etc. and the first paren # Pointers align-pointer=name # Align the * next to the variable name # Line wrapping max-code-length=80 # 80 character line limit break-after-logical # For if statements, wrap to the next line after logical operator # Line endings lineend=linux # LF line endings # General options suffix=none formatted QATzip-1.2.1/test/code_format_tests/format.sh000077500000000000000000000047271465165016500212200ustar00rootroot00000000000000#!/usr/bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ # exit on errors set -e : ${QZ_ROOT?} readonly BASEDIR=$(readlink -f $(dirname $0)) declare -i rc=0 rm -f $BASEDIR/astyle.log if hash astyle; then echo -n "Checking coding style..." find $QZ_ROOT -iregex '.*\.[ch]' | \ xargs astyle --options=$BASEDIR/astylerc | \ tee -a $BASEDIR/astyle.log if grep -q "^Formatted" $BASEDIR/astyle.log; then echo -e "ERRORS detected\n" grep --color=auto "^Formatted.*" $BASEDIR/astyle.log echo "Incorrect code style detected in one or more files." echo "The files have been automatically formatted." rc=1 else echo " OK" fi else echo "You do not have astyle installed so your code style is not being checked!" rc=2 fi exit $rc QATzip-1.2.1/test/main.c000077500000000000000000004240051465165016500147530ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #define _POSIX_C_SOURCE 200112L #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include #include #include #include /* QAT headers */ #ifdef HAVE_QAT_HEADERS #include #include #include #else #include #include #include #endif #include #include #include #include #define QZ_FMT_NAME "QZ" #define GZIP_FMT_NAME "GZIP" #define MAX_FMT_NAME 8 #define MAX_NUMA_NODE 8 #define ARRAY_LEN(arr) (sizeof(arr) / sizeof((arr)[0])) #define KB (1024) #define MB (KB * KB) /* According to different platforms, * instance total = instance on each device * num of device */ #define G_PROCESS_NUM_INSTANCES_4 4 /* instance=4 * device=1 */ #define G_PROCESS_NUM_INSTANCES_8 8 /* instance=1 * device=8 */ #define G_PROCESS_NUM_INSTANCES_12 12 /* instance=4 * device=3 */ #define G_PROCESS_NUM_INSTANCES_16 16 /* instance=4 * device=4 */ #define G_PROCESS_NUM_INSTANCES_32 32 /* instance=4 * device=8 */ #define G_PROCESS_NUM_INSTANCES_64 64 /* instance=4 * device=16 */ #define MAX_HUGEPAGE_FILE "/sys/module/usdm_drv/parameters/max_huge_pages" #define QZ_INIT_HW_FAIL(rc) (QZ_DUPLICATE != rc && \ (QZ_OK != rc || \ QZ_NO_HW == g_process.qz_init_status)) #if CPA_DC_API_VERSION_AT_LEAST(3, 1) #define COMP_LVL_MAXIMUM QZ_LZS_COMP_LVL_MAXIMUM #else #define COMP_LVL_MAXIMUM QZ_DEFLATE_COMP_LVL_MAXIMUM #endif typedef void *(QzThdOps)(void *); typedef enum { UNKNOWN, QZ, GZIP, FMT_NUM } QzFormatId_T; typedef struct QzFormat_S { char fmt_name[MAX_FMT_NAME]; QzFormatId_T fmt; } QzFormat_T; QzFormat_T g_format_list[] = { {QZ_FMT_NAME, QZ}, {GZIP_FMT_NAME, GZIP} }; typedef struct QzBlock_S { QzFormatId_T fmt; unsigned int size; struct QzBlock_S *next; } QzBlock_T; typedef enum { COMP = 0, DECOMP, BOTH } ServiceType_T; typedef enum { TEST_DEFLATE = 0, TEST_GZIP, TEST_GZIPEXT, TEST_DEFLATE_4B, TEST_LZ4, TEST_LZ4S } TEST_FORMAT_T; typedef struct CPUCore_S { int seq; int used; } CPUCore_T; typedef struct NUMANode_S { int num_cores; CPUCore_T *core; } NUMANode_T; typedef struct { long thd_id; ServiceType_T service; int count; int verify_data; int debug; size_t src_sz; size_t comp_out_sz; size_t decomp_out_sz; int max_forks; unsigned char *src; unsigned char *comp_out; unsigned char *decomp_out; int gen_data; int comp_algorithm; int sw_backup; int hw_buff_sz; int comp_lvl; int req_cnt_thrshold; int huffman_hdr; QzPollingMode_T polling_mode; TEST_FORMAT_T test_format; QzThdOps *ops; QzBlock_T *blks; int init_engine_disabled; int init_sess_disabled; int thread_sleep; int block_size; } TestArg_T; const unsigned int USDM_ALLOC_MAX_SZ = (2 * MB - 5 * KB); const unsigned int DEFAULT_STREAM_BUF_SZ = 256 * KB; const unsigned int QATZIP_MAX_HW_SZ = 512 * KB; const unsigned int MAX_HUGE_PAGE_SZ = 2 * MB; static pthread_mutex_t g_lock_print = PTHREAD_MUTEX_INITIALIZER; #ifndef ENABLE_THREAD_BARRIER static pthread_mutex_t g_cond_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t g_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t g_start_cond = PTHREAD_COND_INITIALIZER; static int g_ready_to_start; static int g_ready_thread_count; #else static pthread_barrier_t g_bar; #endif char *g_input_file_name = NULL; static bool g_perf_svm = false; static struct timeval g_timers[100][100]; static struct timeval g_timer_start; extern void dumpAllCounters(); static int test_thread_safe_flag = 0; extern processData_T g_process; extern int errno; QzBlock_T *parseFormatOption(char *buf) { char *str = buf, *sub_str = NULL; char *delim = "/", *sub_delim = ":"; char *token, *sub_token; char *saveptr, *sub_saveptr; int i, j, fmt_idx; unsigned int fmt_found = 0; QzBlock_T *blk = NULL; QzBlock_T *head, *prev, *r; unsigned int list_len = sizeof(g_format_list) / sizeof(QzFormat_T); head = malloc(sizeof(QzBlock_T)); assert(NULL != head); head->next = NULL; prev = head; for (i = 1; ; i++, str = NULL) { token = strtok_r(str, delim, &saveptr); if (NULL == token) { break; } QZ_DEBUG("String[%d]: %s\n", i, token); fmt_found = 0; blk = NULL; for (j = 1, sub_str = token; ; j++, sub_str = NULL) { sub_token = strtok_r(sub_str, sub_delim, &sub_saveptr); if (NULL == sub_token) { break; } QZ_DEBUG(" -[%d]-> %s\n", j, sub_token); if (fmt_found) { blk->size = atoi(sub_token); break; } char *tmp = sub_token; while (*tmp) { *tmp = GET_LOWER_8BITS(toupper(*tmp)); tmp++; } for (fmt_idx = 0; fmt_idx < list_len; fmt_idx++) { if (0 == strcmp(sub_token, g_format_list[fmt_idx].fmt_name)) { blk = malloc(sizeof(QzBlock_T)); assert(NULL != blk); blk->fmt = g_format_list[fmt_idx].fmt; blk->next = NULL; prev->next = blk; fmt_found = 1; break; } } } if (NULL != blk) { prev = blk; } } blk = head->next; i = 1; while (blk) { QZ_PRINT("[INFO] Block%d: format -%8s, \tsize - %d\n", i++, g_format_list[blk->fmt - 1].fmt_name, blk->size); blk = blk->next; } if (NULL == head->next) { r = head->next; free(head); } else { r = head; } return r; } static void genRandomData(uint8_t *data, size_t size) { size_t i, j; char c; uint8_t *ptr = data; while (ptr < (data + size)) { j = rand() % 100; c = GET_LOWER_8BITS((rand() % 65 + 90)); for (i = (size_t)0; i < j; i++) { *ptr = c; ptr++; if (ptr >= (data + size)) { break; } } } } static void sigInt(int sig) { dumpAllCounters(); _exit(1); } static void timeCheck(int i, long tid) { gettimeofday(&g_timers[i][tid], NULL); } #ifdef TESTMAIN_DUMP_TIMERS static void dumpTimers(int tid) { int i; unsigned long long start, local, diff; start = (g_timer_start.tv_sec * 1000000) + g_timer_start.tv_usec; if (0 == tid) { QZ_PRINT("[ts]: %lld\n", start); } QZ_PRINT("[%5.5d]", tid); for (i = 0; i < 15; i++) { local = (g_timers[i][tid].tv_sec * 1000000) + g_timers[i][tid].tv_usec; if (local > 0) { diff = local - start; QZ_PRINT(" %lld", diff); } else { QZ_PRINT(" -"); } } QZ_PRINT("\n"); } #endif static void dumpInputData(size_t size, uint8_t *data) { int fd; ssize_t ulen; char temp_file[] = "QATZip_Input_XXXXXX"; if (0 == size || NULL == data) return; fd = mkstemp(temp_file); if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); return; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); return; } close(fd); } static void dumpOutputData(size_t size, uint8_t *data, char *filename) { int fd = 0; ssize_t ulen; char *output_filename = NULL; char tmp_filename[] = "QATZip_Output_XXXXXX.gz"; const unsigned int suffix_len = 3; if (0 == size || NULL == data) return; if (NULL == filename) { output_filename = tmp_filename; } else { output_filename = filename; } if (NULL == filename) { fd = mkstemps(output_filename, suffix_len); } else { fd = open(output_filename, O_RDWR | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); } if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); goto done; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); goto done; } done: if (fd >= 0) { close(fd); } } static void dumpDecompressedData(size_t size, uint8_t *data, char *filename) { int fd = 0; ssize_t ulen; char *filename_ptr = NULL; char *output_filename = NULL; unsigned int filename_len = 0; const char *suffix = ".decomp"; const unsigned int suffix_len = strlen(suffix); if (0 == size || NULL == data || NULL == filename) return; filename_len = strlen(filename); filename_ptr = filename; filename_len = (filename_len + suffix_len + 1 + 7) / 8 * 8; output_filename = (char *) calloc(1, filename_len); if (NULL == output_filename) { QZ_ERROR("Creat dump file Failed\n"); goto done; } snprintf(output_filename, filename_len, "%s%s", filename_ptr, suffix); fd = open(output_filename, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IRGRP | S_IROTH); if (-1 == fd) { QZ_ERROR("Creat dump file Failed\n"); goto done; } ulen = write(fd, data, size); if (ulen != (ssize_t) size) { QZ_ERROR("Creat dump file Failed\n"); goto done; } done: free(output_filename); if (fd >= 0) { close(fd); } } int qzSetupDeflate(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsDeflate_T params; status = qzGetDefaultsDeflate(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } switch (arg->test_format) { case TEST_DEFLATE: params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIP: params.data_fmt = QZ_DEFLATE_GZIP; break; case TEST_GZIPEXT: params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case TEST_DEFLATE_4B: params.data_fmt = QZ_DEFLATE_4B; break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } params.huffman_hdr = arg->huffman_hdr; params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; status = qzSetupSessionDeflate(sess, ¶ms); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzSetupLZ4(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsLZ4_T params; status = qzGetDefaultsLZ4(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; status = qzSetupSessionLZ4(sess, ¶ms); if (status) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzSetupLZ4S(QzSession_T *sess, TestArg_T *arg) { int status; QzSessionParamsLZ4S_T params; status = qzGetDefaultsLZ4S(¶ms); if (status < 0) { QZ_ERROR("Get defaults params error with error: %d\n", status); return QZ_FAIL; } params.common_params.comp_lvl = arg->comp_lvl; params.common_params.comp_algorithm = arg->comp_algorithm; params.common_params.hw_buff_sz = arg->hw_buff_sz; params.common_params.polling_mode = arg->polling_mode; params.common_params.req_cnt_thrshold = arg->req_cnt_thrshold; params.common_params.max_forks = arg->max_forks; params.common_params.sw_backup = arg->sw_backup; status = qzSetupSessionLZ4S(sess, ¶ms); if (status) { QZ_ERROR("Session setup failed with error: %d\n", status); return QZ_FAIL; } return QZ_OK; } int qzInitSetupsession(QzSession_T *sess, TestArg_T *arg) { int rc = QZ_OK; if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(sess, arg->sw_backup); if (QZ_INIT_FAIL(rc)) { return rc; } } if (!((TestArg_T *)arg)->init_sess_disabled) { switch (arg->test_format) { case TEST_DEFLATE: case TEST_GZIP: case TEST_GZIPEXT: rc = qzSetupDeflate(sess, arg); break; case TEST_LZ4: rc = qzSetupLZ4(sess, arg); break; case TEST_LZ4S: rc = qzSetupLZ4S(sess, arg); break; default: QZ_ERROR("Unsupported data format\n"); return QZ_FAIL; } if (QZ_SETUP_SESSION_FAIL(rc)) { return rc; } } return rc; } void *qzDecompressSwQz(void *arg) { int rc, k; unsigned char *src = NULL, *comp_out = NULL; unsigned char *decomp_sw_out = NULL, *decomp_qz_out = NULL; size_t src_sz, comp_out_sz, decomp_sw_out_sz, decomp_qz_out_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = 1; const int count = ((TestArg_T *)arg)->count; QzSession_T sess = {0}; QzSessionParams_T cus_params = {0}; if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_sw_out_sz = org_src_sz; decomp_qz_out_sz = org_src_sz; QZ_DEBUG("Hello from qzDecompressSwQz tid=%ld, count=%d, service=2, " "verify_data=%d\n", tid, count, verify_data); src = qzMalloc(src_sz, 0, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, 0, PINNED_MEM); decomp_sw_out = qzMalloc(decomp_sw_out_sz, 0, PINNED_MEM); decomp_qz_out = qzMalloc(decomp_qz_out_sz, 0, PINNED_MEM); if (!src || !comp_out || !decomp_sw_out || !decomp_qz_out) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); comp_out_sz = org_src_sz; //Compress 1st { //Set default hwBufferSize to 64KB cus_params.hw_buff_sz = 64 * 1024; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); unsigned int last = 0; rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), comp_out, (uint32_t *)(&comp_out_sz), last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); qzTeardownSession(&sess); } //Decompress SW { cus_params.hw_buff_sz = 32 * 1024; //32KB if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %u.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_sw_out_sz); qzSetupSession(&sess, NULL); unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); rc = qzDecompress(&sess, comp_out, (uint32_t *)(&tmp_comp_out_sz), decomp_sw_out, (uint32_t *)(&decomp_sw_out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } if (decomp_sw_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu\n!", decomp_sw_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after SW Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_sw_out_sz); qzTeardownSession(&sess); } //Decompress QAT { //Reset default hwBufferSize to 64KB cus_params.hw_buff_sz = 64 * 1024; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect hw_buff_sz %u.\n", cus_params.hw_buff_sz); goto done; } QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_qz_out_sz); qzSetupSession(&sess, NULL); unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); rc = qzDecompress(&sess, comp_out, (uint32_t *)&tmp_comp_out_sz, decomp_qz_out, (uint32_t *)(&decomp_qz_out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } if (decomp_qz_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_qz_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after QZ Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_qz_out_sz); qzTeardownSession(&sess); } (void)gettimeofday(&te, NULL); { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_sw_out, org_src_sz)) { QZ_ERROR("ERROR: SW Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } if (memcmp(src, decomp_qz_out, org_src_sz)) { QZ_ERROR("ERROR: QZip Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_sw_out, 0, decomp_sw_out_sz); memset(decomp_qz_out, 0, decomp_qz_out_sz); } ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz * 8;// bits rate *= 2; rate /= 1024; rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps rc = pthread_mutex_lock(&g_lock_print); assert(0 == rc); QZ_PRINT("[INFO] srv=BOTH, tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); QZ_PRINT(", comp_len=%lu, sw_decomp_len=%lu", comp_out_sz, decomp_sw_out_sz); QZ_PRINT(", comp_len=%lu, qz_decomp_len=%lu", comp_out_sz, decomp_qz_out_sz); QZ_PRINT("\n"); rc = pthread_mutex_unlock(&g_lock_print); assert(0 == rc); done: qzFree(src); qzFree(comp_out); qzFree(decomp_sw_out); qzFree(decomp_qz_out); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressDecompressWithFormatOption(void *arg) { int rc = 0, k; unsigned char *src, *comp_out, *decomp_out; size_t src_sz, comp_out_sz, decomp_out_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const int verify_data = 1; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; QzBlock_T *head, *blk; QzSession_T sess = {0}; if (!org_src_sz) { pthread_exit((void *)"input size is 0"); } head = ((TestArg_T *)arg)->blks; if (head == NULL) { pthread_exit((void *)"No Input -F options or phrase options failed\n"); } blk = head->next; if (blk == NULL) { pthread_exit((void *)"No Input -F options or phrase options failed\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzCompressDecompressWithFormatOption tid=%ld, count=%d, service=2, " "verify_data=%d\n", tid, count, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (gen_data) { src = qzMalloc(src_sz, 0, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, 0, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, 0, PINNED_MEM); } else { src = ((TestArg_T *)arg)->src; comp_out = ((TestArg_T *)arg)->comp_out; decomp_out = ((TestArg_T *)arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); //Compress 1st { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); unsigned int remaining = GET_LOWER_32BITS(src_sz), tmp_src_sz = 0, last = 0; unsigned int tmp_comp_out_sz = GET_LOWER_32BITS(comp_out_sz); unsigned int comp_available_out = GET_LOWER_32BITS(comp_out_sz); unsigned char *tmp_src = src, *tmp_comp_out = comp_out; comp_out_sz = (size_t)0; while (remaining) { if (remaining > blk->size) { tmp_src_sz = blk->size; last = 0; } else { tmp_src_sz = remaining; last = 1; } tmp_comp_out_sz = comp_available_out; if (QZ == blk->fmt) { rc = qzCompress(&sess, tmp_src, &tmp_src_sz, tmp_comp_out, &tmp_comp_out_sz, last); } else { rc = qzSWCompress(&sess, tmp_src, &tmp_src_sz, tmp_comp_out, &tmp_comp_out_sz, last); } tmp_src += tmp_src_sz; tmp_comp_out += tmp_comp_out_sz; comp_out_sz += tmp_comp_out_sz; comp_available_out -= tmp_comp_out_sz; remaining -= tmp_src_sz; QZ_DEBUG("[Thead%ld] Compress: format is %4s, remaining %u, tmp_src_sz is %u\n", tid, g_format_list[blk->fmt - 1].fmt_name, remaining, tmp_src_sz); blk = (blk->next) ? blk->next : head->next; } if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto done; } if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu\n!", src_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } //Decompress { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); unsigned int remaining = GET_LOWER_32BITS(comp_out_sz); unsigned int decomp_available_out = GET_LOWER_32BITS(decomp_out_sz); unsigned char *tmp_comp_out = comp_out, *tmp_decomp_out = decomp_out; unsigned int tmp_comp_out_sz, tmp_decomp_out_sz, decomp_out_sz = 0; while (remaining) { tmp_comp_out_sz = remaining; tmp_decomp_out_sz = decomp_available_out; rc = qzDecompress(&sess, tmp_comp_out, &tmp_comp_out_sz, tmp_decomp_out, &tmp_decomp_out_sz); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } tmp_comp_out += tmp_comp_out_sz; tmp_decomp_out += tmp_decomp_out_sz; decomp_out_sz += tmp_decomp_out_sz; remaining -= tmp_comp_out_sz; decomp_available_out -= tmp_decomp_out_sz; QZ_DEBUG("[Thead%ld] Decompress: remaining %d, tmp_decomp_out_sz is %u\n", tid, remaining, tmp_decomp_out_sz); } if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %u != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %u\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); goto done; } QZ_DEBUG("reset data..\n"); memset(comp_out, 0, (size_t)comp_out_sz); memset(decomp_out, 0, (size_t)decomp_out_sz); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz * 8;// bits rate *= 2; rate /= 1024; rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps rc = pthread_mutex_lock(&g_lock_print); assert(0 == rc); QZ_PRINT("[INFO] srv=BOTH, tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); QZ_PRINT("\n"); rc = pthread_mutex_unlock(&g_lock_print); assert(0 == rc); done: if (gen_data) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzSetupParamFuncTest(void *arg) { QzSessionParams_T def_params = {0}; QzSessionParams_T new_params = {0}; QzSessionParams_T cus_params = {0}; unsigned char *src, *dest; size_t src_sz, dest_sz, test_dest_sz;; int rc; QzSession_T sess = {0}; src_sz = 256 * 1024; test_dest_sz = dest_sz = 256 * 1024 * 2; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); if (!src || !dest) { QZ_ERROR("Malloc failed\n"); return NULL; } if (qzGetDefaults(&def_params) != QZ_OK || qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("Err: fail to init HW with ret: %d.\n", rc); goto end; } rc = qzSetupSession(&sess, &def_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto end; } rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), dest, (uint32_t *)(&test_dest_sz), 1); if (rc != QZ_OK) { QZ_ERROR("Err: fail to compress data with ret: %d\n", rc); goto end; } QZ_PRINT("With default params, input_len:%lu, output_len:%lu.\n", src_sz, test_dest_sz); test_dest_sz = dest_sz; // Negative Test cus_params.huffman_hdr = QZ_STATIC_HDR + 1; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect huffman: %d.\n", cus_params.huffman_hdr); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.direction = QZ_DIR_BOTH + 1; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect direction: %d.\n", cus_params.direction); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.comp_lvl = 0; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect comp_level: %d.\n", cus_params.comp_lvl); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.comp_lvl = (COMP_LVL_MAXIMUM + 1); if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect comp_level: %d.\n", cus_params.comp_lvl); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.sw_backup = 2; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect sw_backup: %d.\n", cus_params.sw_backup); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 0; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 1025; if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } cus_params.hw_buff_sz = 2 * 1024 * 1024; //2M if (qzSetDefaults(&cus_params) != QZ_PARAMS) { QZ_ERROR("FAILED: set params should fail with incorrect hw_buff_sz %d.\n", cus_params.hw_buff_sz); goto end; } if (qzGetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } // Positive Test cus_params.huffman_hdr = (QZ_HUFF_HDR_DEFAULT == QZ_DYNAMIC_HDR) ? QZ_STATIC_HDR : QZ_DYNAMIC_HDR; if (qzSetDefaults(&cus_params) != QZ_OK) { QZ_ERROR("Err: fail to set default params.\n"); goto end; } if (qzGetDefaults(&new_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto end; } if (memcmp(&def_params, &new_params, sizeof(QzSessionParams_T)) == 0) { QZ_ERROR("Err: set default params fail.\n"); goto end; } if (memcmp(&cus_params, &new_params, sizeof(QzSessionParams_T)) != 0) { QZ_ERROR("Err: set default params fail with incorrect value.\n"); QZ_ERROR(" cus_params.huff(%d) != new_params.huff(%d).\n", cus_params.huffman_hdr, new_params.huffman_hdr); goto end; } rc = qzSetupSession(&sess, &new_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto end; } rc = qzCompress(&sess, src, (uint32_t *)(&src_sz), dest, (uint32_t *)(&test_dest_sz), 1); if (rc != QZ_OK) { QZ_ERROR("Err: fail to compress data with ret: %d\n", rc); goto end; } QZ_ERROR("With custom params, input_len:%lu, output_len:%lu.\n", src_sz, test_dest_sz); end: qzFree(src); qzFree(dest); (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressAndDecompress(void *arg) { int rc = -1, k; unsigned char *src, *comp_out, *decomp_out; int *compressed_blocks_sz = NULL; size_t src_sz, comp_out_sz, decomp_out_sz; size_t block_size, in_sz, out_sz, consumed, produced; size_t num_blocks; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; const size_t org_src_sz = ((TestArg_T *)arg)->src_sz; const size_t org_comp_out_sz = ((TestArg_T *)arg)->comp_out_sz; const long tid = ((TestArg_T *)arg)->thd_id; const ServiceType_T service = ((TestArg_T *)arg)->service; const int verify_data = ((TestArg_T *)arg)->verify_data; const int count = ((TestArg_T *)arg)->count; const int gen_data = ((TestArg_T *)arg)->gen_data; int thread_sleep = ((TestArg_T *)arg)->thread_sleep; QzSession_T sess = {0}; if (!org_src_sz) { pthread_exit((void *)"input size is 0\n"); } src_sz = org_src_sz; comp_out_sz = org_comp_out_sz; decomp_out_sz = org_src_sz; QZ_DEBUG("Hello from qzCompressAndDecompress tid=%ld, count=%d, service=%d, " "verify_data=%d\n", tid, count, service, verify_data); rc = qzInitSetupsession(&sess, (TestArg_T *)arg); if (rc != QZ_OK && rc != QZ_DUPLICATE) { #ifndef ENABLE_THREAD_BARRIER g_ready_thread_count++; pthread_cond_signal(&g_ready_cond); #endif pthread_exit((void *)"qzInit failed"); } //timeCheck(3, tid); /* The sleep is for enabling the sw fallback in test. sw fallback simulate hang will happen when detect process generate the 'fatal events'. but detect will happen every seconds. The sleep will guarantee that test capture the 'fatal events' and fallback */ if (thread_sleep > 0) { usleep(thread_sleep); } QZ_DEBUG("qzInitSetupsession rc = %d\n", rc); if (gen_data && !g_perf_svm) { src = qzMalloc(src_sz, 0, PINNED_MEM); comp_out = qzMalloc(comp_out_sz, 0, PINNED_MEM); decomp_out = qzMalloc(decomp_out_sz, 0, PINNED_MEM); } else { src = g_perf_svm ? malloc(src_sz) : ((TestArg_T *)arg)->src; comp_out = g_perf_svm ? malloc(comp_out_sz) : ((TestArg_T *)arg)->comp_out; decomp_out = g_perf_svm ? malloc(decomp_out_sz) : ((TestArg_T *) arg)->decomp_out; } if (!src || !comp_out || !decomp_out) { QZ_ERROR("Malloc failed\n"); goto done; } if (g_perf_svm && g_input_file_name) { memcpy(src, ((TestArg_T *)arg)->src, src_sz); } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } //timeCheck(4, tid); block_size = ((TestArg_T *)arg)->block_size; if (-1 == block_size) { block_size = src_sz; } num_blocks = src_sz / block_size + (src_sz % block_size ? 1 : 0); compressed_blocks_sz = malloc(sizeof(int) * num_blocks); if (NULL == compressed_blocks_sz) { QZ_ERROR("Malloc failed\n"); goto done; } memset(compressed_blocks_sz, 0, sizeof(int) * num_blocks); // Compress the data for testing if (DECOMP == service) { consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_wait(&g_bar); #else /* mutex lock for thread count */ rc = pthread_mutex_lock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } g_ready_thread_count++; rc = pthread_cond_signal(&g_ready_cond); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_signal, status = %d\n", rc); goto done; } while (!g_ready_to_start) { rc = pthread_cond_wait(&g_start_cond, &g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to pthread_cond_wait, status = %d\n", rc); goto done; } } rc = pthread_mutex_unlock(&g_cond_mutex); if (rc != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", rc); goto done; } #endif // Start the testing for (k = 0; k < count; k++) { (void)gettimeofday(&ts, NULL); if (DECOMP != service) { comp_out_sz = org_comp_out_sz; QZ_DEBUG("thread %ld before Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = block_size < (org_src_sz - consumed) ? block_size : (org_src_sz - consumed); out_sz = comp_out_sz - produced; rc = qzCompress(&sess, src + consumed, (uint32_t *)(&in_sz), comp_out + produced, (uint32_t *)(&out_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); dumpInputData(in_sz, src + consumed); goto done; } consumed = consumed + in_sz; produced = produced + out_sz; compressed_blocks_sz[i] = out_sz; } src_sz = consumed; comp_out_sz = produced; if (src_sz != org_src_sz) { QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Compressed %lu bytes into %lu\n", tid, src_sz, comp_out_sz); } if (COMP != service) { QZ_DEBUG("thread %ld before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } decomp_out_sz = produced; if (decomp_out_sz != org_src_sz) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } QZ_DEBUG("thread %ld after Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); } (void)gettimeofday(&te, NULL); if (verify_data && COMP != service) { QZ_DEBUG("verify data..\n"); if (memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: Decompression FAILED on thread %ld with size: %lu \n!", tid, src_sz); dumpInputData(src_sz, src); goto done; } if (BOTH == service) { QZ_DEBUG("reset data..\n"); memset(comp_out, 0, comp_out_sz); memset(decomp_out, 0, decomp_out_sz); } } ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } /* Verify the last compress is enough decompress data for verify */ if (verify_data && COMP == service) { QZ_DEBUG("verify compress thread %ld, before Decompressed %lu bytes into %lu\n", tid, comp_out_sz, decomp_out_sz); consumed = 0; produced = 0; for (int i = 0; i < num_blocks; i ++) { in_sz = compressed_blocks_sz[i]; out_sz = decomp_out_sz - produced; rc = qzDecompress(&sess, comp_out + consumed, (uint32_t *)(&in_sz), decomp_out + produced, (uint32_t *)(&out_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(src_sz, src); goto done; } consumed += in_sz; produced += out_sz; } QZ_DEBUG("verify compressed data..\n"); decomp_out_sz = produced; if (decomp_out_sz != org_src_sz || memcmp(src, decomp_out, org_src_sz)) { QZ_ERROR("ERROR: After Decompression decomp_out_sz: %lu != org_src_sz: %lu \n!", decomp_out_sz, org_src_sz); dumpInputData(src_sz, src); goto done; } } //timeCheck(5, tid); sec = (long double)(el_m); sec = sec / 1000000.0; rate = org_src_sz; rate /= 1024; rate *= 8;// Kbits if (BOTH == service) { rate *= 2; } rate *= count; rate /= 1024 * 1024; // gigbits rate /= sec;// Gbps if (0 != pthread_mutex_lock(&g_lock_print)) { goto done; } QZ_PRINT("[INFO] srv="); if (COMP == service) { QZ_PRINT("COMP"); } else if (DECOMP == service) { QZ_PRINT("DECOMP"); } else if (BOTH == service) { QZ_PRINT("BOTH"); } else { QZ_ERROR("UNKNOWN\n"); pthread_mutex_unlock(&g_lock_print); goto done; } QZ_PRINT(", tid=%ld, verify=%d, count=%d, msec=%llu, " "bytes=%lu, %Lf Gbps", tid, verify_data, count, el_m, org_src_sz, rate); if (DECOMP != service) { QZ_PRINT(", input_len=%lu, comp_len=%lu, ratio=%f%%", org_src_sz, comp_out_sz, ((double)comp_out_sz / (double)org_src_sz) * 100); } if (COMP != service) { QZ_PRINT(", comp_len=%lu, decomp_len=%lu", comp_out_sz, decomp_out_sz); } QZ_PRINT("\n"); if (test_thread_safe_flag == 1) { if (thread_sleep == 0) { srand(time(NULL)); thread_sleep = (rand() % 500 + 1) * 1000; } usleep(thread_sleep); } pthread_mutex_unlock(&g_lock_print); done: if (gen_data && !g_perf_svm) { qzFree(src); qzFree(comp_out); qzFree(decomp_out); } else if (g_perf_svm) { free(src); free(comp_out); free(decomp_out); } if (compressed_blocks_sz != NULL) { free(compressed_blocks_sz); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzMemFuncTest(void *test_arg) { int i; unsigned char *ptr[1000]; unsigned char *ptr2[1000]; unsigned success = 0; const long tid = ((TestArg_T *)test_arg)->thd_id; QZ_DEBUG("Hello from test2 thread id %ld\n", tid); for (i = 0; i < 1000; i++) { ptr[i] = qzMalloc(100000, 0, PINNED_MEM); ptr2[i] = qzMalloc(100000, 0, COMMON_MEM); if (ptr[i] == NULL || ptr2[i] == NULL) { QZ_ERROR("[Test2 %ld]\tptr[%d]=0x%lx\t0x%lx\n", tid, i, (unsigned long)ptr[i], (unsigned long)ptr2[i]); if (ptr[i]) { qzFree(ptr[i]); } if (ptr2[i]) { qzFree(ptr2[i]); } break; } success++; } for (i = 0; i < success; i++) { qzFree(ptr[i]); qzFree(ptr2[i]); } for (i = 0; i < success; i++) { if (1 == qzMemFindAddr(ptr[i])) { QZ_DEBUG("[Test2 %ld]\tptr[%d]=0x%lx\tstill as pinned memory after qzFree.\n", tid, i, (unsigned long)ptr[i]); break; } } pthread_exit((void *)NULL); } int qzCompressDecompressWithParams(const TestArg_T *arg, QzSessionParams_T *comp_params, QzSessionParams_T *decomp_params) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; orig_sz = comp_sz = decomp_sz = arg->src_sz; orig_src = qzMalloc(orig_sz, 0, PINNED_MEM); comp_src = qzMalloc(comp_sz, 0, PINNED_MEM); decomp_src = qzMalloc(orig_sz, 0, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return -1; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; if (qzSetDefaults(comp_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzCompress(&comp_sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*do decompress Data*/ if (qzSetDefaults(decomp_params) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return rc; } void *qzCompressStreamAndDecompress(void *arg) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}, decomp_params = {0}; uint8_t *orig_src = NULL, *comp_src = NULL, *decomp_src = NULL; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; unsigned int decomp_out_sz = 0; int org_in_sz; int offset = 0; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); if (NULL == orig_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } comp_src = malloc(comp_sz); if (NULL == comp_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } decomp_src = calloc(orig_sz, 1); if (NULL == decomp_src) { QZ_ERROR("Err: fail to malloc memory\n"); goto exit; } if (qzGetDefaults(&comp_params) != QZ_OK) { QZ_ERROR("Err: get params fail with incorrect compress params.\n"); goto exit; } if (qzGetDefaults(&decomp_params) != QZ_OK) { QZ_ERROR("Err: get params fail with incorrect decompress params.\n"); goto exit; } slice_sz = comp_params.hw_buff_sz / 4; rc = qzInit(&comp_sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("Err: fail to init HW with ret: %d.\n", rc); goto exit; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; decomp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; decomp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); goto exit; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); rc = qzSetupSession(&comp_sess, &comp_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto exit; } rc = qzSetupSession(&decomp_sess, &decomp_params); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("Err: fail to setup session with ret: %d\n", rc); goto exit; } genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } decomp_out_sz = produced; qzEndStream(&comp_sess, &comp_strm); QZ_DEBUG("qzCompressStream consumed: %d produced: %d\n", consumed, produced); comp_sz = produced; rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(produced, comp_src); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } if (memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpOutputData(comp_sz, comp_src, "comp_out"); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } QZ_DEBUG("qzDecompress Test PASS\n"); QZ_DEBUG("*** Decompress Stream Test 1 ***\n"); comp_sz = produced; done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpOutputData(comp_sz, comp_src, "decomp_stream__input"); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %d produced: %d input_left: %d last: %d, pending_in: %d, pending_out: %d\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_DEBUG("*** Decompress Stream Test 1 PASS ***\n"); if (comp_params.data_fmt != QZ_DEFLATE_GZIP_EXT) { goto test_2_end; } QZ_DEBUG("*** Decompress Stream Test 2 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); QzGzH_T hdr; while (!done) { if (QZ_OK != qzGzipHeaderExt(comp_src + offset, &hdr)) { QZ_ERROR("ERROR: extracting header failed\n"); goto exit; } input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = sizeof(QzGzH_T) + hdr.extra.qz_e.dest_sz + sizeof(StdGzF_T); comp_strm.out_sz = decomp_sz - produced; last = 1; offset += comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Memcmp with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; if (offset == comp_sz) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_DEBUG("*** Decompress Stream Test 2 PASS ***\n"); test_2_end: if (comp_params.data_fmt == QZ_DEFLATE_GZIP_EXT) { goto test_3_end; } QZ_DEBUG("*** Decompress Stream Test 3 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > 256) ? 256 : input_left; comp_strm.out_sz = decomp_sz - produced; last = 1; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %u produced: %u input_left: %u last: %u, pending_in: %u, pending_out: %u " "org_in_sz: %d in_sz: %u\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out, org_in_sz, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz && produced == orig_sz && comp_sz - consumed == 0) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_DEBUG("*** Decompress Stream Test 3 PASS***\n"); test_3_end: QZ_DEBUG("*** Decompress Stream Test 4 ***\n"); done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); while (!done) { input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; org_in_sz = comp_strm.in_sz; rc = qzDecompressStream(&decomp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed: %u produced: %u input_left: %u last: %u, pending_in: %u, pending_out: %u " "org_in_sz: %d in_sz: %u\n", consumed, produced, input_left, last, comp_strm.pending_in, comp_strm.pending_out, org_in_sz, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out && org_in_sz == comp_strm.in_sz && produced == orig_sz && comp_sz - consumed == 0) { done = 1; } } QZ_DEBUG("Total consumed: %u produced: %u\n", consumed, produced); QZ_DEBUG("verify data of size %lu ...\n", orig_sz); if (produced != orig_sz || consumed != decomp_out_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Memory compare FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpInputData(orig_sz, decomp_src); goto exit; } QZ_DEBUG("*** Decompress Stream Test 4 PASS***\n"); QZ_PRINT("Compress Stream and Decompress function test: PASS\n"); exit: if (NULL != orig_src) { free(orig_src); orig_src = NULL; } if (NULL != comp_src) { free(comp_src); comp_src = NULL; } if (NULL != decomp_src) { free(decomp_src); decomp_src = NULL; } qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); return NULL; } void *qzCompressStreamOnCommonMem(void *thd_arg) { int rc, k; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz, avail_dest_sz; struct timeval ts, te; unsigned long long ts_m, te_m, el_m; long double sec, rate; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamOnCommonMem id %ld\n", tid); timeCheck(0, tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } timeCheck(1, tid); //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } timeCheck(2, tid); QZ_DEBUG("qzSetupSession rc = %d\n", rc); src_sz = QATZIP_MAX_HW_SZ; avail_dest_sz = dest_sz = QATZIP_MAX_HW_SZ; if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } el_m = 0; if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } timeCheck(3, tid); for (k = 0; k < test_arg->count; k++) { dest_sz = avail_dest_sz; (void)gettimeofday(&ts, NULL); comp_strm.in = src; comp_strm.out = dest; comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); qzEndStream(&sess, &comp_strm); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } (void)gettimeofday(&te, NULL); QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); ts_m = (ts.tv_sec * 1000000) + ts.tv_usec; te_m = (te.tv_sec * 1000000) + te.tv_usec; el_m += te_m - ts_m; } timeCheck(4, tid); sec = (long double)(el_m); sec = sec / 1000000.0; rate = src_sz * test_arg->count * 8; // bits rate = rate / 1000000000.0; // gigbits rate = rate / sec;// Gbps QZ_PRINT("[%ld] elapsed microsec = %llu bytes = %lu rate = %Lf Gbps\n", tid, el_m, src_sz, rate); done: timeCheck(5, tid); if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamOutput(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamOutput\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; switch (test_arg->test_format) { case TEST_DEFLATE: params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: break; } rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } { // Add header and tailer for DEFLATE_RAW data, this is simulate from // nginx qatzip module, and it's convenient for us to valid correctness. if (params.data_fmt == QZ_DEFLATE_RAW) { static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; memcpy(dest, gzheader, 10); comp_strm.out = dest + 10; } else { comp_strm.out = dest; } comp_strm.in = src; comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); // Add tailer for Deflate raw data. if (params.data_fmt == QZ_DEFLATE_RAW) { StdGzF_T *tailer = (StdGzF_T *)(comp_strm.out + comp_strm.out_sz); tailer->crc32 = comp_strm.crc_32; tailer->i_size = comp_strm.in_sz; comp_strm.out_sz += 18; comp_strm.out = dest; } dumpOutputData(comp_strm.out_sz, comp_strm.out, filename); qzEndStream(&sess, &comp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzDecompressStreamInput(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; unsigned int consumed, done; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzDecompressStreamInput\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = 1024 * 1024; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { QZ_ERROR("Err: No input file.\n"); goto done; } src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->decomp_out; dest_sz = test_arg->decomp_out_sz; consumed = 0; done = 0; filename = g_input_file_name; if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } { while (!done) { decomp_strm.in = src + consumed; decomp_strm.in_sz = src_sz - consumed; decomp_strm.out = dest; decomp_strm.out_sz = dest_sz; last = 1; rc = qzDecompressStream(&sess, &decomp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzDecompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Decompressed %lu bytes into %lu\n", src_sz, dest_sz); dumpDecompressedData(decomp_strm.out_sz, decomp_strm.out, filename); consumed += decomp_strm.in_sz; if (src_sz == consumed && decomp_strm.pending_out == 0) { done = 1; } } qzEndStream(&sess, &decomp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamInvalidChunkSize(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; QzSessionParams_T params = {0}; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_PRINT("Hello from qzCompressStreamInvalidChunkSize id %ld\n", tid); timeCheck(0, tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } params.hw_buff_sz = 525312; /*513k*/ rc = qzSetupSession(&sess, ¶ms); if (rc != QZ_PARAMS) { pthread_exit((void *) "qzCompressStreamInvalidChunkSize input param check FAILED"); } params.hw_buff_sz = 100; rc = qzSetupSession(&sess, ¶ms); if (rc != QZ_PARAMS) { pthread_exit((void *) "qzCompressStreamInvalidChunkSize input param check FAILED"); } QZ_PRINT("qzCompressStreamInvalidChunkSize : PASS\n"); done: timeCheck(5, tid); if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressStreamInvalidQzStreamParam(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; const long tid = test_arg->thd_id; QzSession_T sess = {0}; QZ_PRINT("Hello from qzCompressStreamInvalidQzStreamParam id %ld\n", tid); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } { /*case 1: set strm all params to zero*/ last = 1; memset(&comp_strm, 0, sizeof(QzStream_T)); rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_PARAMS) { QZ_ERROR("qzCompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Compressed %lu bytes into %lu\n", src_sz, dest_sz); /*case 2: set strm in, our ptr to NULL, but in_sz, out_sz not zero*/ memset(&comp_strm, 0, sizeof(QzStream_T)); comp_strm.in_sz = src_sz; comp_strm.out_sz = dest_sz; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_PARAMS) { QZ_ERROR("qzCompressStream FAILED, return: %d\n", rc); goto done; } dumpOutputData(comp_strm.out_sz, comp_strm.out, filename); qzEndStream(&sess, &comp_strm); } QZ_PRINT("qzCompressStreamInvalidQzStreamParam : PASS\n"); done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *testqzDecompressStreamInvalidParam(void *arg, int test_no) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; QzSession_T *test_sess = NULL; QzStream_T *test_strm = NULL; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); comp_src = malloc(comp_sz); decomp_src = calloc(orig_sz, 1); if (qzGetDefaults(&comp_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); return NULL; } slice_sz = comp_params.hw_buff_sz / 4; if (NULL == orig_src || NULL == comp_src || NULL == decomp_src) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return NULL; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); free(orig_src); free(comp_src); free(decomp_src); return NULL; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } qzEndStream(&comp_sess, &comp_strm); QZ_DEBUG("qzCompressStream consumed: %d produced: %d\n", consumed, produced); comp_sz = produced; rc = qzDecompress(&decomp_sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK) { QZ_ERROR("ERROR: Decompression FAILED with return value: %d\n", rc); dumpInputData(produced, comp_src); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } if (memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression FAILED with size: %lu \n!", orig_sz); dumpInputData(orig_sz, orig_src); dumpOutputData(comp_sz, comp_src, "comp_out"); dumpOutputData(decomp_sz, decomp_src, "decomp_out"); goto exit; } QZ_DEBUG("qzDecompress Test PASS\n"); QZ_DEBUG("*** Decompress Stream Test ***\n"); comp_sz = produced; done = 0; consumed = 0; produced = 0; memset(decomp_src, 0, orig_sz); input_left = comp_sz - consumed; comp_strm.in = comp_src + consumed; comp_strm.out = decomp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = decomp_sz - produced; last = (comp_sz == (consumed + comp_strm.in_sz)) ? 1 : 0; if (1 == test_no) { QZ_DEBUG("T#############T DecompressStream Session is null Test ***\n"); test_strm = &comp_strm; } else if (2 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for last is -1 Test ***\n"); last = -1; test_sess = &comp_sess; test_strm = &comp_strm; } else if (3 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for last is 2 Test ***\n"); last = 2; test_sess = &comp_sess; test_strm = &comp_strm; } else if (4 == test_no) { QZ_DEBUG("T#############T DecompressStream Neg parameter for strm null Test ***\n"); test_sess = &comp_sess; } else { //nothing to do goto exit; } rc = qzDecompressStream(test_sess, test_strm, last); if (rc == QZ_OK) { QZ_ERROR("T#############T ERROR: qzDecompressStream negative test FAILED: %d*** \n", rc); dumpOutputData(comp_sz, comp_src, "decomp_stream__input"); goto exit; } QZ_DEBUG("T#############T: qzDecompressStream return value: %d*** \n", rc); exit: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return NULL; } void *qzDecompressStreamNegParam(void *arg) { int test_no = 0; for (test_no = 1; test_no <= 5; test_no++) { QZ_DEBUG("*** qzDecompressStreamNegParam test_no: %d ***\n", test_no); testqzDecompressStreamInvalidParam(arg, test_no); } return NULL; } void *testqzEndStreamInvalidParam(void *arg, int test_no) { int rc = -1; QzSession_T comp_sess = {0}, decomp_sess = {0}; QzStream_T comp_strm = {0}; QzSessionParams_T comp_params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, comp_sz, decomp_sz; unsigned int slice_sz = 0, done = 0; unsigned int consumed = 0, produced = 0; unsigned int input_left = 0, last = 0; QzSession_T *test_sess = NULL; QzStream_T *test_strm = NULL; TestArg_T *test_arg = (TestArg_T *) arg; orig_sz = comp_sz = decomp_sz = test_arg->src_sz; orig_src = malloc(orig_sz); comp_src = malloc(comp_sz); decomp_src = calloc(orig_sz, 1); if (qzGetDefaults(&comp_params) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); return NULL; } slice_sz = comp_params.hw_buff_sz / 4; if (NULL == orig_src || NULL == comp_src || NULL == decomp_src) { free(orig_src); free(comp_src); free(decomp_src); QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return NULL; } switch (test_arg->test_format) { case TEST_DEFLATE: comp_params.data_fmt = QZ_DEFLATE_RAW; break; case TEST_GZIPEXT: comp_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; default: QZ_ERROR("Unsupported data format in Stream API\n"); free(orig_src); free(comp_src); free(decomp_src); return NULL; } QZ_DEBUG("*** Data Format: %d ***\n", comp_params.data_fmt); genRandomData(orig_src, orig_sz); while (!done) { input_left = orig_sz - consumed; comp_strm.in = orig_src + consumed; comp_strm.out = comp_src + produced; comp_strm.in_sz = (input_left > slice_sz) ? slice_sz : input_left; comp_strm.out_sz = comp_sz - produced; last = (((consumed + comp_strm.in_sz) == orig_sz) ? 1 : 0); rc = qzCompressStream(&comp_sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); goto exit; } consumed += comp_strm.in_sz; produced += comp_strm.out_sz; QZ_DEBUG("consumed is %u, in_sz is %d\n", consumed, comp_strm.in_sz); if (1 == last && 0 == comp_strm.pending_in && 0 == comp_strm.pending_out) { done = 1; } } if (1 == test_no) { QZ_DEBUG("T#############T qzEndStream Session is null Test ***\n"); test_strm = &comp_strm; } else if (2 == test_no) { QZ_DEBUG("T#############T qzEndStream stream is null Test ***\n"); test_sess = &comp_sess; } else { goto exit; } rc = qzEndStream(test_sess, test_strm); if (rc == QZ_OK) { QZ_ERROR("\nT#############T ERROR: qzEndStream negative test FAILED,return: %d*** \n", rc); goto exit; } QZ_DEBUG("T#############T: qzEndStream return value: %d*** \n", rc); exit: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); qzEndStream(&comp_sess, &comp_strm); (void)qzTeardownSession(&comp_sess); (void)qzTeardownSession(&decomp_sess); qzClose(&comp_sess); qzClose(&decomp_sess); return NULL; } void *qzEndStreamNegParam(void *arg) { int test_no = 0; for (test_no = 1; test_no <= 3; test_no++) { QZ_DEBUG("*** qzEndStreamNegParam test_no: %d ***\n", test_no); testqzEndStreamInvalidParam(arg, test_no); } return NULL; } void *qzInitPcieCountCheck(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; unsigned int consumed, done; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Start qzInitPcieCountCheck test\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit1 error. rc = %d\n", rc); } QZ_DEBUG("qzInit1 done. rc = %d, g_process.qat_available = %d\n", rc, g_process.qat_available); qzClose(&sess); QZ_DEBUG("qzClose done. g_process.qat_available = %d\n", g_process.qat_available); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit2 error. rc = %d\n", rc); } QZ_DEBUG("qzInit2 done. rc = %d, g_process.qat_available = %d\n", rc, g_process.qat_available); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = 1024 * 1024; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { QZ_ERROR("Err: No input file.\n"); goto done; } src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->decomp_out; dest_sz = test_arg->decomp_out_sz; consumed = 0; done = 0; filename = g_input_file_name; if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } { while (!done) { decomp_strm.in = src + consumed; decomp_strm.in_sz = src_sz - consumed; decomp_strm.out = dest; decomp_strm.out_sz = dest_sz; last = 1; rc = qzDecompressStream(&sess, &decomp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzDecompressStream FAILED, return: %d\n", rc); goto done; } QZ_DEBUG("Decompressed %lu bytes into %lu\n", src_sz, dest_sz); dumpDecompressedData(decomp_strm.out_sz, decomp_strm.out, filename); consumed += decomp_strm.in_sz; if (src_sz == consumed && decomp_strm.pending_out == 0) { done = 1; } } qzEndStream(&sess, &decomp_strm); } done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *qzCompressDecompressSwQZMixed(void *arg) { enum TestType_E { SW_SW, SW_QZ, QZ_SW, QZ_QZ, NUM_OF_TEST }; struct TestParams_T { enum TestType_E type; char *name; QzSessionParams_T *comp_params; QzSessionParams_T *decomp_params; }; QzSessionParams_T sw_comp_params = {0}, qz_comp_params = {0}, sw_decomp_params = {0}, qz_decomp_params = {0}; int i = 0; if ((qzGetDefaults(&sw_comp_params) != QZ_OK) || (qzGetDefaults(&qz_comp_params) != QZ_OK) || (qzGetDefaults(&sw_decomp_params) != QZ_OK) || (qzGetDefaults(&qz_decomp_params) != QZ_OK)) { QZ_ERROR("Err: fail to get default params.\n"); return NULL; } sw_comp_params.input_sz_thrshold = 512 * 1024; qz_comp_params.input_sz_thrshold = 1024; sw_decomp_params.input_sz_thrshold = 512 * 1024; qz_decomp_params.input_sz_thrshold = 1024; struct TestParams_T test_params[NUM_OF_TEST] = { (struct TestParams_T){SW_SW, "SW compress SW decompress", &sw_comp_params, &sw_decomp_params}, (struct TestParams_T){SW_QZ, "SW compress QZ decompress", &sw_comp_params, &qz_decomp_params}, (struct TestParams_T){QZ_SW, "QZ compress SW decompress", &qz_comp_params, &sw_decomp_params}, (struct TestParams_T){QZ_QZ, "QZ compress QZ decompress", &qz_comp_params, &qz_decomp_params}, }; ((TestArg_T *) arg)->src_sz = 128 * 1024; //128KB for (i = 0; i < NUM_OF_TEST; i++) { if (qzCompressDecompressWithParams(arg, test_params[i].comp_params, test_params[i].decomp_params) < 0) { QZ_ERROR("ERROR: HW/SW mixed function test in: %s \n", test_params[i].name); return NULL; } } QZ_PRINT("HW/SW mixed function test: PASS\n"); return NULL; } int qzDecompressFailedAtUnknownGzipHeader(void) { int rc; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = comp_sz = decomp_sz = 64 * 1024; /*64K*/ orig_src = qzMalloc(orig_sz, 0, PINNED_MEM); comp_src = qzMalloc(comp_sz, 0, PINNED_MEM); decomp_src = qzMalloc(orig_sz, 0, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); return -1; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.sw_backup = 0; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); /*do compress Data*/ src_sz = orig_sz; rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*wrap bad block*/ hdr = (QzGzH_T *)comp_src; hdr->std_hdr.id1 = 0; /* id1 !=0x1f */ /*do decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL) { QZ_ERROR("FAILED: Decompression success with Error GipHeader\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressSWFailedAtUnknownGzipBlock(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; unsigned int produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, 0, PINNED_MEM); comp_src = qzMalloc(comp_sz, 0, PINNED_MEM); decomp_src = qzMalloc(orig_sz, 0, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.hw_buff_sz = QZ_HW_BUFF_MAX_SZ; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; produce = hdr->extra.qz_e.dest_sz; /*wrap unknown block*/ memset(hdr + qzGzipHeaderSz(), 0, (size_t)produce); /*Scenario1: produce > DEST_SZ(params.hw_buff_sz)*/ /*set minimum hw size 16K*/ params.hw_buff_sz = 16 * 1024; while (produce < DEST_SZ(params.hw_buff_sz)) { params.hw_buff_sz *= 2; } QZ_DEBUG("produce: %u, DEST_SZ(hw_sz): %d\n", produce, DEST_SZ(params.hw_buff_sz)); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL && rc != QZ_DATA_ERROR) { QZ_ERROR("FAILED: Decompression success with Error Unknown Gzip block\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressHWFailedAtUnknownGzipBlock(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; QzSessionParams_T params = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; uint32_t produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, 0, PINNED_MEM); comp_src = qzMalloc(comp_sz, 0, PINNED_MEM); decomp_src = qzMalloc(orig_sz, 0, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 0); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.sw_backup = 0; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; produce = hdr->extra.qz_e.dest_sz; /*wrap unknown block*/ memset(hdr + qzGzipHeaderSz(), 'Q', (size_t)produce); /*do Decompress Data*/ rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_FAIL && rc != QZ_DATA_ERROR) { QZ_ERROR("FAILED: Decompression success with Error Unknown Gzip block\n"); goto done; } rc = 0; done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressForceSW(void) { int rc = 0; QzGzH_T *hdr = NULL; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; uint32_t consume, produce; orig_sz = comp_sz = decomp_sz = USDM_ALLOC_MAX_SZ; orig_src = qzMalloc(orig_sz, 0, PINNED_MEM); comp_src = qzMalloc(comp_sz, 0, PINNED_MEM); decomp_src = qzMalloc(orig_sz, 0, PINNED_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = QZ_HW_BUFF_MAX_SZ; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress Data*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } hdr = (QzGzH_T *)comp_src; consume = hdr->extra.qz_e.src_sz; produce = hdr->extra.qz_e.dest_sz; qzTeardownSession(&sess); /*Scenario1: produce > DEST_SZ(params.hw_buff_sz)*/ /*set minimum hw size 2K*/ params.hw_buff_sz = 2 * 1024; while (produce < DEST_SZ(params.hw_buff_sz)) { params.hw_buff_sz *= 2; } QZ_DEBUG("produce: %d, DEST_SZ(hw_sz): %d\n", produce, DEST_SZ(params.hw_buff_sz)); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } (void)qzTeardownSession(&sess); /*Scenario2: consume > qzSess->sess_params.hw_buff_sz*/ /*set maximum hw size 1M*/ params.hw_buff_sz = QATZIP_MAX_HW_SZ; while (consume < params.hw_buff_sz) { params.hw_buff_sz /= 2; } QZ_DEBUG("consume: %d, hw_sz: %d\n", consume, params.hw_buff_sz); rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("ERROR: qzSetupSession FAILED with return value: %d\n", rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } done: (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzDecompressStandalone(void) { int rc = 0; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = src_sz = comp_sz = decomp_sz = 4 * KB; orig_src = calloc(1, orig_sz); comp_src = calloc(1, comp_sz); decomp_src = calloc(1, decomp_sz); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = 1 * KB; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, orig_sz)) { QZ_ERROR("ERROR: Decompression failed, orig_sc:%lu != decomp_src:%lu\n", orig_sz, decomp_sz); goto done; } rc = 0; done: free(orig_src); free(comp_src); free(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzCompressFailedAtBufferOverflow(void) { int rc = QZ_BUF_ERROR; QzSession_T sess = {0}; QzSessionParams_T params = {0}; uint8_t *src, *low_comp, *comp, *low_decomp; size_t orig_sz = 64 * KB, low_comp_sz = 1 * KB, comp_sz = orig_sz, low_decomp_sz = 1 * KB; src = calloc(1, orig_sz); low_comp = calloc(1, low_comp_sz); comp = calloc(1, comp_sz); low_decomp = calloc(1, low_decomp_sz); if (NULL == src || NULL == low_comp || NULL == comp || NULL == low_decomp) { goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.hw_buff_sz = 1 * KB; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } genRandomData(src, orig_sz); rc = qzCompress(&sess, src, (uint32_t *)(&orig_sz), comp, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression fail with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; rc = qzDecompress(&sess, comp, (uint32_t *)(&comp_sz), low_decomp, (uint32_t *)(&low_decomp_sz)); if (rc != QZ_BUF_ERROR) { QZ_ERROR("FAILED: Decompression success with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; orig_sz = 64 * KB; rc = qzCompress(&sess, src, (uint32_t *)(&orig_sz), low_comp, (uint32_t *)(&low_comp_sz), 1); if (rc != QZ_BUF_ERROR) { QZ_ERROR("FAILED: Compression success with overflow buffer length:rc = %d\n", rc); goto done; } rc = 0; done: free(src); free(comp); free(low_comp); free(low_decomp); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int doQzCompressCrcCheck(size_t orig_sz) { int rc = QZ_BUF_ERROR; QzSession_T sess = {0}; uint8_t *src, *comp; size_t comp_sz = orig_sz; unsigned long crc_sw = 0, crc_qz = 0; src = calloc(1, orig_sz); comp = calloc(1, comp_sz); if (NULL == src || NULL == comp) { goto done; } genRandomData(src, orig_sz); crc_sw = crc32(crc_sw, src, GET_LOWER_32BITS(orig_sz)); rc = qzCompressCrc(&sess, src, (uint32_t *)(&orig_sz), comp, (uint32_t *)(&comp_sz), 1, &crc_qz); if (rc != QZ_OK) { QZ_ERROR("ERROR: Compression fail with overflow buffer length:rc = %d\n", rc); goto done; } if (crc_sw != crc_qz) { QZ_ERROR("ERROR: Compression fail on CRC check: SW CRC %lu, QATzip CRC %lu\n", crc_sw, crc_qz); rc = QZ_FAIL; } done: free(src); free(comp); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzCompressCrcCheck(void) { size_t test_sz_qz = (64 * KB), test_sz_sw = (QZ_COMP_THRESHOLD_DEFAULT - 1); size_t test_sz[] = {test_sz_qz, test_sz_sw}; int i, rc = 0; for (i = 0; i < ARRAY_LEN(test_sz); i++) { rc = doQzCompressCrcCheck(test_sz[i]); if (QZ_OK != rc) { goto done; } } done: return rc; } int qzCompressSWL9DecompressHW(void) { int rc = 0; QzSession_T sess = {0}; uint8_t *orig_src, *comp_src, *decomp_src; size_t orig_sz, src_sz, comp_sz, decomp_sz; QzSessionParams_T params = {0}; orig_sz = comp_sz = decomp_sz = 4 * MB; orig_src = qzMalloc(orig_sz, 0, COMMON_MEM); comp_src = qzMalloc(comp_sz, 0, COMMON_MEM); decomp_src = qzMalloc(orig_sz, 0, COMMON_MEM); if (orig_src == NULL || comp_src == NULL || decomp_src == NULL) { QZ_ERROR("Malloc Memory for testing %s error\n", __func__); goto done; } rc = qzInit(&sess, 1); if (QZ_INIT_HW_FAIL(rc)) { QZ_ERROR("qzInit for testing %s error, return: %d\n", __func__, rc); goto done; } assert(!qzGetDefaults(¶ms)); params.input_sz_thrshold = orig_sz + 1; params.comp_lvl = QZ_DEFLATE_COMP_LVL_MAXIMUM; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } /*compress data by software*/ src_sz = orig_sz; genRandomData(orig_src, orig_sz); rc = qzCompress(&sess, orig_src, (uint32_t *)(&src_sz), comp_src, (uint32_t *)(&comp_sz), 1); if (rc != QZ_OK || src_sz != orig_sz) { QZ_ERROR("ERROR: Compression FAILED with return value: %d\n", rc); QZ_ERROR("ERROR: After Compression src_sz: %lu != org_src_sz: %lu \n!", src_sz, orig_sz); goto done; } /*decompress data by hardware*/ params.input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT; rc = qzSetupSession(&sess, ¶ms); if (QZ_SETUP_SESSION_FAIL(rc)) { QZ_ERROR("qzSetupSession for testing %s error, return: %d\n", __func__, rc); goto done; } rc = qzDecompress(&sess, comp_src, (uint32_t *)(&comp_sz), decomp_src, (uint32_t *)(&decomp_sz)); if (rc != QZ_OK || decomp_sz != orig_sz || memcmp(orig_src, decomp_src, (size_t)orig_sz)) { QZ_ERROR("ERROR: Decompression success with Error GipHeader\n"); goto done; } done: qzFree(orig_src); qzFree(comp_src); qzFree(decomp_src); (void)qzTeardownSession(&sess); qzClose(&sess); return rc; } int qzFuncTests(void) { int i = 0; int (*sw_failover_func_tests[])(void) = { qzDecompressFailedAtUnknownGzipHeader, qzDecompressSWFailedAtUnknownGzipBlock, qzDecompressHWFailedAtUnknownGzipBlock, qzDecompressStandalone, qzDecompressForceSW, qzCompressSWL9DecompressHW, }; for (i = 0; i < ARRAY_LEN(sw_failover_func_tests); i++) { if (sw_failover_func_tests[i]()) { QZ_ERROR("SWFailOverFunc[%d] : failed\n", i); return -1; } } QZ_PRINT("SWFailOverFunc test : Passed\n"); int (*qz_compress_negative_tests[])(void) = { qzCompressFailedAtBufferOverflow, }; for (i = 0; i < ARRAY_LEN(qz_compress_negative_tests); i++) { if (qz_compress_negative_tests[i]()) { QZ_ERROR("qzCompressNegative[%d] : failed\n", i); return -1; } } QZ_PRINT("qzCompressNegative test : Passed\n"); int (*qz_compress_crc_positive[])(void) = { qzCompressCrcCheck, }; for (i = 0; i < ARRAY_LEN(qz_compress_crc_positive); i++) { if (qz_compress_crc_positive[i]()) { QZ_ERROR("qz_compress_crc_positive[%d] : failed\n", i); return -1; } } QZ_PRINT("qz_compress_crc_positive test : Passed\n"); return 0; } void *qzCompressStreamWithPendingOut(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T comp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 0; char *filename = NULL; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; unsigned char *out; unsigned int out_sz = 0; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzCompressStreamWithPendingOut\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = DEFAULT_STREAM_BUF_SZ; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; filename = (char *) calloc(1, strlen(g_input_file_name) + 4); if (NULL != filename) { snprintf(filename, strlen(g_input_file_name) + 4, "%s.%s", g_input_file_name, "gz"); } else { QZ_ERROR("Calloc failed\n"); goto done; } } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } out = dest; comp_strm.in = src; comp_strm.out = dest; comp_strm.in_sz = src_sz; comp_strm.out_sz = 8192; last = 1; if (comp_strm.in_sz) { rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } out_sz += comp_strm.out_sz; QZ_DEBUG("qzCompressStream in: in:%p out:%p in_sz:%ud out_sz:%ud last:%d", comp_strm.in, comp_strm.out, comp_strm.in_sz, comp_strm.out_sz, last); } while (comp_strm.pending_out > 0) { comp_strm.in = src; comp_strm.out += comp_strm.out_sz; comp_strm.in_sz = 0; comp_strm.out_sz = 8192; last = 1; rc = qzCompressStream(&sess, &comp_strm, last); if (rc != QZ_OK) { QZ_ERROR("qzCompressStream FAILED, return: %d", rc); goto done; } out_sz += comp_strm.out_sz; QZ_DEBUG("qzCompressStream in: in:%p out:%p in_sz:%ud out_sz:%ud last:%d", comp_strm.in, comp_strm.out, comp_strm.in_sz, comp_strm.out_sz, last); } dumpOutputData(out_sz, out, filename); qzEndStream(&sess, &comp_strm); done: if (gen_data) { qzFree(src); qzFree(dest); } else { free(filename); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } void *forkResourceCheck(void *arg) { int rc = -1; pid_t pid; int status; char max_hp_str[10] = {0}; int hp_params_fd; size_t number_huge_pages; char *stop = NULL; QzSession_T sess = {0}; QZ_DEBUG("Hello from forkResourceCheck\n"); QZ_PRINT("This is parent process, my pid = %d\n", getpid()); QZ_PRINT("Before qzInit, qz_init_status in parent process is %d\n", g_process.qz_init_status); if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(&sess, ((TestArg_T *)arg)->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } } pid = fork(); if (pid > 0) { QZ_PRINT("After qzInit, qz_init_status in parent process is %d\n", g_process.qz_init_status); QZ_PRINT("instID in parent process is %s\n", g_process.qz_inst[0].instance_info.instID); hp_params_fd = open(MAX_HUGEPAGE_FILE, O_RDONLY); if (hp_params_fd < 0) { QZ_ERROR("Open %s failed\n", MAX_HUGEPAGE_FILE); goto done; } if (read(hp_params_fd, max_hp_str, sizeof(max_hp_str)) < 0) { QZ_ERROR("Read max_huge_pages from %s failed\n", MAX_HUGEPAGE_FILE); close(hp_params_fd); goto done; } number_huge_pages = strtoul(max_hp_str, &stop, 0); if (*stop != '\n') { QZ_ERROR("convert from %s to size_t failed\n", max_hp_str); close(hp_params_fd); goto done; } QZ_PRINT("After qzInit, number_huge_pages in parent process is %d\n", (int)number_huge_pages); close(hp_params_fd); wait(&status); } else if (pid == 0) { sleep(2); QZ_PRINT("This is child process, my pid = %d\n", getpid()); QZ_PRINT("This is child process, my ppid = %d\n", getppid()); g_process.qz_init_status = QZ_NONE; QZ_PRINT("Before qzInit, qz_init_status in child process is %d\n", g_process.qz_init_status); if (!((TestArg_T *)arg)->init_engine_disabled) { rc = qzInit(&sess, ((TestArg_T *)arg)->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_PRINT("After qzInit, qz_init_status in child process is %d\n", g_process.qz_init_status); QZ_PRINT("instID in child process is %s\n", g_process.qz_inst[0].instance_info.instID); } hp_params_fd = open(MAX_HUGEPAGE_FILE, O_RDONLY); if (hp_params_fd < 0) { QZ_ERROR("Open %s failed\n", MAX_HUGEPAGE_FILE); goto done; } if (read(hp_params_fd, max_hp_str, sizeof(max_hp_str)) < 0) { QZ_ERROR("Read max_huge_pages from %s failed\n", MAX_HUGEPAGE_FILE); close(hp_params_fd); goto done; } number_huge_pages = strtoul(max_hp_str, &stop, 0); if (*stop != '\n') { QZ_ERROR("convert from %s to size_t failed\n", max_hp_str); close(hp_params_fd); goto done; } QZ_PRINT("After qzInit, number_huge_pages in child process is %d\n", (int)number_huge_pages); close(hp_params_fd); exit(0); } else { perror("fork"); } done: pthread_exit((void *)NULL); } void *qzDecompressStreamWithBufferError(void *thd_arg) { int rc; unsigned char *src = NULL, *dest = NULL; size_t src_sz, dest_sz; QzStream_T decomp_strm = {0}; QzSessionParams_T params = {0}; unsigned int last = 1; TestArg_T *test_arg = (TestArg_T *)thd_arg; const int gen_data = test_arg->gen_data; QzSession_T sess = {0}; QZ_DEBUG("Hello from qzDecompressStreamWithBufferError\n"); rc = qzInit(&sess, test_arg->sw_backup); if (QZ_INIT_FAIL(rc)) { pthread_exit((void *)"qzInit failed"); } QZ_DEBUG("qzInit rc = %d\n", rc); if (qzGetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: fail to get default params.\n"); goto done; } params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT - 1; params.sw_backup = 0; if (qzSetDefaults(¶ms) != QZ_OK) { QZ_ERROR("Err: set params fail with incorrect compress params.\n"); goto done; } //set by default configurations rc = qzSetupSession(&sess, NULL); if (QZ_SETUP_SESSION_FAIL(rc)) { pthread_exit((void *)"qzSetupSession failed"); } QZ_DEBUG("qzSetupSession rc = %d\n", rc); if (gen_data) { src_sz = QATZIP_MAX_HW_SZ; dest_sz = QATZIP_MAX_HW_SZ; src = qzMalloc(src_sz, 0, COMMON_MEM); dest = qzMalloc(dest_sz, 0, COMMON_MEM); } else { src = test_arg->src; src_sz = test_arg->src_sz; dest = test_arg->comp_out; dest_sz = test_arg->comp_out_sz; } if (!src || !dest) { QZ_ERROR("Malloc failed\n"); goto done; } if (gen_data) { QZ_DEBUG("Gen Data...\n"); genRandomData(src, src_sz); } /*dest_recv_sz > dest_avail_len*/ decomp_strm.in = src; decomp_strm.out = dest; decomp_strm.in_sz = src_sz; decomp_strm.out_sz = dest_sz; rc = qzDecompressStream(&sess, &decomp_strm, last); assert(QZ_FAIL == rc); rc = qzEndStream(&sess, &decomp_strm); done: if (gen_data) { qzFree(src); qzFree(dest); } (void)qzTeardownSession(&sess); pthread_exit((void *)NULL); } #define STR_INTER(N) #N #define STR(N) STR_INTER(N) #define USAGE_STRING(MAX_LVL) \ "Usage: %s [options]\n" \ "\n" \ "Required options:\n" \ "\n" \ " -m testMode 1 test memcpy feature\n" \ " 2 test Memory\n" \ " 3 test comp/decomp by default parameters\n" \ " 4 test comp/decomp by configurable parameters\n" \ " 5 test comp/decomp by format parameters\n" \ " 6 test set default configurable parameters\n" \ "\n" \ "Optional options can be:\n" \ "\n" \ " -i inputfile input source file\n" \ " default by random generate data \n" \ " -t thread_count maximum forks permitted in the current thread\n" \ " 0 means no forking permitted. \n" \ " -l loop count default is 2\n" \ " -v verify, disabled by default\n" \ " -e init engine enable | disable. enabled by default\n" \ " -s init session enable | disable. enabled by default\n" \ " -A comp_algorithm deflate | lz4 | lz4s\n" \ " -B swBack 0 means disable sw\n" \ " 1 means enable sw\n" \ " -C hw_buff_sz default 64K\n" \ " -b block_size If set this option, the test will split test\n" \ " data into pieces. qzCompress/qzDecompress will\n"\ " de/compress block_size bytes every time.\n" \ " It must be the power of 2. The minimum is 4k,\n" \ " and maximum is 1M. Default is -1, don't split \n" \ " the test data.\n" \ " -D direction comp | decomp | both\n" \ " -F format [comp format]:[orig data size]/...\n" \ " -L comp_lvl 1 - " STR(MAX_LVL) "\n" \ " -O data_fmt deflate | gzip | gzipext | deflate_4B | lz4 | lz4s\n"\ " -T huffmanType static | dynamic\n" \ " -r req_cnt_thrshold max in-flight request num, default is 16\n" \ " -S thread_sleep the unit is milliseconds, default is a random time\n" \ " -P polling set polling mode, default is periodical polling\n" \ " -M svm set perf mode with file input, default is non\n" \ " svm mode. When set to svm, all memory will\n" \ " be allocated with malloc instead of qzMalloc\n" \ " This option is only applied to test case 4\n" \ " -p compress_buf_type pinned | common, default is common\n" \ " This option is only applied to file compression test in case 4\n" \ " If set common, memory of compress buffer will be allocated through malloc\n" \ " If set pinned, memory of compress buffer will be allocated in huge page, the\n" \ " allocation limit is 2M\n" \ " -h Print this help message\n" void qzPrintUsageAndExit(char *progName) { QZ_ERROR(USAGE_STRING(COMP_LVL_MAXIMUM), progName); exit(-1); } static int qz_do_g_process_Check(void) { if (g_process.qz_init_status == QZ_OK && g_process.sw_backup == 1 && (g_process.num_instances == G_PROCESS_NUM_INSTANCES_12 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_4 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_16 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_32 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_8 || g_process.num_instances == G_PROCESS_NUM_INSTANCES_64) && g_process.qat_available == CPA_TRUE) { return QZ_OK; } else { return QZ_FAIL; } } int main(int argc, char *argv[]) { int rc = 0, ret = 0, rc_check = 0; int i = 0; void *p_rc; int thread_count = 1, test = 0; ServiceType_T service = COMP; pthread_t threads[100] = {0}; TestArg_T test_arg[100] = {0}; struct sigaction s1; int block_size = -1; PinMem_T compress_buf_type = COMMON_MEM; TestArg_T args = {0}; unsigned char *input_buf = NULL; unsigned int input_buf_len = QATZIP_MAX_HW_SZ; int thread_sleep = 0; s1.sa_handler = sigInt; sigemptyset(&s1.sa_mask); s1.sa_flags = 0; sigaction(SIGINT, &s1, NULL); const char *optstring = "m:t:A:C:D:F:L:T:i:l:e:s:r:B:O:S:P:M:b:p:vh"; int opt = 0, loop_cnt = 2, verify = 0; int disable_init_engine = 0, disable_init_session = 0; char *stop = NULL; QzThdOps *qzThdOps = NULL; QzBlock_T *qzBlocks = NULL; errno = 0; QzSessionParamsDeflate_T default_params = {{0}}; rc = qzGetDefaultsDeflate(&default_params); if (rc != QZ_OK) { QZ_ERROR("Get default params error\n"); return -1; } args.test_format = TEST_GZIPEXT; args.comp_algorithm = default_params.common_params.comp_algorithm; args.sw_backup = default_params.common_params.sw_backup; args.hw_buff_sz = default_params.common_params.hw_buff_sz; args.comp_lvl = default_params.common_params.comp_lvl; args.huffman_hdr = default_params.huffman_hdr; args.polling_mode = default_params.common_params.polling_mode; args.req_cnt_thrshold = default_params.common_params.req_cnt_thrshold; args.max_forks = default_params.common_params.max_forks; while ((opt = getopt(argc, argv, optstring)) != -1) { switch (opt) { case 'm': // test case test = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error input: %s\n", optarg); return -1; } break; case 't': thread_count = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); args.max_forks = thread_count; if (*stop != '\0' || errno || thread_count > 100) { QZ_ERROR("Error thread count arg: %s\n", optarg); return -1; } break; case 'A': if (strcmp(optarg, "deflate") == 0) { args.comp_algorithm = QZ_DEFLATE; } else if (strcmp(optarg, "lz4") == 0) { args.comp_algorithm = QZ_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { args.comp_algorithm = QZ_LZ4s; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'O': if (strcmp(optarg, "deflate") == 0) { args.test_format = TEST_DEFLATE; } else if (strcmp(optarg, "gzip") == 0) { args.test_format = TEST_GZIP; } else if (strcmp(optarg, "gzipext") == 0) { args.test_format = TEST_GZIPEXT; } else if (strcmp(optarg, "deflate_4B") == 0) { args.test_format = TEST_DEFLATE_4B; } else if (strcmp(optarg, "lz4") == 0) { args.test_format = TEST_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { args.test_format = TEST_LZ4S; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'B': args.sw_backup = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno || (args.sw_backup != 0 && args.sw_backup != 1)) { QZ_ERROR("Error input: %s\n", optarg); return -1; } break; case 'C': args.hw_buff_sz = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno || args.hw_buff_sz > USDM_ALLOC_MAX_SZ / 2) { QZ_ERROR("Error chunkSize arg: %s\n", optarg); return -1; } break; case 'D': if (strcmp(optarg, "comp") == 0) { service = COMP; } else if (strcmp(optarg, "decomp") == 0) { service = DECOMP; } else if (strcmp(optarg, "both") == 0) { service = BOTH; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'F': qzBlocks = parseFormatOption(optarg); if (NULL == qzBlocks) { QZ_ERROR("Error format arg: %s\n", optarg); return -1; } break; case 'L': args.comp_lvl = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno || \ args.comp_lvl > COMP_LVL_MAXIMUM || args.comp_lvl <= 0) { QZ_ERROR("Error compLevel arg: %s\n", optarg); return -1; } break; case 'T': if (strcmp(optarg, "static") == 0) { args.huffman_hdr = QZ_STATIC_HDR; } else if (strcmp(optarg, "dynamic") == 0) { args.huffman_hdr = QZ_DYNAMIC_HDR; } else { QZ_ERROR("Error huffman arg: %s\n", optarg); return -1; } break; case 'l': loop_cnt = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error loop count arg: %s\n", optarg); return -1; } break; case 'v': verify = 1; break; case 'i': g_input_file_name = optarg; break; case 'e': if (strcmp(optarg, "enable") == 0) { disable_init_engine = 0; } else if (strcmp(optarg, "disable") == 0) { disable_init_engine = 1; } else { QZ_ERROR("Error init qat engine arg: %s\n", optarg); return -1; } break; case 's': if (strcmp(optarg, "enable") == 0) { disable_init_session = 0; } else if (strcmp(optarg, "disable") == 0) { disable_init_session = 1; } else { QZ_ERROR("Error init qat session arg: %s\n", optarg); return -1; } break; case 'r': args.req_cnt_thrshold = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error req_cnt_thrshold arg: %s\n", optarg); return -1; } break; case 'S': thread_sleep = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno) { QZ_ERROR("Error thread_sleep arg: %s\n", optarg); return -1; } thread_sleep *= 1000; break; case 'P': if (strcmp(optarg, "busy") == 0) { args.polling_mode = QZ_BUSY_POLLING; } else { QZ_ERROR("Error set polling mode: %s\n", optarg); return -1; } break; case 'M': if (strcmp(optarg, "svm") == 0) { g_perf_svm = true; } else { QZ_ERROR("Error set perf mode: %s\n", optarg); return -1; } break; case 'b': block_size = GET_LOWER_32BITS(strtol(optarg, &stop, 0)); if (*stop != '\0' || errno || ((block_size & (block_size - 1)) != 0) || block_size < 4096 || block_size > 1024 * 1024) { QZ_ERROR("Error block size arg: %s, please set it to the power of 2 in range of 4k to 1M.\n", optarg); return -1; } break; case 'p': if (strcmp(optarg, "pinned") == 0) { compress_buf_type = PINNED_MEM; } else if (strcmp(optarg, "common") == 0) { compress_buf_type = COMMON_MEM; } else { QZ_ERROR("Error compress_buf_type arg: %s\n", optarg); return -1; } break; default: qzPrintUsageAndExit(argv[0]); } } if (test == 0) { qzPrintUsageAndExit(argv[0]); } switch (test) { case 1: QZ_ERROR("Test mode 1 has been removed\n"); return 0; case 2: qzThdOps = qzMemFuncTest; break; case 3: QZ_ERROR("Test mode 3 has been removed\n"); return 0; case 4: qzThdOps = qzCompressAndDecompress; break; case 5: qzThdOps = qzCompressDecompressWithFormatOption; break; case 6: qzThdOps = qzSetupParamFuncTest; break; case 7: qzThdOps = qzDecompressSwQz; break; case 8: qzThdOps = qzCompressDecompressSwQZMixed; break; case 9: qzThdOps = qzCompressStreamAndDecompress; break; case 10: qzThdOps = qzCompressStreamOnCommonMem; break; case 11: qzThdOps = qzCompressStreamOutput; break; case 12: qzThdOps = qzDecompressStreamInput; break; case 13: qzThdOps = qzCompressStreamInvalidChunkSize; break; case 14: qzThdOps = qzCompressStreamInvalidQzStreamParam; break; case 15: qzThdOps = qzDecompressStreamNegParam; break; case 16: qzThdOps = qzEndStreamNegParam; break; case 17: return qzFuncTests(); break; case 18: test_thread_safe_flag = 1; qzThdOps = qzCompressAndDecompress; break; case 19: qzThdOps = qzInitPcieCountCheck; break; case 20: qzThdOps = qzCompressStreamWithPendingOut; break; case 21: qzThdOps = forkResourceCheck; break; case 22: qzThdOps = qzDecompressStreamWithBufferError; break; default: goto done; } if (g_input_file_name != NULL) { FILE *file; struct stat file_state; if (stat(g_input_file_name, &file_state)) { QZ_ERROR("ERROR: fail to get stat of file %s\n", g_input_file_name); return -1; } input_buf_len = GET_LOWER_32BITS((file_state.st_size > QATZIP_MAX_HW_SZ ? QATZIP_MAX_HW_SZ : file_state.st_size)); if (test == 4 || test == 10 || test == 11 || test == 12) { input_buf_len = GET_LOWER_32BITS(file_state.st_size); } if (compress_buf_type == PINNED_MEM) { if (input_buf_len > MAX_HUGE_PAGE_SZ) { QZ_ERROR("ERROR: only can allocate 2M memory in huge page\n"); return -1; } input_buf = qzMalloc(input_buf_len, 0, PINNED_MEM); } else { input_buf = malloc(input_buf_len); } if (!input_buf) { QZ_ERROR("ERROR: fail to alloc %d bytes of memory with qzMalloc\n", input_buf_len); return -1; } file = fopen(g_input_file_name, "rb"); if (!file) { QZ_ERROR("ERROR: fail to read file %s\n", g_input_file_name); goto done; } if (fread(input_buf, 1, input_buf_len, file) != input_buf_len) { QZ_ERROR("ERROR: fail to read file %s\n", g_input_file_name); fclose(file); goto done; } else { QZ_DEBUG("Read %d bytes from file %s\n", input_buf_len, g_input_file_name); } fclose(file); } for (i = 0; i < thread_count; i++) { test_arg[i] = args; test_arg[i].thd_id = i; test_arg[i].service = service; test_arg[i].verify_data = verify; test_arg[i].debug = 0; test_arg[i].count = loop_cnt; test_arg[i].src_sz = GET_LOWER_32BITS(input_buf_len); if (compress_buf_type == PINNED_MEM) { test_arg[i].comp_out_sz = test_arg[i].src_sz; test_arg[i].src = input_buf; test_arg[i].comp_out = qzMalloc(test_arg[i].comp_out_sz, 0, PINNED_MEM); test_arg[i].decomp_out_sz = test_arg[i].src_sz; test_arg[i].decomp_out = qzMalloc(test_arg[i].decomp_out_sz, 0, PINNED_MEM); } else { test_arg[i].comp_out_sz = test_arg[i].src_sz * 2; test_arg[i].src = input_buf; test_arg[i].comp_out = malloc(test_arg[i].comp_out_sz); test_arg[i].decomp_out_sz = test_arg[i].src_sz * 5; test_arg[i].decomp_out = malloc(test_arg[i].decomp_out_sz); } test_arg[i].gen_data = g_input_file_name ? 0 : 1; test_arg[i].init_engine_disabled = disable_init_engine; test_arg[i].init_sess_disabled = disable_init_session; test_arg[i].ops = qzThdOps; test_arg[i].blks = qzBlocks; test_arg[i].thread_sleep = thread_sleep; test_arg[i].block_size = block_size; if (!test_arg[i].comp_out || !test_arg[i].decomp_out) { QZ_ERROR("ERROR: fail to create memory for thread %d\n", i); goto done; } } srand((uint32_t)getpid()); (void)gettimeofday(&g_timer_start, NULL); #ifdef ENABLE_THREAD_BARRIER pthread_barrier_init(&g_bar, NULL, thread_count); #endif for (i = 0; i < thread_count; i++) { rc = pthread_create(&threads[i], NULL, test_arg[i].ops, (void *)&test_arg[i]); if (0 != rc) { QZ_ERROR("Error from pthread_create %d\n", rc); goto done; } } #ifndef ENABLE_THREAD_BARRIER /*for qzCompressAndDecompress test*/ if (test == 4 || test == 18) { ret = pthread_mutex_lock(&g_cond_mutex); if (ret != 0) { QZ_ERROR("Failure to get Mutex Lock, status = %d\n", ret); goto done; } while (g_ready_thread_count < thread_count) { ret = pthread_cond_wait(&g_ready_cond, &g_cond_mutex); if (ret != 0) { pthread_mutex_unlock(&g_cond_mutex); QZ_ERROR("Failure calling pthread_cond_wait, status = %d\n", ret); goto done; } } g_ready_to_start = 1; ret = pthread_cond_broadcast(&g_start_cond); if (ret != 0) { pthread_mutex_unlock(&g_cond_mutex); QZ_ERROR("Failure calling pthread_cond_broadcast, status = %d\n", ret); goto done; } ret = pthread_mutex_unlock(&g_cond_mutex); if (ret != 0) { QZ_ERROR("Failure to release Mutex Lock, status = %d\n", ret); goto done; } } #endif for (i = 0; i < thread_count; i++) { timeCheck(10, i); rc = pthread_join(threads[i], (void *)&p_rc); if (0 != rc) { QZ_ERROR("Error from pthread_join %d\n", rc); break; } if (NULL != p_rc) { QZ_ERROR("Error from pthread_exit %s\n", (char *)p_rc); ret = -1; } } #ifdef ENABLE_THREAD_BARRIER pthread_barrier_destroy(&g_bar); #endif if (test == 18) { rc_check = qz_do_g_process_Check(); if (QZ_OK == rc_check) { QZ_PRINT("Check g_process PASSED\n"); } else { ret = -1; QZ_PRINT("Check g_process FAILED\n"); } } done: if (NULL != qzBlocks) { QzBlock_T *tmp, *blk = qzBlocks; while (blk) { tmp = blk; blk = blk->next; free(tmp); } } /* free memory */ if (NULL != input_buf) { if (compress_buf_type == PINNED_MEM) { qzFree(input_buf); } else { free(input_buf); } } for (i = 0; i < thread_count; i++) { if (NULL != test_arg[i].comp_out) { if (compress_buf_type == PINNED_MEM) { qzFree(test_arg[i].comp_out); } else { free(test_arg[i].comp_out); } } if (NULL != test_arg[i].decomp_out) { if (compress_buf_type == PINNED_MEM) { qzFree(test_arg[i].decomp_out); } else { free(test_arg[i].decomp_out); } } } return (ret != 0) ? ret : rc; } QATzip-1.2.1/test/performance_tests/000077500000000000000000000000001465165016500173765ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/000077500000000000000000000000001465165016500216425ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/4xxx/000077500000000000000000000000001465165016500225555ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev0.conf000066400000000000000000000127141465165016500252620ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev1.conf000066400000000000000000000127141465165016500252630ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev2.conf000066400000000000000000000127141465165016500252640ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev3.conf000066400000000000000000000127141465165016500252650ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev4.conf000066400000000000000000000127141465165016500252660ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev5.conf000066400000000000000000000127141465165016500252670ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev6.conf000066400000000000000000000127141465165016500252700ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/4xxx/4xxx_dev7.conf000066400000000000000000000127141465165016500252710ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # ################################################################ [GENERAL] ServicesEnabled = dc ConfigVersion = 2 #Default value for FW Auth loading FirmwareAuthEnabled = 1 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable SSF features (CNV and BnP) StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # Default value for power management idle interrupt delay PmIdleInterruptDelay = 0 # This flag is to enable power management idle support PmIdleSupport = 1 # This flag is to enable key protection technology KptEnabled = 1 # Define the maximum SWK count per function can have # Default value is 1, the maximum value is 128 KptMaxSWKPerFn = 1 # Define the maximum SWK count per pasid can have # Default value is 1, the maximum value is 128 KptMaxSWKPerPASID = 1 # Define the maximum SWK lifetime in second # Default value is 0 (eternal of life) # The maximum value is 31536000 (one year) KptMaxSWKLifetime = 31536000 # Flag to define whether to allow SWK to be shared among processes # Default value is 0 (shared mode is off) KptSWKShared = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 # Data Compression - Kernel instance #0 Dc0Name = "IPComp0" Dc0IsPolled = 0 Dc0CoreAffinity = 0 ############################################## # ADI Section for Scalable IOV ############################################## [SIOV] NumberAdis = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 6 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 1 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 1 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity =2 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity =3 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity =4 QATzip-1.2.1/test/performance_tests/config_file/c3xxx/000077500000000000000000000000001465165016500227175ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/c3xxx/c3xxx_dev0.conf000066400000000000000000000132361465165016500255660ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # ################################################################ [GENERAL] ServicesEnabled = dc # Set the service profile to determine available features # ===================================================================== # DEFAULT CRYPTO COMPRESSION CUSTOM1 # Asymmetric Crypto * * * # Symmetric Crypto * * * # Hash * * * * # Cipher * * * # MGF KeyGen * * # SSL/TLS KeyGen * * * # HKDF * * # Compression * * * # Decompression (stateless) * * * # Decompression (stateful) * * # Service Chaining * # Device Utilization * * * # Rate Limiting * * * # ===================================================================== ServicesProfile = DEFAULT ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 1 NumProcesses = 4 LimitDevAccess = 1 # Crypto - User instance #0 Cy0Name = "SSL0" Cy0IsPolled = 1 # List of core affinities Cy0CoreAffinity = 0 # Crypto - User instance #1 Cy1Name = "SSL1" Cy1IsPolled = 1 # List of core affinities Cy1CoreAffinity = 1 # Crypto - User instance #2 Cy2Name = "SSL2" Cy2IsPolled = 1 # List of core affinities Cy2CoreAffinity = 2 # Crypto - User instance #3 Cy3Name = "SSL3" Cy3IsPolled = 1 # List of core affinities Cy3CoreAffinity = 3 # Crypto - User instance #4 Cy4Name = "SSL4" Cy4IsPolled = 1 # List of core affinities Cy4CoreAffinity = 4 # Crypto - User instance #5 Cy5Name = "SSL5" Cy5IsPolled = 1 # List of core affinities Cy5CoreAffinity = 5 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 1 QATzip-1.2.1/test/performance_tests/config_file/c6xx/000077500000000000000000000000001465165016500225325ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/c6xx/c6xx_dev0.conf000066400000000000000000000112671465165016500252160ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.2.1/test/performance_tests/config_file/c6xx/c6xx_dev1.conf000066400000000000000000000112671465165016500252170ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.2.1/test/performance_tests/config_file/c6xx/c6xx_dev2.conf000066400000000000000000000112671465165016500252200ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 KptEnabled = 0 # This flag is to enable SSF features StorageEnabled = 0 # Disable public key crypto and prime number # services by specifying a value of 1 (default is 0) PkeServiceDisabled = 0 # Specify size of intermediate buffers for which to # allocate on-chip buffers. Legal values are 32 and # 64 (default is 64). Specify 32 to optimize for # compressing buffers <=32KB in size. DcIntermediateBufferSizeInKB = 64 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.2.1/test/performance_tests/config_file/dh895xcc/000077500000000000000000000000001465165016500232015ustar00rootroot00000000000000QATzip-1.2.1/test/performance_tests/config_file/dh895xcc/dh895xcc_dev0.conf000066400000000000000000000105131465165016500263250ustar00rootroot00000000000000################################################################ # This file is provided under a dual BSD/GPLv2 license. When using or # redistributing this file, you may do so under either license. # # GPL LICENSE SUMMARY # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # 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 # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. # The full GNU General Public License is included in this distribution # in the file called LICENSE.GPL. # # Contact Information: # Intel Corporation # # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # # version: QAT1.7.L.4.5.0-00034 ################################################################ [GENERAL] ServicesEnabled = cy;dc ConfigVersion = 2 #Default values for number of concurrent requests*/ CyNumConcurrentSymRequests = 512 CyNumConcurrentAsymRequests = 64 #Statistics, valid values: 1,0 statsGeneral = 1 statsDh = 1 statsDrbg = 1 statsDsa = 1 statsEcc = 1 statsKeyGen = 1 statsDc = 1 statsLn = 1 statsPrime = 1 statsRsa = 1 statsSym = 1 # This flag is to enable device auto reset on heartbeat error AutoResetOnError = 0 # This flag is to enable SSF features StorageEnabled = 0 ############################################## # Kernel Instances Section ############################################## [KERNEL] NumberCyInstances = 0 NumberDcInstances = 0 # Crypto - Kernel instance #0 Cy0Name = "IPSec0" Cy0IsPolled = 0 Cy0CoreAffinity = 0 ############################################## # User Process Instance Section ############################################## [SHIM] NumberCyInstances = 0 NumberDcInstances = 4 NumProcesses = 8 LimitDevAccess = 1 # Crypto - User instance #0 #Cy0Name = "SSL0" #Cy0IsPolled = 1 ## List of core affinities #Cy0CoreAffinity = 0 # Data Compression - User instance #0 Dc0Name = "Dc0" Dc0IsPolled = 1 # List of core affinities Dc0CoreAffinity = 0 # Data Compression - User instance #1 Dc1Name = "Dc1" Dc1IsPolled = 1 # List of core affinities Dc1CoreAffinity = 0 # Data Compression - User instance #2 Dc2Name = "Dc2" Dc2IsPolled = 1 # List of core affinities Dc2CoreAffinity = 0 # Data Compression - User instance #3 Dc3Name = "Dc3" Dc3IsPolled = 1 # List of core affinities Dc3CoreAffinity = 0 QATzip-1.2.1/test/performance_tests/run_perf_test.sh000077500000000000000000000106631465165016500226220ustar00rootroot00000000000000#! /bin/bash ################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ set -e echo "***QZ_ROOT run_perf_test.sh start" rm -f result_comp_stderr rm -f result_decomp_stderr CURRENT_PATH=`dirname $(readlink -f "$0")` #check whether qatzip-test exists if [ ! -f "$QZ_ROOT/test/qatzip-test" ]; then echo "$QZ_ROOT/test/qatzip-test: No such file. Compile first!" exit 1 fi #get the type of QAT hardware platform=`lspci | grep Co-processor | awk '{print $6}' | head -1` if [[ $platform != "37c8" && $platform != "4940" ]] then platform=`lspci | grep Co-processor | awk '{print $5}' | head -1` if [[ $platform != "DH895XCC" && $platform != "C62x" ]] then platform=`lspci | grep Co-processor | awk '{print $7}' | head -1` if [ $platform != "C3000" ] then echo "Unsupported Platform: `lspci | grep Co-processor` " exit 1 fi fi fi echo "platform=$platform" #Replace the driver configuration files and configure hugepages echo "Replace the driver configuration files and configure hugepages." if [[ $platform = "37c8" || $platform = "C62x" ]] then process=24 \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev0.conf /etc \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev1.conf /etc \cp $CURRENT_PATH/config_file/c6xx/c6xx_dev2.conf /etc elif [ $platform = "DH895XCC" ] then process=8 \cp $CURRENT_PATH/config_file/dh895xcc/dh895xcc_dev0.conf /etc elif [ $platform = "4940" ] then process=48 \cp $CURRENT_PATH/config_file/4xxx/4xxx*.conf /etc elif [ $platform = "C3000" ] then process=4 \cp $CURRENT_PATH/config_file/c3xxx/c3xxx_dev0.conf /etc fi service qat_service restart echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages rmmod usdm_drv insmod $ICP_ROOT/build/usdm_drv.ko max_huge_pages=1024 max_huge_pages_per_process=24 sleep 5 #Perform performance test echo "Perform performance test" thread=4 if [ $platform = "4940" ] then thread=1 fi echo > result_comp cpu_list=0 for((numProc_comp = 0; numProc_comp < $process; numProc_comp ++)) do taskset -c $cpu_list $QZ_ROOT/test/qatzip-test -m 4 -l 1000 -t $thread -D comp >> result_comp 2>> result_comp_stderr & cpu_list=$(($cpu_list + 1)) done wait compthroughput=`awk '{sum+=$8} END{print sum}' result_comp` echo "compthroughput=$compthroughput Gbps" echo > result_decomp cpu_list=0 for((numProc_decomp = 0; numProc_decomp < $process; numProc_decomp ++)) do taskset -c $cpu_list $QZ_ROOT/test/qatzip-test -m 4 -l 1000 -t $thread -D decomp >> result_decomp 2>> result_decomp_stderr & cpu_list=$(($cpu_list + 1)) done wait decompthroughput=`awk '{sum+=$8} END{print sum}' result_decomp` echo "decompthroughput=$decompthroughput Gbps" rm -f result_comp rm -f result_decomp echo "***QZ_ROOT run_perf_test.sh end" QATzip-1.2.1/utils/000077500000000000000000000000001465165016500140345ustar00rootroot00000000000000QATzip-1.2.1/utils/Makefile.am000066400000000000000000000061641465165016500160770ustar00rootroot00000000000000################################################################ # BSD LICENSE # # Copyright(c) 2007-2024 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of Intel Corporation nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ################################################################ bin_PROGRAMS = qzip qzip_SOURCES = \ qzip_7z.c \ qzip_main.c \ qzip.c qzip_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qzip_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) qzip_LDFLAGS = \ $(ICP_LDFLAGS) qzip_obj_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) if QATZIP_LZ4S_POSTPROCESS_AC noinst_PROGRAMS = qzstd qzstd_SOURCES = \ qzstd.c \ qzstd_main.c qzstd_CFLAGS = \ -I$(abs_top_srcdir)/include/ \ -I$(abs_top_srcdir)/src/ \ -I$(abs_top_srcdir)/utils/ \ $(COMMON_CFLAGS) \ $(ICP_INCLUDE_CFLAGS) qzstd_LDADD = \ $(abs_top_srcdir)/src/.libs/libqatzip.a \ $(QATLIB_FLAGS) \ $(USDMLIB_FLAGS) \ $(ZSTD_LIBADD) qzstd_LDFLAGS = \ $(ICP_LDFLAGS) endif qzip_obj_without_main: qzip.c qzip_7z.c $(CC) $^ -c $(qzip_obj_CFLAGS) QATzip-1.2.1/utils/qzip.c000066400000000000000000000704741465165016500151770ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" char const *const g_license_msg[] = { "Copyright (C) 2021 Intel Corporation.", 0 }; char *g_program_name = NULL; /* program name */ int g_decompress = 0; /* g_decompress (-d) */ int g_keep = 0; /* keep (don't delete) input files */ QzSession_T g_sess; QzipParams_T g_params_th = { .huffman_hdr = QZ_HUFF_HDR_DEFAULT, .direction = QZ_DIRECTION_DEFAULT, .data_fmt = QZIP_DEFLATE_GZIP_EXT, .comp_lvl = QZ_COMP_LEVEL_DEFAULT, .comp_algorithm = QZ_COMP_ALGOL_DEFAULT, .hw_buff_sz = QZ_HW_BUFF_SZ, .polling_mode = QZ_PERIODICAL_POLLING, .req_cnt_thrshold = 32 }; /* Estimate maximum data expansion after decompression */ const unsigned int g_bufsz_expansion_ratio[] = {5, 20, 50, 100}; /* Command line options*/ char const g_short_opts[] = "A:H:L:C:r:o:O:P:dfhkVR"; const struct option g_long_opts[] = { /* { name has_arg *flag val } */ {"decompress", 0, 0, 'd'}, /* decompress */ {"uncompress", 0, 0, 'd'}, /* decompress */ {"force", 0, 0, 'f'}, /* force overwrite of output file */ {"help", 0, 0, 'h'}, /* give help */ {"keep", 0, 0, 'k'}, /* keep (don't delete) input files */ {"version", 0, 0, 'V'}, /* display version number */ {"algorithm", 1, 0, 'A'}, /* set algorithm type */ {"huffmanhdr", 1, 0, 'H'}, /* set huffman header type */ {"level", 1, 0, 'L'}, /* set compression level */ {"chunksz", 1, 0, 'C'}, /* set chunk size */ {"output", 1, 0, 'O'}, /* set output header format(gzip, gzipext, 7z, deflate_4B, lz4, lz4s) */ {"recursive", 0, 0, 'R'}, /* set recursive mode when compressing a directory */ {"polling", 1, 0, 'P'}, /* set polling mode when compressing and decompressing */ { 0, 0, 0, 0 } }; const unsigned int USDM_ALLOC_MAX_SZ = (2 * 1024 * 1024 - 5 * 1024); void tryHelp(void) { QZ_PRINT("Try `%s --help' for more information.\n", g_program_name); exit(ERROR); } void help(void) { static char const *const help_msg[] = { "Compress or uncompress FILEs (by default, compress FILES in-place).", "", "Mandatory arguments to long options are mandatory for short options " "too.", "", " -A, --algorithm set algorithm type", " -d, --decompress decompress", " -f, --force force overwrite of output file and compress links", " -h, --help give this help", " -H, --huffmanhdr set huffman header type", " -k, --keep keep (don't delete) input files", " -V, --version display version number", " -L, --level set compression level", " -C, --chunksz set chunk size", " -O, --output set output header format(gzip|gzipext|7z|deflate_4B|lz4|lz4s)", " -r, set max in-flight request number", " -R, set Recursive mode for a directory", " -o, set output file name", " -P, --polling set polling mode, only supports busy polling settings", "", "With no FILE, read standard input.", 0 }; char const *const *p = help_msg; QZ_PRINT("Usage: %s [OPTION]... [FILE]...\n", g_program_name); while (*p) { QZ_PRINT("%s\n", *p++); } } void freeTimeList(RunTimeList_T *time_list) { RunTimeList_T *time_node = time_list; RunTimeList_T *pre_time_node = NULL; while (time_node) { pre_time_node = time_node; time_node = time_node->next; free(pre_time_node); } } void displayStats(RunTimeList_T *time_list, off_t insize, off_t outsize, int is_compress) { /* Calculate time taken (from begin to end) in micro seconds */ unsigned long us_begin = 0; unsigned long us_end = 0; double us_diff = 0; RunTimeList_T *time_node = time_list; while (time_node) { us_begin = time_node->time_s.tv_sec * 1000000 + time_node->time_s.tv_usec; us_end = time_node->time_e.tv_sec * 1000000 + time_node->time_e.tv_usec; us_diff += (us_end - us_begin); time_node = time_node->next; } if (insize) { assert(0 != us_diff); double size = (is_compress) ? insize : outsize; double throughput = (size * CHAR_BIT) / us_diff; /* in MB (megabytes) */ double compressionRatio = ((double)insize) / ((double)outsize); double spaceSavings = 1 - ((double)outsize) / ((double)insize); QZ_PRINT("Time taken: %9.3lf ms\n", us_diff / 1000); QZ_PRINT("Throughput: %9.3lf Mbit/s\n", throughput); if (is_compress) { QZ_PRINT("Space Savings: %9.3lf %%\n", spaceSavings * 100.0); QZ_PRINT("Compression ratio: %.3lf : 1\n", compressionRatio); } } } int doProcessBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int is_compress) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int buf_processed = 0; unsigned int buf_remaining = *src_len; unsigned int bytes_written = 0; unsigned int valid_dst_buf_len = dst_len; RunTimeList_T *time_node = time_list; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); assert(NULL != run_time); run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* Do actual work */ if (is_compress) { ret = qzCompress(sess, src, src_len, dst, &dst_len, 1); if (QZ_BUF_ERROR == ret && 0 == *src_len) { done = 1; } } else { ret = qzDecompress(sess, src, src_len, dst, &dst_len); if (QZ_DATA_ERROR == ret || (QZ_BUF_ERROR == ret && 0 == *src_len)) { done = 1; } } if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { const char *op = (is_compress) ? "Compression" : "Decompression"; QZ_ERROR("doProcessBuffer:%s failed with error: %d\n", op, ret); break; } gettimeofday(&run_time->time_e, NULL); bytes_written = fwrite(dst, 1, dst_len, dst_file); assert(bytes_written == dst_len); *dst_file_size += bytes_written; buf_processed += *src_len; buf_remaining -= *src_len; if (0 == buf_remaining) { done = 1; } src += *src_len; QZ_DEBUG("src_len is %u ,buf_remaining is %u\n", *src_len, buf_remaining); *src_len = buf_remaining; dst_len = valid_dst_buf_len; bytes_written = 0; } *src_len = buf_processed; return ret; } void doProcessFile(QzSession_T *sess, const char *src_file_name, const char *dst_file_name, int is_compress) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; unsigned int bytes_read = 0; unsigned long bytes_processed = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); assert(NULL != time_list_head); gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; //open file src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { QZ_PRINT("Open input file %s failed\n", src_file_name); exit(ERROR); } ret = fstat(src_fd, &src_file_stat); assert(!ret); if (S_ISBLK(src_file_stat.st_mode)) { /* ioctl return device size / 512, so device size = src_file_size * 512 */ if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { close(src_fd); perror(src_file_name); exit(ERROR); } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; if (is_compress) { dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); if (0 == dst_buffer_size) { perror("During SW compression, src file size is less than HW size!\n"); exit(ERROR); } } else { /* decompress */ dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; } if (0 == src_file_size && is_compress) { dst_buffer_size = 1024; } src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); src_file = fdopen(src_fd, "r"); assert(src_file != NULL); dst_file = fopen(dst_file_name, "w"); assert(dst_file != NULL); file_remaining = src_file_size; read_more = 1; do { if (read_more) { bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_PRINT("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } else { bytes_read = file_remaining; } puts((is_compress) ? "Compressing..." : "Decompressing..."); ret = doProcessBuffer(sess, src_buffer, &bytes_read, dst_buffer, dst_buffer_size, time_list_head, dst_file, &dst_file_size, is_compress); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { bytes_processed += bytes_read; if (0 != bytes_read) { if (-1 == fseek(src_file, bytes_processed, SEEK_SET)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { //dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer with size " "%u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; } file_remaining -= bytes_read; } while (file_remaining > 0); displayStats(time_list_head, src_file_size, dst_file_size, is_compress); exit: freeTimeList(time_list_head); fclose(src_file); fclose(dst_file); close(src_fd); free(src_buffer); free(dst_buffer); if (!g_keep && OK == ret) { unlink(src_file_name); } if (ret) { exit(ret); } } int qzipSetupSessionDeflate(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsDeflate_T deflate_params; status = qzGetDefaultsDeflate(&deflate_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } switch (params->data_fmt) { case QZIP_DEFLATE_4B: deflate_params.data_fmt = QZ_DEFLATE_4B; break; case QZIP_DEFLATE_GZIP: deflate_params.data_fmt = QZ_DEFLATE_GZIP; break; case QZIP_DEFLATE_GZIP_EXT: deflate_params.data_fmt = QZ_DEFLATE_GZIP_EXT; break; case QZIP_DEFLATE_RAW: deflate_params.data_fmt = QZ_DEFLATE_RAW; break; default: QZ_ERROR("Unsupported data format\n"); return ERROR; } deflate_params.huffman_hdr = params->huffman_hdr; deflate_params.common_params.direction = params->direction; deflate_params.common_params.comp_lvl = params->comp_lvl; deflate_params.common_params.comp_algorithm = params->comp_algorithm; deflate_params.common_params.hw_buff_sz = params->hw_buff_sz; deflate_params.common_params.polling_mode = params->polling_mode; deflate_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; status = qzSetupSessionDeflate(sess, &deflate_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qzipSetupSessionLZ4(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsLZ4_T lz4_params; status = qzGetDefaultsLZ4(&lz4_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } lz4_params.common_params.direction = params->direction; lz4_params.common_params.comp_lvl = params->comp_lvl; lz4_params.common_params.comp_algorithm = params->comp_algorithm; lz4_params.common_params.hw_buff_sz = params->hw_buff_sz; lz4_params.common_params.polling_mode = params->polling_mode; lz4_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; status = qzSetupSessionLZ4(sess, &lz4_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qzipSetupSessionLZ4S(QzSession_T *sess, QzipParams_T *params) { int status; QzSessionParamsLZ4S_T lz4s_params; status = qzGetDefaultsLZ4S(&lz4s_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } lz4s_params.common_params.direction = params->direction; lz4s_params.common_params.comp_lvl = params->comp_lvl; lz4s_params.common_params.comp_algorithm = params->comp_algorithm; lz4s_params.common_params.hw_buff_sz = params->hw_buff_sz; lz4s_params.common_params.polling_mode = params->polling_mode; lz4s_params.common_params.req_cnt_thrshold = params->req_cnt_thrshold; status = qzSetupSessionLZ4S(sess, &lz4s_params); if (status < 0) { QZ_ERROR("Session setup failed with error: %d\n", status); return ERROR; } return OK; } int qatzipSetup(QzSession_T *sess, QzipParams_T *params) { int status; QZ_DEBUG("mw>>> sess=%p\n", sess); status = qzInit(sess, 1); if (status != QZ_OK && status != QZ_DUPLICATE) { QZ_ERROR("QAT init failed with error: %d\n", status); return ERROR; } QZ_DEBUG("QAT init OK with error: %d\n", status); switch (params->data_fmt) { case QZIP_DEFLATE_4B: case QZIP_DEFLATE_GZIP: case QZIP_DEFLATE_GZIP_EXT: case QZIP_DEFLATE_RAW: status = qzipSetupSessionDeflate(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionDeflate fail with error: %d\n", status); } break; case QZIP_LZ4_FH: status = qzipSetupSessionLZ4(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionLZ4 fail with error: %d\n", status); } break; case QZIP_LZ4S_BK: status = qzipSetupSessionLZ4S(sess, params); if (status != OK) { QZ_ERROR("qzipSetupSessionLZ4S fail with error: %d\n", status); } break; default: QZ_ERROR("Unsupported data format\n"); return ERROR; } QZ_DEBUG("Session setup OK with error: %d\n", status); return 0; } int qatzipClose(QzSession_T *sess) { qzTeardownSession(sess); qzClose(sess); return 0; } QzSuffix_T getSuffix(const char *filename) { QzSuffix_T s = E_SUFFIX_UNKNOWN; size_t len = strlen(filename); if (len >= strlen(SUFFIX_GZ) && !strcmp(filename + (len - strlen(SUFFIX_GZ)), SUFFIX_GZ)) { s = E_SUFFIX_GZ; } else if (len >= strlen(SUFFIX_7Z) && !strcmp(filename + (len - strlen(SUFFIX_7Z)), SUFFIX_7Z)) { s = E_SUFFIX_7Z; } else if (len >= strlen(SUFFIX_LZ4) && !strcmp(filename + (len - strlen(SUFFIX_LZ4)), SUFFIX_LZ4)) { s = E_SUFFIX_LZ4; } else if (len >= strlen(SUFFIX_LZ4S) && !strcmp(filename + (len - strlen(SUFFIX_LZ4S)), SUFFIX_LZ4S)) { s = E_SUFFIX_LZ4S; } return s; } bool hasSuffix(const char *fname) { size_t len = strlen(fname); switch (g_params_th.data_fmt) { case QZIP_LZ4_FH: if (len >= strlen(SUFFIX_LZ4) && !strcmp(fname + (len - strlen(SUFFIX_LZ4)), SUFFIX_LZ4)) { return 1; } break; case QZIP_LZ4S_BK: if (len >= strlen(SUFFIX_LZ4S) && !strcmp(fname + (len - strlen(SUFFIX_LZ4S)), SUFFIX_LZ4S)) { return 1; } break; case QZIP_DEFLATE_RAW: case QZIP_DEFLATE_GZIP_EXT: case QZIP_DEFLATE_GZIP: case QZIP_DEFLATE_4B: default: if (len >= strlen(SUFFIX_GZ) && !strcmp(fname + (len - strlen(SUFFIX_GZ)), SUFFIX_GZ)) { return 1; } else if (len >= strlen(SUFFIX_7Z) && !strcmp(fname + (len - strlen(SUFFIX_7Z)), SUFFIX_7Z)) { return 1; } break; } return 0; } QzSuffixCheckStatus_T checkSuffix(QzSuffix_T suffix, int is_format_set) { if (E_SUFFIX_GZ == suffix) { if (!is_format_set) { // format is not specified, reassign data format by suffix instead of default value g_params_th.data_fmt = QZIP_DEFLATE_GZIP_EXT; return E_CHECK_SUFFIX_OK; } if (QZIP_DEFLATE_GZIP_EXT != g_params_th.data_fmt && QZIP_DEFLATE_GZIP != g_params_th.data_fmt && QZIP_DEFLATE_4B != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else if (E_SUFFIX_7Z == suffix) { if (!is_format_set) { g_params_th.data_fmt = QZIP_DEFLATE_RAW; return E_CHECK_SUFFIX_OK; } if (QZIP_DEFLATE_RAW != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else if (E_SUFFIX_LZ4 == suffix) { if (!is_format_set) { g_params_th.data_fmt = QZIP_LZ4_FH; return E_CHECK_SUFFIX_OK; } if (QZIP_LZ4_FH != g_params_th.data_fmt) { return E_CHECK_SUFFIX_FORMAT_UNMATCH; } else { return E_CHECK_SUFFIX_OK; } } else { //unsupported suffix return E_CHECK_SUFFIX_UNSUPPORT; } } int makeOutName(const char *in_name, const char *out_name, char *oname, int is_compress) { if (is_compress) { if (hasSuffix(in_name)) { QZ_ERROR("Warning: %s already has suffix -- unchanged\n", in_name); return -1; } /* add suffix */ if (g_params_th.data_fmt == QZIP_LZ4_FH) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_LZ4); } else if (g_params_th.data_fmt == QZIP_LZ4S_BK) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_LZ4S); } else if (g_params_th.data_fmt == QZIP_DEFLATE_RAW) { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_7Z); } else { snprintf(oname, MAX_PATH_LEN, "%s%s", out_name ? out_name : in_name, SUFFIX_GZ); } } else { if (!hasSuffix(in_name)) { QZ_ERROR("%s: Wrong suffix. Supported suffix: 7z/gz/lz4\n", in_name); return -1; } /* remove suffix */ snprintf(oname, MAX_PATH_LEN, "%s", out_name ? out_name : in_name); if (NULL == out_name) { if (g_params_th.data_fmt == QZIP_LZ4_FH) { oname[strlen(in_name) - strlen(SUFFIX_LZ4)] = '\0'; } else { oname[strlen(in_name) - strlen(SUFFIX_GZ)] = '\0'; } } } return 0; } /* Makes a complete file system path by adding a file name to the path of its * parent directory. */ void mkPath(char *path, const char *dirpath, char *file) { const int nprinted = snprintf(path, MAX_PATH_LEN, "%s/%s", dirpath, file); if (nprinted >= MAX_PATH_LEN || nprinted < 0) { /* truncated, or output error */ assert(0); } } void processDir(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress) { DIR *dir; struct dirent *entry; char inpath[MAX_PATH_LEN]; dir = opendir(in_name); assert(dir); while ((entry = readdir(dir))) { /* Ignore anything starting with ".", which includes the special * files ".", "..", as well as hidden files. */ if (entry->d_name[0] == '.') { continue; } /* Qualify the file with its parent directory to obtain a complete * path. */ mkPath(inpath, in_name, entry->d_name); processFile(sess, inpath, out_name, is_compress); } closedir(dir); } void processFile(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress) { int ret; struct stat fstat; struct timespec timebuf[2]; ret = stat(in_name, &fstat); if (ret) { perror(in_name); exit(-1); } if (S_ISDIR(fstat.st_mode)) { processDir(sess, in_name, out_name, is_compress); } else { char oname[MAX_PATH_LEN]; memset(oname, 0, MAX_PATH_LEN); if (makeOutName(in_name, out_name, oname, is_compress)) { return; } doProcessFile(sess, in_name, oname, is_compress); if (access(oname, F_OK) == 0) { //update src file stat to dst file memset(timebuf, 0, sizeof(timebuf)); timebuf[0].tv_nsec = UTIME_NOW; timebuf[1].tv_sec = fstat.st_mtime; utimensat(AT_FDCWD, oname, timebuf, 0); } } } void version() { char const *const *p = g_license_msg; QZ_PRINT("%s v%s\n", g_program_name, QZIP_VERSION); while (*p) { QZ_PRINT("%s\n", *p++); } } char *qzipBaseName(char *fname) { char *p; if ((p = strrchr(fname, '/')) != NULL) { fname = p + 1; } return fname; } void processStream(QzSession_T *sess, FILE *src_file, FILE *dst_file, int is_compress) { int ret = OK; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; off_t dst_file_size = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; unsigned int bytes_read = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); assert(NULL != time_list_head); gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; int pending_in = 0; int bytes_input = 0; src_buffer_size = SRC_BUFF_LEN; if (is_compress) { dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); if (0 == dst_buffer_size) { perror("During SW compression, src file size is less than HW size!\n"); exit(ERROR); } } else { /* decompress */ dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; } src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); read_more = 1; while (!feof(stdin)) { if (read_more) { bytes_read = fread(src_buffer + pending_in, 1, src_buffer_size - pending_in, src_file); if (0 == is_compress) { bytes_read += pending_in; bytes_input = bytes_read; pending_in = 0; } } ret = doProcessBuffer(sess, src_buffer, &bytes_read, dst_buffer, dst_buffer_size, time_list_head, dst_file, &dst_file_size, is_compress); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { if (!is_compress) { pending_in = bytes_input - bytes_read; } if (0 != bytes_read) { if (!is_compress && pending_in > 0) { memmove(src_buffer, src_buffer + bytes_read, src_buffer_size - bytes_read); } read_more = 1; } else if (QZ_BUF_ERROR == ret) { // dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer with size " "%u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; } } exit: freeTimeList(time_list_head); free(src_buffer); free(dst_buffer); if (ret) { exit(ret); } } QATzip-1.2.1/utils/qzip.h000066400000000000000000000667661465165016500152150ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _UTILS_QZIP_H #define _UTILS_QZIP_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* new QATzip interface */ #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include #include #include /* qzip version */ #define QZIP_VERSION "1.2.0" /* field offset in signature header */ #define SIGNATUREHEADER_OFFSET_BASE 8 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET 4 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_SIZE 12 #define SIGNATUREHEADER_OFFSET_NEXTHEADER_CRC 20 /* resolving status */ #define RESOLVE_STATUS_IN_HEADER 0x0001 #define RESOLVE_STATUS_IN_ARCHIVE_PROPERTIES 0x0002 #define RESOLVE_STATUS_IN_STREAMSINFO 0x0004 #define RESOLVE_STATUS_IN_FILESINFO 0x0008 #define RESOLVE_STATUS_IN_PACKINFO 0x0010 #define RESOLVE_STATUS_IN_CODERSINFO 0x0020 #define RESOLVE_STATUS_IN_SUBSTREAMSINFO 0x0040 /* definitions of 7z archive tags */ #define PROPERTY_ID_END 0x00 #define PROPERTY_ID_HEADER 0x01 #define PROPERTY_ID_ARCHIVE_PROPERTIES 0x02 #define PROPERTY_ID_ADDITIONAL_STREAMSINFO 0x03 #define PROPERTY_ID_MAIN_STREAMSINFO 0x04 #define PROPERTY_ID_FILESINFO 0x05 #define PROPERTY_ID_PACKINFO 0x06 #define PROPERTY_ID_UNPACKINFO 0x07 #define PROPERTY_ID_SUBSTREAMSINFO 0x08 #define PROPERTY_ID_SIZE 0x09 #define PROPERTY_ID_CRC 0x0a #define PROPERTY_ID_FOLDER 0x0b #define PROPERTY_ID_CODERS_UNPACK_SIZE 0x0c #define PROPERTY_ID_NUM_UNPACK_STREAM 0x0d #define PROPERTY_ID_EMPTY_STREAM 0x0e #define PROPERTY_ID_EMPTY_FILE 0x0f #define PROPERTY_ID_ANTI 0x10 #define PROPERTY_ID_NAME 0x11 #define PROPERTY_ID_CTIME 0x12 #define PROPERTY_ID_ATIME 0x13 #define PROPERTY_ID_MTIME 0x14 /* Support windows(low 16 bit) and unix(high 16 bit) */ #define PROPERTY_ID_ATTRIBUTES 0x15 #define PROPERTY_ID_COMMENT 0x16 #define PROPERTY_ID_ENCODED_HEADER 0x17 #define PROPERTY_ID_STARTPOS 0x18 #define PROPERTY_ID_DUMMY 0x19 #define PROPERTY_CONTENT_DUMMY 0x00 #define FLAG_ATTR_DEFINED_SET 0x01 #define FLAG_ATTR_DEFINED_UNSET 0x00 #define FLAG_ATTR_EXTERNAL_UNSET 0x00 /* 7z format version */ #define G_7ZHEADER_MAJOR_VERSION 0x00 #define G_7ZHEADER_MINOR_VERSION 0x04 /* default size for allocating memory for one node */ #define QZ_DIRLIST_DEFAULT_NUM_PER_NODE 100 #define QZ_FILELIST_DEFAULT_NUM_PER_NODE 1000 /* archiveproperties develop ID */ #define QZ7Z_DEVELOP_PREFIX 0x3ful #define QZ7Z_DEVELOP_ID ('Q'*1ul<<32|'A'<<24|'T'<<16|'7'<<8|'z') #define QZ7Z_DEVELOP_SUBID 0x0a01ul /* return codes from qzip */ #define OK 0 #define ERROR 1 /* internal return codes for functions that implement 7z format */ #define QZ7Z_OK OK #define QZ7Z_ERR_INVALID_SIZE -200 #define QZ7Z_ERR_OPEN -201 #define QZ7Z_ERR_OOM -202 #define QZ7Z_ERR_CONCAT_FILE -203 #define QZ7Z_ERR_STAT -204 #define QZ7Z_ERR_IOCTL -205 #define QZ7Z_ERR_END_HEADER -206 #define QZ7Z_ERR_NULL_INPUT_LIST -207 #define QZ7Z_ERR_REMOVE -208 #define QZ7Z_ERR_RESOLVE_END_HEADER -209 #define QZ7Z_ERR_NOT_EXPECTED_CHAR -210 #define QZ7Z_ERR_GETCWD -211 #define QZ7Z_ERR_READ_EOF -212 #define QZ7Z_ERR_READ_LESS -213 #define QZ7Z_ERR_WRITE_EOF -214 #define QZ7Z_ERR_WRITE_LESS -215 #define QZ7Z_ERR_MKDIR -216 #define QZ7Z_ERR_CHDIR -217 #define QZ7Z_ERR_CREATE_TEMP -218 #define QZ7Z_ERR_HEADER_CRC -219 #define QZ7Z_ERR_TIMES -220 #define QZ7Z_ERR_SIG_HEADER_BROKEN -221 #define QZ7Z_ERR_READLINK -222 #define QZ7Z_ERR_SIG_HEADER -223 #define QZ7Z_ERR_RESOLVE_SUBSTREAMS -224 #define QZ7Z_ERR_UNEXPECTED -225 #define MAX_PATH_LEN 1024 /* max pathname length */ #define SUFFIX_GZ ".gz" #define SUFFIX_7Z ".7z" #define SUFFIX_LZ4 ".lz4" #define SUFFIX_LZ4S ".lz4s" #define QZIP_GET_LOWER_32BITS(v) ((v) & 0xFFFFFFFF) typedef enum QzSuffix_E { E_SUFFIX_GZ, E_SUFFIX_7Z, E_SUFFIX_LZ4, E_SUFFIX_LZ4S, E_SUFFIX_UNKNOWN = 999 } QzSuffix_T; typedef enum QzSuffixCheckStatus_E { E_CHECK_SUFFIX_OK, E_CHECK_SUFFIX_UNSUPPORT, E_CHECK_SUFFIX_FORMAT_UNMATCH } QzSuffixCheckStatus_T; #define SRC_BUFF_LEN (512 * 1024 * 1024) typedef enum QzipDataFormat_E { QZIP_DEFLATE_4B = 0, /**< Data is in raw deflate format with 4 byte header */ QZIP_DEFLATE_GZIP, /**< Data is in deflate wrapped by GZip header and footer */ QZIP_DEFLATE_GZIP_EXT, /**< Data is in deflate wrapped by GZip extended header and footer */ QZIP_DEFLATE_RAW, /**< Data is in raw deflate format */ QZIP_LZ4_FH, /**< Data is in LZ4 format with frame headers */ QZIP_LZ4S_BK, /**< Data is in LZ4s format with block headers */ } QzipDataFormat_T; typedef struct QzipParams_S { QzHuffmanHdr_T huffman_hdr; QzDirection_T direction; QzipDataFormat_T data_fmt; unsigned int comp_lvl; unsigned char comp_algorithm; unsigned char force; unsigned char keep; unsigned int hw_buff_sz; unsigned int polling_mode; unsigned int recursive_mode; unsigned int req_cnt_thrshold; char *output_filename; } QzipParams_T; #define QZ7Z_PROPERTY_ID_INTEL7Z_1001 ((QZ7Z_DEVELOP_PREFIX << 56) | \ (QZ7Z_DEVELOP_ID << 16) | \ (QZ7Z_DEVELOP_SUBID)) /* check allocated memory */ #define CHECK_ALLOC_RETURN_VALUE(p) \ if (NULL == p) {\ printf("%s:%d oom\n", __FILE__, __LINE__); \ exit(-QZ7Z_ERR_OOM);\ } /* check fread return */ #define CHECK_FREAD_RETURN(ret, n) if((ret) != (n)) { \ if (feof(fp)) { \ fprintf(stderr, "fread reach EOF.\n"); \ exit(-QZ7Z_ERR_READ_EOF); \ } else { \ fprintf(stderr, "fread errors.\n"); \ exit(-QZ7Z_ERR_READ_LESS); \ } \ } /* check fwrite return */ #define CHECK_FWRITE_RETURN(ret, n) CHECK_FWRITE_RETURN_FP(fp, ret, n) #define CHECK_FWRITE_RETURN_FP(fp, ret, n) if((ret) != (n)) { \ if (feof((fp))) { \ fprintf(stderr, "fwrite reach EOF.\n"); \ exit(-QZ7Z_ERR_WRITE_EOF); \ } else { \ fprintf(stderr, "fwrite errors.\n"); \ exit(-QZ7Z_ERR_WRITE_LESS); \ } \ } typedef struct RunTimeList_S { struct timeval time_s; struct timeval time_e; struct RunTimeList_S *next; } RunTimeList_T; /* Windows FILETIME structure * contains a 64-bit value representing the number of 100-nanosecond intervals * since January 1, 1601 (UTC). */ /* 1601 to 1970 is 369 years plus 89 leap days */ #define NUM_DAYS (134774UL) /* time in seconds from 1601 Jan 1 to 1970 Jan 1 */ #define DELTA_TIME (NUM_DAYS * (24 * 60 * 60UL)) #define NANO_SEC 1000000000UL #define TICKS_PER_SEC 10000000UL typedef struct FILETIME { uint32_t low; uint32_t high; } FILETIME_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip linked list node structure * * @description * Qatzip linked list node structure * ******************************************************************************/ typedef struct QzListNode_S { uint32_t num; // number of allocated region per node uint32_t used; // used space of element void **items; struct QzListNode_S *next; } QzListNode_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip linked list head structure * * @description * Qatzip linked list head structure * ******************************************************************************/ typedef struct QzListHead_S { uint32_t total; // total elements uint32_t num; // number of allocated region per node QzListNode_T *next; } QzListHead_T; /** ****************************************************************************** * @ingroup qatZip * A file or a directory compressed by qatzip * * @description * This structure contains a file or directory and it's attributes * ******************************************************************************/ typedef struct Qz7zFileItem_S { char *fileName; /* dynamic allocated memory for filename(pathname) */ unsigned char isDir; /* 1byte */ unsigned char isEmpty; /* 1byte */ /* is empty file */ unsigned char isSymLink; /* 1byte */ /* is symbol link */ unsigned char isAnti; /* 1byte */ /* is anti file(on windows) */ uint32_t baseNameLength; /* base pathname length */ uint32_t nameLength; /* memory allocated length */ size_t size; /* for file it's file's length*/ uint32_t crc; uint32_t attribute; uint64_t atime; uint32_t atime_nano; uint64_t mtime; uint32_t mtime_nano; } Qz7zFileItem_T; /** ****************************************************************************** * @ingroup qatZip * 7z signature header * * @description * This structure contains a 7z signature header * ******************************************************************************/ typedef struct Qz7zSignatureHeader_S { unsigned char signature[6]; /* {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}*/ unsigned char majorVersion; /* 0x00 */ unsigned char minorVersion; /* 0x04 */ uint32_t startHeaderCRC; uint64_t nextHeaderOffset; uint64_t nextHeaderSize; uint32_t nextHeaderCRC; } Qz7zSignatureHeader_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info * * @description * This structure presents Coder info * ******************************************************************************/ typedef struct Qz7zDigest_S { unsigned char allAreDefined; uint64_t numStreams; uint64_t numDefined; uint32_t *crc; /* array: CRC[NumDefined] */ } Qz7zDigest_T; /** ****************************************************************************** * @ingroup qatZip * 7z Pack Info structure * * @description * This structure presents a 7z pack info * ******************************************************************************/ typedef struct Qz7zPackInfo_S { uint64_t PackPos; uint64_t NumPackStreams; uint64_t *PackSize; /* PackSize[NumPackStreams] */ Qz7zDigest_T *PackStreamDigests; /* not used */ } Qz7zPackInfo_T; /** ****************************************************************************** * @ingroup qatZip * First byte of 7z Coder Info structure * * @description * This structure contains some attributes of a coder * ******************************************************************************/ typedef union Qz7zCoderFirstByte_S { struct { unsigned CodecIdSize : 4; unsigned IsComplexCoder : 1; unsigned HasAttributes : 1; unsigned Reserved : 1; unsigned MoreAlterMethods: 1; /* not used: 0 for ever */ } st; unsigned char uc; } Qz7zCoderFirstByte_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info list * * @description * This structure is Coder info list node * ******************************************************************************/ typedef struct Qz7zCoder_S { Qz7zCoderFirstByte_T coderFirstByte; unsigned char *codecID ; /* CodecID[CodecIdSize] */ uint64_t numInStreams; /* if it is complex coder */ uint64_t numOutStreams; /* if it is complex coder */ uint64_t propertySize; /* if there are attributes */ unsigned char *properties; /* array: Properties[PropertiSize] if there are attributes */ struct Qz7zCoder_S *next; } Qz7zCoder_T; /** ****************************************************************************** * @ingroup qatZip * 7z Folder Info * * @description * This structure is Folder info * ******************************************************************************/ typedef struct Qz7zFolderInfo_S { uint64_t numCoders; Qz7zCoder_T *coder_list; QzListHead_T *items; /* fileitems list */ uint64_t numBindPairs; uint64_t *inIndex; /* array: InIndex[NumBindPairs] */ uint64_t *outIndex; /* array: InIndex[NumBindPairs] */ uint64_t numPackedStreams; uint64_t *index; /* array: Index[NumPackedStreams] */ } Qz7zFolderInfo_T; typedef struct Qz7zFolderLoc_S { QzListNode_T *node; unsigned int index; size_t pos; } Qz7zFolderLoc_T; typedef struct Qz7zFolderHandle_S { Qz7zFolderInfo_T *folder; Qz7zFolderLoc_T *loc; } Qz7zFolderHandle_T; /** ****************************************************************************** * @ingroup qatZip * 7z Coder Info * * @description * This structure presents Coder info * The folders points to an array of all the folders * This part contains all the folders info here, in one struct variable. * ******************************************************************************/ typedef struct Qz7zCodersInfo_S { uint64_t numFolders; Qz7zFolderInfo_T *folders; /* array folders[numFolders] */ uint64_t dataStreamIndex; uint64_t *unPackSize; /* array: unPackSize[numFolders] */ Qz7zDigest_T *unPackDigests; /* not used */ } Qz7zCodersInfo_T ; /** ****************************************************************************** * @ingroup qatZip * 7z Substreams Info * * @description * This structure presents Substreams info * ******************************************************************************/ typedef struct Qz7zSubstreamsInfo_S { uint64_t numFolders; uint64_t *numUnPackStreams; /* NumUnPackStreams[numFolders] */ uint64_t *unPackSize; /* unPackSize[AllNumFiles - 1], AllNumFiles is sum of the array NumUnPackStreamsInFolders */ Qz7zDigest_T *digests; /* points to digests structure with all non-empty files num*/ } Qz7zSubstreamsInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Streams Info structure * * @description * This structure presents a 7z streams info * ******************************************************************************/ typedef struct Qz7zStreamsInfo_S { Qz7zPackInfo_T *packInfo; Qz7zCodersInfo_T *codersInfo; Qz7zSubstreamsInfo_T *substreamsInfo; } Qz7zStreamsInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files Info structure * * @description * This structure presents a 7z files info. It is used for compressing * ******************************************************************************/ typedef struct Qz7zFilesInfo_S { uint64_t num; QzListHead_T *head[2]; } Qz7zFilesInfo_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files Info structure * * @description * This structure presents a 7z files info. It is used for decompressing * ******************************************************************************/ typedef struct Qz7zFilesInfo_DEC_S { uint64_t dir_num; uint64_t file_num; Qz7zFileItem_T *items; } Qz7zFilesInfo_Dec_T; /** ****************************************************************************** * @ingroup qatZip * 7z Files ArchiveProperties structure * * @description * This structure presents a 7z Archive Properties Info, if there are more * than one properties, the `next` points to the next property * ******************************************************************************/ typedef struct Qz7zArchiveProperty_S { uint64_t id; uint64_t size; unsigned char *data; struct Qz7zArchiveProperty_S *next; } Qz7zArchiveProperty_T; /** ****************************************************************************** * @ingroup qatZip * 7z End header structure * * @description * This structure contains a 7z end header * ******************************************************************************/ typedef struct Qz7zEndHeader_S { Qz7zArchiveProperty_T *propertyInfo; Qz7zStreamsInfo_T *streamsInfo; Qz7zFilesInfo_T *filesInfo; Qz7zFilesInfo_Dec_T *filesInfo_Dec; } Qz7zEndHeader_T; /** ****************************************************************************** * @ingroup qatZip * 7z Category * * @description * This structure presents a 7z category * ******************************************************************************/ typedef struct QzCatagory_S { unsigned char cat_id; const char *cat_name; QzListHead_T *cat_files; } QzCatagory_T; /** ****************************************************************************** * @ingroup qatZip * 7z Category table * * @description * This structure presents all categories * ******************************************************************************/ typedef struct QzCatagoryTable_S { unsigned int cat_num; QzCatagory_T *catas; /* array: catas[cat_num] */ } QzCatagoryTable_T; /** ****************************************************************************** * @ingroup qatZip * Qatzip items list structure * * @description * the structure is used for hold input arguments * items[0] is the list of all directory and empty file * items[1] is the list of all non-empty file * ******************************************************************************/ typedef struct Qz7zItemList_S { QzListHead_T *items[2]; QzCatagoryTable_T *table; } Qz7zItemList_T; /* create a list return list head */ QzListHead_T *qzListCreate(int num_per_node); /* Add one element's address to the list */ void qzListAdd(QzListHead_T *head, void **node); /* Get an element's address from a list */ void *qzListGet(QzListHead_T *head, int index); /* Free all allocated memory pointed by head */ void qzListDestroy(QzListHead_T *head); /* create the file items list */ Qz7zFileItem_T *fileItemCreate(char *pfilename); /* destroy the items list */ void itemListDestroy(Qz7zItemList_T *p); /* process the cmdline inputs */ Qz7zItemList_T *itemListCreate(int n, char **files); /* * resolve functions */ Qz7zSignatureHeader_T *resolveSignatureHeader(FILE *fp); Qz7zArchiveProperty_T *resolveArchiveProperties(FILE *fp); Qz7zPackInfo_T *resolvePackInfo(FILE *fp); Qz7zCodersInfo_T *resolveCodersInfo(FILE *fp); Qz7zSubstreamsInfo_T *resolveSubstreamsInfo(int n_folder, FILE *fp); Qz7zFilesInfo_Dec_T *resolveFilesInfo(FILE *fp); Qz7zStreamsInfo_T *resolveMainStreamsInfo(FILE *fp); Qz7zEndHeader_T *resolveEndHeader(FILE *fp, Qz7zSignatureHeader_T *sheader); /* create category list */ QzCatagoryTable_T *createCatagoryList(); int scanFilesIntoCatagory(Qz7zItemList_T *the_list); /* * generate functions */ Qz7zSignatureHeader_T *generateSignatureHeader(void); Qz7zArchiveProperty_T *generatePropertyInfo(void); Qz7zPackInfo_T *generatePackInfo(Qz7zItemList_T *the_list, size_t compressed_size); Qz7zFolderInfo_T *generateFolderInfo(Qz7zItemList_T *the_list, int n_folders); Qz7zCodersInfo_T *generateCodersInfo(Qz7zItemList_T *the_list); Qz7zDigest_T *generateDigestInfo(QzListHead_T *head); Qz7zSubstreamsInfo_T *generateSubstreamsInfo(Qz7zItemList_T *the_list); Qz7zFilesInfo_T *generateFilesInfo(Qz7zItemList_T *the_list); Qz7zEndHeader_T *generateEndHeader(Qz7zItemList_T *the_list, size_t compressed_size); /* * write function */ int writeSignatureHeader(Qz7zSignatureHeader_T *header, FILE *fp); size_t writeArchiveProperties(Qz7zArchiveProperty_T *property, FILE *fp, uint32_t *crc); size_t writePackInfo(Qz7zPackInfo_T *pack, FILE *fp, uint32_t *crc); size_t writeFolder(Qz7zFolderInfo_T *folder, FILE *fp, uint32_t *crc); size_t writeCodersInfo(Qz7zCodersInfo_T *coders, FILE *fp, uint32_t *crc); size_t writeDigestInfo(Qz7zDigest_T *digest, FILE *fp, uint32_t *crc); size_t writeStreamsInfo(Qz7zStreamsInfo_T *streams, FILE *fp, uint32_t *crc); size_t writeFilesInfo(Qz7zFilesInfo_T *files, FILE *fp, uint32_t *crc); size_t writeSubstreamsInfo(Qz7zSubstreamsInfo_T *substreams, FILE *fp, uint32_t *crc); size_t writeEndHeader(Qz7zEndHeader_T *header, FILE *fp, uint32_t *crc); /* * free functions */ void freePropertyInfo(Qz7zArchiveProperty_T *info); void freePackInfo(Qz7zPackInfo_T *info); void freeCodersInfo(Qz7zCodersInfo_T *info); void freeSubstreamsInfo(Qz7zSubstreamsInfo_T *info); void freeStreamsInfo(Qz7zStreamsInfo_T *info); void freeFilesInfo(Qz7zFilesInfo_T *info); void freeFilesDecInfo(Qz7zFilesInfo_Dec_T *info); void freeEndHeader(Qz7zEndHeader_T *eheader, int is_compress); /* the main API for compress into 7z format */ int qz7zCompress(QzSession_T *sess, Qz7zItemList_T *the_list, const char *out_name); /* the main API for decompress a 7z file */ int qz7zDecompress(QzSession_T *sess, const char *archive); /* * UINT64 conversion functions */ /* conversion from real uint64_t to UINT64 */ int getExtraByteNum(uint64_t n); int getUint64Bytes(uint64_t n, unsigned char *u64); /* conversion from UINT64 to uint64_t */ int getExtraByteNum2(uint8_t first); uint64_t getU64FromBytes(FILE *fp); #ifdef QZ7Z_DEBUG void printSignatureHeader(Qz7zSignatureHeader_T *sheader); void printEndHeader(Qz7zEndHeader_T *eheader); #endif /* create the directory in path of newdir */ int createDir(const char *newdir, int back); /* delete source files represented by the list */ int deleteSourceFile(Qz7zItemList_T *the_list); /* check whether the file is 7z archive */ int check7zArchive(const char *archive); /* check whether the filename is directory */ int checkDirectory(const char *filename); void freeTimeList(RunTimeList_T *time_list); void displayStats(RunTimeList_T *time_list, off_t insize, off_t outsize, int is_compress); void tryHelp(void); void help(void); void version(); char *qzipBaseName(char *fname); QzSuffix_T getSuffix(const char *filename); bool hasSuffix(const char *fname); QzSuffixCheckStatus_T checkSuffix(QzSuffix_T suffix, int is_format_set); int makeOutName(const char *in_name, const char *out_name, char *oname, int is_compress); /* Makes a complete file system path by adding a file name to the path of its * parent directory. */ void mkPath(char *path, const char *dirpath, char *file); /* * internal api functions */ int qatzipSetup(QzSession_T *sess, QzipParams_T *params); int qatzipClose(QzSession_T *sess); void processFile(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress); int doProcessBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int is_compress); void doProcessFile(QzSession_T *sess, const char *src_file_name, const char *dst_file_name, int is_compress); void processDir(QzSession_T *sess, const char *in_name, const char *out_name, int is_compress); void processStream(QzSession_T *sess, FILE *src_file, FILE *dst_file, int is_compress); int doCompressFile(QzSession_T *sess, Qz7zItemList_T *list, const char *dst_file_name); int doDecompressFile(QzSession_T *sess, const char *src_file_name); /* * extern declaration */ extern char const *const g_license_msg[2]; extern char *g_program_name; extern int g_decompress; /* g_decompress (-d) */ extern int g_keep; /* keep (don't delete) input files */ extern QzSession_T g_sess; extern QzipParams_T g_params_th; /* Estimate maximum data expansion after decompression */ extern const unsigned int g_bufsz_expansion_ratio[4]; /* Command line options*/ extern char const g_short_opts[]; extern const struct option g_long_opts[]; extern const unsigned int USDM_ALLOC_MAX_SZ; extern int errno; #endif QATzip-1.2.1/utils/qzip_7z.c000066400000000000000000003024451465165016500156130ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" #define OK 0 #define ERROR 1 static const unsigned char g_header_signature[] = { '7', 'z', 0xBC, 0xAF, 0x27, 0x1C }; static const char g_deflate_codecId[] = { 0x04, 0x01, 0x08 }; static const char g_property_data[] = { 'Q', 'A', 'T' }; static uint64_t const extra_byte_boundary[] = { 0x0, 0x7f, 0x3fff, 0x1fffff, 0xfffffff, 0x7ffffffff, 0x3ffffffffff, 0x1ffffffffffff, 0xffffffffffffff }; static uint8_t const first_byte_table[] = { 0, 0x80/* 1000 0000 */, 0xc0/* 1100 0000 */, 0xe0/* 1110 0000 */, 0xf0/* 1111 0000 */, 0xf8/* 1111 1000 */, 0xfc/* 1111 1100 */, 0xfe/* 1111 1110 */, 0xff/* 1111 1111 */ }; FILETIME_T unixtimeToFiletime(unsigned long t, uint32_t nsec) { FILETIME_T ft; unsigned long long secs = t * TICKS_PER_SEC + DELTA_TIME * TICKS_PER_SEC + nsec / 100; ft.low = (uint32_t)secs; ft.high = (uint32_t)(secs >> 32); return ft; } time_t filetimeToUnixtime(FILETIME_T ft) { time_t t; uint64_t ti; ti = (uint64_t)ft.high << 32; ti += ft.low; t = ti / TICKS_PER_SEC - DELTA_TIME; return t; } #define writeByte(b, fp, crc) writeTag(b, fp, crc) static size_t writeTag(unsigned char tag, FILE *fp, uint32_t *crc) { size_t n; n = fwrite(&tag, sizeof(unsigned char), 1, fp); CHECK_FWRITE_RETURN(n, 1) *crc = crc32(*crc, &tag, 1); return n; } static size_t writeTime(unsigned int t, FILE *fp, uint32_t *crc) { size_t n; n = fwrite(&t, sizeof(unsigned int), 1, fp); CHECK_FWRITE_RETURN(n, 1) *crc = crc32(*crc, (unsigned char *)&t, 4); return 4; } static size_t writeNumber(uint64_t u64, FILE *fp, uint32_t *crc) { uint64_t size; int n; unsigned char u64_bytes[9]; n = getUint64Bytes(u64, u64_bytes); size = fwrite(u64_bytes, sizeof(unsigned char), n, fp); CHECK_FWRITE_RETURN(size, n) *crc = crc32(*crc, u64_bytes, n); return size; } static unsigned char readByte(FILE *fp) { unsigned char c; int n; n = fread(&c, 1, 1, fp); CHECK_FREAD_RETURN(n, 1) return c; } static void skipNByte(int n, FILE *fp) { fseek(fp, n, SEEK_CUR); } static uint32_t readCRC(FILE *fp) { uint32_t crc; int n; n = fread(&crc, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1) return crc; } int getExtraByteNum2(uint8_t first) { int i; if (first == 0xff) return 8; for (i = 0; i < sizeof(first_byte_table) - 1; ++i) { if (first >= first_byte_table[i] && first < first_byte_table[i + 1]) break; } return i; } int getExtraByteNum(uint64_t n) { int i; int boundary_len = sizeof(extra_byte_boundary) / sizeof(extra_byte_boundary[0]); if (n == 0) return 0; for (i = 0; i < boundary_len; ++i) { if (n > extra_byte_boundary[i]) continue; break; } return i ? i - 1 : i; } /* * from UINT64 to uint64_t */ uint64_t getU64FromBytes(FILE *fp) { int i; int k; int extra; uint64_t ret; unsigned char c; uint8_t p = 0; unsigned char buf[8] = {0}; c = readByte(fp); extra = getExtraByteNum2(c); for (i = 0, k = 7; i < extra; ++i, --k) { p += 1 << k; } for (i = 0; i < extra; ++i) { buf[i] = readByte(fp); } if (extra != 7 && extra != 8) { buf[i] = c & ~p; } memcpy(&ret, buf, sizeof(buf)); return ret; } /** * get the number n's UINT64 form * n: the number * p: the bytes * return: total bytes */ int getUint64Bytes(uint64_t n, unsigned char *p) { int i; int extra = getExtraByteNum(n); uint64_t number = n; unsigned char first_byte; for (i = 0; i < extra; ++i) { number /= 0x100; } first_byte = number | first_byte_table[extra]; number = n; p[0] = first_byte; for (i = 0; i < extra; ++i) { p[i + 1] = number % 0x100; number /= 0x100; } return extra + 1; } /** * this means no category, every files are in one folder * the folder number/packed streams number is equal to * the number of category names * default is the last one, DO NOT delete it, add new * category names in front of it */ static const char *g_category_names[] = { "default" }; #ifdef QZ7Z_DEBUG void printSignatureHeader(Qz7zSignatureHeader_T *sheader) { QZ_DEBUG("-----signature header start-----\n"); QZ_DEBUG("signature: %c %c %x %x %x %x\n", sheader->signature[0], sheader->signature[1], sheader->signature[2], sheader->signature[3], sheader->signature[4], sheader->signature[5]); QZ_DEBUG("major version: %d minor version: %d\n", sheader->majorVersion, sheader->minorVersion); QZ_DEBUG("nextheaderoffset: %lu\n", sheader->nextHeaderOffset); QZ_DEBUG("nextHeaderSize: %lu\n", sheader->nextHeaderSize); QZ_DEBUG("nextHeaderCRC: %u\n", sheader->nextHeaderCRC); QZ_DEBUG("startHeaderCRC: %u\n", sheader->startHeaderCRC); QZ_DEBUG("-----end of signature header-----\n"); } void printEndHeader(Qz7zEndHeader_T *eheader) { int i; int j; QZ_DEBUG("-----print end header-------\n"); if (eheader->propertyInfo) { QZ_DEBUG(" ----------ArchiveProperties-------------\n"); QZ_DEBUG("Develop ID: %lx \n", eheader->propertyInfo->id); } if (eheader->streamsInfo) { QZ_DEBUG(" ----------StreamsInfo ------------------\n"); QZ_DEBUG(" NumPackStreams: %lu\n", eheader->streamsInfo->packInfo->NumPackStreams); QZ_DEBUG(" PackSize: "); for (i = 0; i < eheader->streamsInfo->packInfo->NumPackStreams; ++i) { QZ_DEBUG("%lu ", eheader->streamsInfo->packInfo->PackSize[i]); } QZ_DEBUG("\n ----------CodersInfo -------------------\n"); QZ_DEBUG(" NumFolders: %lu\n", eheader->streamsInfo->codersInfo->numFolders); for (i = 0; i < eheader->streamsInfo->codersInfo->numFolders; ++i) { QZ_DEBUG(" %lu ", eheader->streamsInfo->codersInfo->unPackSize[i]); } QZ_DEBUG("\n ----------SubstreamsInfo-------------------\n"); QZ_DEBUG(" NumUnpackSubstreamsInFolders: \n"); for (i = 0; i < eheader->streamsInfo->codersInfo->numFolders; ++i) { if (eheader->streamsInfo->substreamsInfo->numUnPackStreams) { QZ_DEBUG(" %lu ", eheader->streamsInfo->substreamsInfo-> numUnPackStreams[i]); QZ_DEBUG("\n unpacksize: \n"); for (j = 0; j < eheader->streamsInfo->substreamsInfo-> numUnPackStreams[i]; ++j) { QZ_DEBUG(" %lu ", eheader->streamsInfo->substreamsInfo-> unPackSize[j]); } } } } if (eheader->filesInfo) { QZ_DEBUG("\n --------------FilesInfo -------------\n"); } } #endif static int doCompressBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int *dst_len, RunTimeList_T *time_list, FILE *dst_file, off_t *dst_file_size, int last) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int buf_processed = 0; unsigned int buf_remaining = *src_len; unsigned int bytes_written; unsigned int output_len = 0; RunTimeList_T *time_node = time_list; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); CHECK_ALLOC_RETURN_VALUE(run_time) run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* do actual work */ ret = qzCompress(sess, src, src_len, dst, dst_len, last); if (QZ_BUF_ERROR == ret && 0 == *src_len) { done = 1; } QZ_DEBUG("qzCompress returned: src_len=%u dst_len=%u\n", *src_len, *dst_len); if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { QZ_ERROR("doCompressBuffer in qzip_7z.c :failed with error: %d\n", ret); break; } gettimeofday(&run_time->time_e, NULL); bytes_written = fwrite(dst, 1, *dst_len, dst_file); CHECK_FWRITE_RETURN_FP(dst_file, bytes_written, *dst_len) *dst_file_size += bytes_written; buf_processed += *src_len; buf_remaining -= *src_len; output_len += *dst_len; if (0 == buf_remaining) { done = 1; } src += *src_len; QZ_DEBUG("src_len is %u ,buf_remaining is %u\n", *src_len, buf_remaining); *src_len = buf_remaining; } *src_len = buf_processed; *dst_len = output_len; return ret; } static int doDecompressBuffer(QzSession_T *sess, unsigned char *src, unsigned int *src_len, unsigned char *dst, unsigned int *dst_len, RunTimeList_T *time_list, int last) { int ret = QZ_FAIL; unsigned int done = 0; unsigned int buf_processed = 0; unsigned int src_remain = *src_len; unsigned int output_len = 0; RunTimeList_T *time_node = time_list; unsigned int src_remain_output = *dst_len; unsigned int total = *dst_len; while (time_node->next) { time_node = time_node->next; } while (!done) { RunTimeList_T *run_time = calloc(1, sizeof(RunTimeList_T)); CHECK_ALLOC_RETURN_VALUE(run_time) run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); /* do actual work */ ret = qzDecompress(sess, src, src_len, dst, &src_remain_output); if (QZ_DATA_ERROR == ret || (QZ_BUF_ERROR == ret && 0 == *src_len)) { done = 1; } if (ret != QZ_OK && ret != QZ_BUF_ERROR && ret != QZ_DATA_ERROR) { QZ_ERROR("doDecompressBuffer in qzip_7z.c :failed with error: %d\n", ret); break; } gettimeofday(&run_time->time_e, NULL); *dst_len = src_remain_output; buf_processed += *src_len; src_remain -= *src_len; output_len += *dst_len; src_remain_output = total - output_len; if (0 == src_remain) { done = 1; } if (0 == src_remain_output) { done = 1; } src += *src_len; QZ_DEBUG("src_len is %u ,src_remain is %u\n", *src_len, src_remain); *src_len = src_remain; } *src_len = buf_processed; *dst_len = output_len; return ret; } int doCompressFile(QzSession_T *sess, Qz7zItemList_T *list, const char *dst_file_name) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0, dst_buffer_max_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; const char *src_file_name = NULL; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; Qz7zEndHeader_T *eheader = NULL; unsigned int bytes_read = 0; unsigned long bytes_processed = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = -1; uint64_t eheader_size; uint32_t crc = 0; uint32_t start_crc = 0; uint64_t non_empty_number = 0; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); Qz7zSignatureHeader_T *sheader = NULL; size_t total_compressed_size = 0; int is_last; int n_part; // how much parts can the src file be splited int n_part_i; if (!time_list_head) { QZ_DEBUG("malloc time_list_head error\n"); ret = QZ7Z_ERR_OOM; goto exit; } gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; dst_file = fopen(dst_file_name, "w+"); if (!dst_file) { QZ_ERROR("Cannot open file: %s\n", dst_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } sheader = generateSignatureHeader(); if (!sheader) { QZ_ERROR("Cannot generate signature header, out of memory"); ret = QZ7Z_ERR_OOM; goto exit; } src_buffer = malloc(SRC_BUFF_LEN); if (!src_buffer) { QZ_DEBUG("malloc error\n"); ret = QZ7Z_ERR_OOM; goto exit; } dst_buffer_max_size = qzMaxCompressedLength(SRC_BUFF_LEN, sess); dst_buffer = malloc(dst_buffer_max_size); if (!dst_buffer) { QZ_DEBUG("malloc error\n"); ret = QZ7Z_ERR_OOM; goto exit; } writeSignatureHeader(sheader, dst_file); non_empty_number = list->items[1]->total; if (non_empty_number) { for (int i = 0; i < non_empty_number; ++i) { Qz7zFileItem_T *cur_file = qzListGet(list->items[1], i); src_file_name = cur_file->fileName; if (!cur_file->isSymLink) { src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { ret = QZ7Z_ERR_OPEN; goto exit; } ret = fstat(src_fd, &src_file_stat); if (ret) { QZ_ERROR("stat(): failed\n"); ret = QZ7Z_ERR_STAT; goto exit; } src_file = fdopen(src_fd, "r"); if (!src_file) { QZ_ERROR("create %s error\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } } else { ret = lstat(src_file_name, &src_file_stat); if (ret) { QZ_ERROR("lstat(): failed\n"); ret = QZ7Z_ERR_STAT; goto exit; } } if (S_ISBLK(src_file_stat.st_mode)) { if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { perror(src_file_name); ret = QZ7Z_ERR_IOCTL; goto exit; } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; dst_buffer_size = qzMaxCompressedLength(src_buffer_size, sess); file_remaining = src_file_size; read_more = 1; n_part = src_file_size / SRC_BUFF_LEN; n_part = (src_file_size % SRC_BUFF_LEN) ? n_part + 1 : n_part; is_last = 0; n_part_i = 1; do { is_last = (i == non_empty_number - 1) && (n_part_i++ == n_part); if (read_more) { if (cur_file->isSymLink) { int size; size = readlink(cur_file->fileName, (char *)src_buffer, src_buffer_size); bytes_read = size; } else { bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_PRINT("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } } else { bytes_read = file_remaining; } puts("Compressing..."); unsigned int dest_len = dst_buffer_size; ret = doCompressBuffer(sess, src_buffer, &bytes_read, dst_buffer, &dest_len, time_list_head, dst_file, &dst_file_size, is_last); if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { bytes_processed += bytes_read; if (0 != bytes_read) { if (-1 == fseek(src_file, bytes_processed, SEEK_SET)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { // dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more destination " "buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer " "with size %u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { if (cur_file->isSymLink) { read_more = 0; } else { read_more = 1; } } file_remaining -= bytes_read; total_compressed_size = dst_file_size; } while (file_remaining > 0); if (!cur_file->isSymLink) { fclose(src_file); src_file = NULL; if (src_fd >= 0) { close(src_fd); src_fd = -1; } } }// end for } else { QZ_PRINT("Compressing...\n"); } eheader = generateEndHeader(list, total_compressed_size); if (!eheader) { QZ_ERROR("cannot allocate for end header\n"); ret = QZ7Z_ERR_OOM; goto exit; } eheader_size = writeEndHeader(eheader, dst_file, &crc); if (eheader_size == 0) { QZ_ERROR("Cannot write 7z end header\n"); ret = QZ7Z_ERR_END_HEADER; goto exit; } QZ_DEBUG("total compressed: %lu\n" "eheader_size: %lu\n" "crc: %x\n", total_compressed_size, eheader_size, crc); unsigned char start_header[24]; memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET, &total_compressed_size, sizeof(total_compressed_size)); memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_SIZE, &eheader_size, sizeof(eheader_size)); memcpy(start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_CRC, &crc, sizeof(crc)); start_crc = crc32(start_crc, start_header + SIGNATUREHEADER_OFFSET_NEXTHEADER_OFFSET, 20); memcpy(start_header, &start_crc, sizeof(start_crc)); fseek(dst_file, SIGNATUREHEADER_OFFSET_BASE, SEEK_SET); fwrite(start_header, 1, sizeof(start_header), dst_file); displayStats(time_list_head, src_file_size, dst_file_size, 1/* is_compress */); exit: if (eheader) { freeEndHeader(eheader, 1); } if (src_file) { fclose(src_file); } if (dst_buffer) { free(dst_buffer); } if (src_buffer) { free(src_buffer); } if (sheader) { qzFree(sheader); } if (dst_file) { fclose(dst_file); } if (src_fd >= 0) { close(src_fd); } freeTimeList(time_list_head); if (!g_keep && OK == ret) { int re = deleteSourceFile(list); if (re != QZ7Z_OK) { QZ_ERROR("deleteSourceFile error: %d\n", re); return re; } } return ret; } int qz7zCompress(QzSession_T *sess, Qz7zItemList_T *list, const char *out_name) { char oname[MAX_PATH_LEN]; memset(oname, 0, MAX_PATH_LEN); //add 7z suffix if (makeOutName(out_name, out_name, oname, 1) == 0) { out_name = oname; } return doCompressFile(sess, list, out_name); } int deleteSourceFile(Qz7zItemList_T *list) { if (list == NULL) { QZ_ERROR("the input is NULL\n"); return QZ7Z_ERR_NULL_INPUT_LIST; } QzListHead_T *head; QzListNode_T *ptr; for (int i = 1; i >= 0; i--) { head = list->items[i]; if (head->total == 0) { continue; } int n_node = (head->total + (head->num - 1)) / head->num; for (int node = n_node - 1; node >= 0; node--) { ptr = head->next; int end = 0; while (end < node) { ptr = ptr->next; end++; } for (int j = ptr->used - 1; j >= 0; j--) { Qz7zFileItem_T *item = (Qz7zFileItem_T *)(*(ptr->items + j)); int re = remove(item->fileName); if (re != 0) { QZ_ERROR("Remove error\n"); return QZ7Z_ERR_REMOVE; } } } } return QZ7Z_OK; } Qz7zSignatureHeader_T *resolveSignatureHeader(FILE *fp) { int n; Qz7zSignatureHeader_T *sheader = qzMalloc(sizeof(Qz7zSignatureHeader_T), 0, PINNED_MEM); if (sheader) { n = fread(&sheader->signature, sizeof(unsigned char), 6, fp); CHECK_FREAD_RETURN(n, 6); n = fread(&sheader->majorVersion, sizeof(unsigned char), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->minorVersion, sizeof(unsigned char), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->startHeaderCRC, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderOffset, sizeof(uint64_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderSize, sizeof(uint64_t), 1, fp); CHECK_FREAD_RETURN(n, 1); n = fread(&sheader->nextHeaderCRC, sizeof(uint32_t), 1, fp); CHECK_FREAD_RETURN(n, 1); } else { QZ_ERROR("malloc error\n"); } return sheader; } #define QZ7Z_DEVELOP_ID_PREFIX_SHIFT 56 #define QZ7Z_DEVELOP_ID_SHIFT 16 Qz7zArchiveProperty_T *resolveArchiveProperties(FILE *fp) { Qz7zArchiveProperty_T *property = qzMalloc(sizeof(Qz7zArchiveProperty_T), 0, PINNED_MEM); if (!property) { QZ_ERROR("malloc property error\n"); return NULL; } uint64_t size; uint64_t id = getU64FromBytes(fp); if ((id >> QZ7Z_DEVELOP_ID_PREFIX_SHIFT) != 0x3f /* 7z dev id prefix */) { QZ_ERROR("7z file ArchiveProperties develop ID error.\n" "develop ID should starts with 0x3f\n"); goto error; } QZ_DEBUG("id = %lu\n", id); if (((id >> QZ7Z_DEVELOP_ID_SHIFT) & 0xffffffffff) != QZ7Z_DEVELOP_ID) { QZ_ERROR("7z file ArchiveProperties develop ID(%lu) error.\n" , id >> 16 & 0xffffffffff); goto error; } if ((id & 0xffff) != QZ7Z_DEVELOP_SUBID) { QZ_ERROR("7z file ArchiveProperties develop subID(%lu) error.\n" , id & 0xffff); goto error; } property->id = id; size = getU64FromBytes(fp); skipNByte(size, fp); if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve PackInfo: kEnd (0x00) expected\n"); goto error; } return property; error: if (property) { qzFree(property); } return NULL; } Qz7zPackInfo_T *resolvePackInfo(FILE *fp) { Qz7zPackInfo_T *pack = qzMalloc(sizeof(Qz7zPackInfo_T), 0, PINNED_MEM); if (!pack) { QZ_ERROR("malloc pack error\n"); return NULL; } pack->PackPos = getU64FromBytes(fp); pack->NumPackStreams = getU64FromBytes(fp); pack->PackSize = qzMalloc(pack->NumPackStreams * sizeof(uint64_t), 0, PINNED_MEM); if (!pack->PackSize) { goto error; } if (readByte(fp) != PROPERTY_ID_SIZE) { QZ_ERROR("Resolve PackInfo: kSize (0x09) expected\n"); goto error; } for (int i = 0; i < pack->NumPackStreams; ++i) { pack->PackSize[i] = getU64FromBytes(fp); } if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve PackInfo: kEnd (0x00) expected\n"); goto error; } return pack; error: if (pack) { qzFree(pack->PackSize); qzFree(pack); } return NULL; } Qz7zCodersInfo_T *resolveCodersInfo(FILE *fp) { unsigned char c; int i_folder = 0; Qz7zCodersInfo_T *coders = qzMalloc(sizeof(Qz7zCodersInfo_T), 0, PINNED_MEM); if (!coders) { QZ_ERROR("malloc coders\n"); return NULL; } if ((c = readByte(fp)) != PROPERTY_ID_FOLDER) { QZ_ERROR("Resolve CodersInfo: kFolders(0x0b) expected: %02x\n", c); goto error; } coders->numFolders = getU64FromBytes(fp); coders->folders = qzMalloc(coders->numFolders * sizeof(Qz7zFolderInfo_T), 0, PINNED_MEM); if (!coders->folders) { QZ_ERROR("malloc folders error\n"); goto error; } if ((c = readByte(fp)) == 0) { for (i_folder = 0; i_folder < coders->numFolders; ++i_folder) { Qz7zFolderInfo_T *p = &coders->folders[i_folder]; size_t n; unsigned int id_size; p->numCoders = readByte(fp); p->coder_list = qzMalloc(sizeof(Qz7zCoder_T), 0, PINNED_MEM); if (!p->coder_list) { goto error; } p->coder_list->coderFirstByte.uc = readByte(fp); id_size = p->coder_list->coderFirstByte.st.CodecIdSize; p->coder_list->codecID = qzMalloc(id_size, 0, PINNED_MEM); if (!p->coder_list->codecID) { QZ_ERROR("malloc error\n"); goto error; } n = fread(p->coder_list->codecID, 1, id_size, fp); CHECK_FREAD_RETURN(n, id_size) QZ_DEBUG("codec id: %0x %0x %0x \n", p->coder_list->codecID[0], p->coder_list->codecID[1], p->coder_list->codecID[2]); } } else if (c == 1) { coders->dataStreamIndex = getU64FromBytes(fp); } else { QZ_ERROR("Folders(0x00) or DataStreamIndex(0x01) expected\n"); goto error; } if ((c = readByte(fp)) != PROPERTY_ID_CODERS_UNPACK_SIZE) { QZ_ERROR("Resolve CodersInfo: kCoderUnpackSize(0x0c) expected: %02x\n", c); goto error; } coders->unPackSize = qzMalloc(coders->numFolders * sizeof(uint64_t), 0, PINNED_MEM); if (!coders->unPackSize) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < coders->numFolders; ++i) { coders->unPackSize[i] = getU64FromBytes(fp); } if (readByte(fp) != PROPERTY_ID_END) { QZ_ERROR("Resolve CodersInfo: kEnd (0x00) expected\n"); goto error; } QZ_DEBUG("Resolve CodersInfo: finished\n"); return coders; error: freeCodersInfo(coders); return NULL; } Qz7zSubstreamsInfo_T *resolveSubstreamsInfo(int n_folder, FILE *fp) { unsigned char c; int total = 1; int end = 0; int unpackstreams_resolved = 0; int unpacksize_resolved = 0; int digests_resolved = 0; Qz7zSubstreamsInfo_T *substreams = qzMalloc(sizeof(Qz7zSubstreamsInfo_T), 0, PINNED_MEM); if (!substreams) { QZ_ERROR("malloc error\n"); return NULL; } memset(substreams, 0, sizeof(Qz7zSubstreamsInfo_T)); while (!end) { c = readByte(fp); switch (c) { case PROPERTY_ID_NUM_UNPACK_STREAM: if (unpackstreams_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } total = 0; QZ_DEBUG("Resolve SubstreamsInfo: number folders: %d\n", n_folder); substreams->numUnPackStreams = qzMalloc(n_folder * sizeof(uint64_t), 0, PINNED_MEM); if (!substreams->numUnPackStreams) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < n_folder; ++i) { substreams->numUnPackStreams[i] = getU64FromBytes(fp); QZ_DEBUG(" numUnPackStreams[i] = %lu\n", substreams->numUnPackStreams[i]); total += substreams->numUnPackStreams[i]; } QZ_DEBUG("resolve numUnpackStreams(0x0d) done\n"); unpackstreams_resolved = 1; break; case PROPERTY_ID_SIZE: if (unpacksize_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } if (total - n_folder == 0) { QZ_DEBUG("every folder has one file. No unpacksize part. \n"); } else { substreams->unPackSize = qzMalloc((total - n_folder) * sizeof(uint64_t), 0, PINNED_MEM); if (!substreams->unPackSize) { QZ_DEBUG("malloc error\n"); goto error; } for (int i = 0; i < total - n_folder; ++i) { substreams->unPackSize[i] = getU64FromBytes(fp); QZ_DEBUG("unpacksize: %lu total:%d folder:%d\n", substreams->unPackSize[i], total, n_folder); } } QZ_DEBUG("resolve kSize(0x09) done \n"); unpacksize_resolved = 1; break; case PROPERTY_ID_CRC: if (digests_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } substreams->digests = qzMalloc(sizeof(Qz7zDigest_T), 0, PINNED_MEM); if (!substreams->digests) { QZ_ERROR("malloc error\n"); goto error; } if ((c = readByte(fp)) != 1) { QZ_DEBUG("Resolve Substreams Info: not allaredefined ERROR. " "c = %02x\n", c); goto error; } substreams->digests->allAreDefined = 1; QZ_DEBUG(" read allaredefined : 111 total: %d\n", total); substreams->digests->numDefined = total; substreams->digests->crc = qzMalloc(total * sizeof(uint32_t), 0, PINNED_MEM); if (!substreams->digests->crc) { QZ_ERROR("malloc error\n"); goto error; } for (int i = 0; i < total; ++i) { readCRC(fp); } QZ_DEBUG("resolve CRC(0x0a) done of substreams\n"); digests_resolved = 1; break; case PROPERTY_ID_END: end = 1; break; default: QZ_ERROR("resolve unexpected byte\n"); goto error; } } QZ_DEBUG("Resolve SubstreamsInfo: finished\n"); return substreams; error: freeSubstreamsInfo(substreams); return NULL; } static int readNames(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { unsigned char c; uint64_t u64; int i, j; char path[PATH_MAX]; /* wc is used to store a wchar_t for ASCII, it is stored at wc[0] and wc[1] is '\0' */ char wc[2]; size_t n; u64 = getU64FromBytes(fp); // size QZ_DEBUG("u64 = %lu\n", u64); (void)u64; c = readByte(fp); if (c != 0) { QZ_ERROR("0x11 label external is not 0. Exit. c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } for (i = 0; i < num; ++i) { memset(path, 0, sizeof(path)); j = 0; while (1) { n = fread(wc, 1, sizeof(wc), fp); CHECK_FREAD_RETURN(n, sizeof(wc)) if (!wc[0] && !wc[1]) // two-zero byte means the end break; path[j++] = wc[0]; } path[j] = 0; QZ_DEBUG("path: %s length: %d\n", path, j); (p + i)->nameLength = j + 1; // not include terminal null byte (p + i)->fileName = malloc(j + 1); CHECK_ALLOC_RETURN_VALUE((p + i)->fileName) strncpy((p + i)->fileName, path, j + 1); } return QZ7Z_OK; } static int readTimes(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { uint64_t section_size; size_t nr; FILETIME_T ft; section_size = getU64FromBytes(fp); (void)section_size; if (readByte(fp) != 1) { QZ_ERROR("Resolve Times: AllAreDefined must be 1\n"); return QZ7Z_ERR_TIMES; } if (readByte(fp) != 0) { QZ_ERROR("Resolve Times: External must be 0\n"); return QZ7Z_ERR_TIMES; } for (int i = 0; i < num; ++i) { nr = fread(&ft.low, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readTimes: fread error\n"); return QZ7Z_ERR_READ_LESS; } nr = fread(&ft.high, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readTimes: fread error\n"); return QZ7Z_ERR_READ_LESS; } (p + i)->mtime = filetimeToUnixtime(ft); (p + i)->atime = filetimeToUnixtime(ft); } return QZ7Z_OK; } static int readAttributes(Qz7zFileItem_T *p, uint64_t num, FILE *fp) { unsigned char c; uint64_t u64; uint32_t attr; size_t nr; u64 = getU64FromBytes(fp); // size (void)u64; c = readByte(fp); // AllAreDefined if (c != 1) { QZ_ERROR("Resolve Attributes: AllAreDefined is not 1. Exit. " "c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } c = readByte(fp); // External if (c != 0) { QZ_ERROR("Resolve Attributes: External is not 0. Exit. c = %d\n", c); return QZ7Z_ERR_NOT_EXPECTED_CHAR; } for (int i = 0; i < num; ++i) { nr = fread(&attr, sizeof(uint32_t), 1, fp); if (nr < 1) { QZ_ERROR("readAttributes: fread error\n"); return QZ7Z_ERR_READ_LESS; } (p + i)->attribute = attr; } return QZ7Z_OK; } Qz7zFilesInfo_Dec_T *resolveFilesInfo(FILE *fp) { int n; int i; int j; int end; int file_index; unsigned char c; uint64_t u64; uint64_t total_num; uint64_t dir_num; uint64_t file_num; Qz7zFilesInfo_Dec_T *files = qzMalloc(sizeof(Qz7zFilesInfo_Dec_T), 0, PINNED_MEM); if (!files) { QZ_ERROR("malloc error\n"); return NULL; } memset(files, 0, sizeof(Qz7zFilesInfo_Dec_T)); total_num = getU64FromBytes(fp); Qz7zFileItem_T *p = qzMalloc(total_num * sizeof( Qz7zFileItem_T), 0, PINNED_MEM); if (!p) { QZ_ERROR("malloc error\n"); goto error; } memset(p, 0, total_num * sizeof(*p)); end = 0; while (!end) { switch ((c = readByte(fp))) { case PROPERTY_ID_END: end = 1; break; case PROPERTY_ID_EMPTY_STREAM: file_index = 0; dir_num = 0; /* n bytes to hold this information */ n = (total_num % 8) ? (total_num / 8 + 1) : (total_num / 8); u64 = getU64FromBytes(fp); /* property size */ file_index = 0; for (i = 0; i < n; ++i) { // read n bytes property c = readByte(fp); for (j = 7; j >= 0; --j) { int is_dir = !!(c & 1 << j); p[file_index++].isDir = is_dir; if (is_dir) { dir_num++; } if (total_num == file_index) { break; } } } file_num = total_num - dir_num; files->file_num = file_num; files->dir_num = dir_num; break; case PROPERTY_ID_EMPTY_FILE: file_index = 0; u64 = getU64FromBytes(fp); // property size for (i = 0; i < u64; ++i) { c = readByte(fp); for (j = 7; j >= 0; --j) { p[file_index].isEmpty = !!(c & 1 << j); if (p[file_index].isEmpty) { p[file_index].isDir = 0; } file_index++; if (total_num == file_index) break; } } break; case PROPERTY_ID_NAME: if (readNames(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_CTIME: case PROPERTY_ID_ATIME: case PROPERTY_ID_MTIME: if (readTimes(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_ATTRIBUTES: if (readAttributes(p, total_num, fp) < 0) { goto error; } break; case PROPERTY_ID_DUMMY: c = readByte(fp); if (c) { skipNByte(c, fp); } break; default: QZ_ERROR("Not expected attribute\n"); goto error; } } files->items = p; return files; error: if (p) { qzFree(p); } if (files) { qzFree(files); } return NULL; } Qz7zStreamsInfo_T *resolveMainStreamsInfo(FILE *fp) { unsigned char c; int end = 0; int pack_info_resolved = 0; int coders_info_allocated = 0; int coders_info_resolved = 0; int substreams_info_resolved = 0; Qz7zStreamsInfo_T *streamsInfo = malloc(sizeof(Qz7zStreamsInfo_T)); if (!streamsInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(streamsInfo, 0, sizeof(Qz7zStreamsInfo_T)); while (!end) { switch (c = readByte(fp)) { case PROPERTY_ID_PACKINFO: if (pack_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } streamsInfo->packInfo = resolvePackInfo(fp); if (!streamsInfo->packInfo) { QZ_ERROR("Resolve Pack Info error\n"); goto error; } pack_info_resolved = 1; break; case PROPERTY_ID_UNPACKINFO: if (coders_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } streamsInfo->codersInfo = resolveCodersInfo(fp); if (!streamsInfo->codersInfo) { QZ_ERROR("Resolve Coders Info error\n"); goto error; } coders_info_allocated = 1; coders_info_resolved = 1; break; case PROPERTY_ID_SUBSTREAMSINFO: if (substreams_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } if (!coders_info_allocated) { QZ_ERROR("No coders info\n"); goto error; } streamsInfo->substreamsInfo = resolveSubstreamsInfo(streamsInfo ->codersInfo->numFolders, fp); if (!streamsInfo->substreamsInfo) { QZ_ERROR("Resolve Substreams Info error\n"); goto error; } substreams_info_resolved = 1; break; case PROPERTY_ID_END: end = 1; break; default: QZ_ERROR("Resolve Mainstreams Info Error\n"); goto error; } } return streamsInfo; error: freeStreamsInfo(streamsInfo); return NULL; } Qz7zEndHeader_T *resolveEndHeader(FILE *fp, Qz7zSignatureHeader_T *sheader) { Qz7zEndHeader_T *eheader = malloc(sizeof(Qz7zEndHeader_T)); if (!eheader) { QZ_ERROR("malloc error\n"); return NULL; } memset(eheader, 0, sizeof(Qz7zEndHeader_T)); unsigned int status = 0; unsigned char c; int end = 0; int has_archive_property = 0; int archive_property_resolved = 0; int streams_info_resolved = 0; int files_info_resolved = 0; fseek(fp, sheader->nextHeaderOffset + 0x20, SEEK_CUR); while (!end) { switch (c = readByte(fp)) { case PROPERTY_ID_HEADER: status = RESOLVE_STATUS_IN_HEADER; break; case PROPERTY_ID_ARCHIVE_PROPERTIES: if (archive_property_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } has_archive_property = 1; status = RESOLVE_STATUS_IN_ARCHIVE_PROPERTIES; eheader->propertyInfo = resolveArchiveProperties(fp); if (!eheader->propertyInfo) { QZ_ERROR("Resolve Archive property error\n"); goto error; } archive_property_resolved = 1; break; case PROPERTY_ID_MAIN_STREAMSINFO: if (streams_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } status = RESOLVE_STATUS_IN_STREAMSINFO; eheader->streamsInfo = resolveMainStreamsInfo(fp); if (!eheader->streamsInfo) { QZ_ERROR("malloc error\n"); goto error; } streams_info_resolved = 1; break; case PROPERTY_ID_FILESINFO: if (files_info_resolved) { QZ_ERROR("Resolve substreams info: duplicated tag\n"); goto error; } status = RESOLVE_STATUS_IN_FILESINFO; eheader->filesInfo_Dec = resolveFilesInfo(fp); if (!eheader->filesInfo_Dec) { QZ_ERROR("Resolve Files Info error\n"); goto error; } files_info_resolved = 1; break; case PROPERTY_ID_END: QZ_DEBUG("read kEnd: %d\n\n\n", status); if (status == RESOLVE_STATUS_IN_FILESINFO) end = 1; break; default: QZ_ERROR("Resolve End Header Error\n"); goto error; } } if (!has_archive_property) { QZ_ERROR("ERROR: property 'QAT7z' not found\n"); QZ_ERROR("This archive is not compressed by QAT,"); QZ_ERROR("QAT only support 7z archive compressed by QAT\n"); goto error; } return eheader; error: freeEndHeader(eheader, 0); return NULL; } static int createEmptyFile(const char *filename) { FILE *fp = fopen(filename, "w"); if (!fp) { QZ_ERROR("create %s error\n", filename); return -1; } fclose(fp); return 0; } /** * create `newdir` at current directory * back: 1 return to original dir, 0 otherwise */ int createDir(const char *newdir, int back) { int ret; char *dirc, *basec; char pwd[PATH_MAX]; char dir_name[PATH_MAX + 1] = {0}; char base_name[PATH_MAX + 1] = {0}; if (!getcwd(pwd, sizeof(pwd))) { return QZ7Z_ERR_GETCWD; } QZ_DEBUG("working directory: %s\n", pwd); strncpy(dir_name, newdir, PATH_MAX); strncpy(base_name, newdir, PATH_MAX); dirc = dirname(dir_name); basec = basename(base_name); if (!strcmp(dirc, ".")) { if (mkdir(newdir, 0755) < 0) { if (errno != EEXIST) { perror("create dir failed\n"); return QZ7Z_ERR_MKDIR; } } if (chdir(newdir) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } if (back) { if (chdir(pwd) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } } return QZ7Z_OK; } if ((ret = createDir(dirc, 0)) < 0) return ret; if ((ret = createDir(basec, 0)) < 0) return ret; if (back) { if (chdir(pwd) < 0) { perror("cannot change working dir\n"); return QZ7Z_ERR_CHDIR; } } return QZ7Z_OK; } void decompressEmptyfilesAndDirectories(Qz7zFilesInfo_Dec_T *info) { uint64_t num = info->dir_num; Qz7zFileItem_T *p = info->items; for (int i = 0; i < num; ++i) { if (p[i].isDir) { createDir(p[i].fileName, 1); } else { createEmptyFile(p[i].fileName); } } } int checkHeaderCRC(Qz7zSignatureHeader_T *sh, FILE *fp) { uint32_t crc = 0; crc = crc32(crc, (unsigned char *)&sh->nextHeaderOffset, sizeof(uint64_t)); crc = crc32(crc, (unsigned char *)&sh->nextHeaderSize, sizeof(uint64_t)); crc = crc32(crc, (unsigned char *)&sh->nextHeaderCRC, sizeof(uint32_t)); if (crc != sh->startHeaderCRC) { QZ_ERROR("Signature CRC failed\n"); return -1; } size_t n; unsigned char buf[4096]; crc = 0; fseek(fp, sh->nextHeaderOffset + 0x20, SEEK_SET); while ((n = fread(buf, 1, sizeof(buf), fp))) { crc = crc32(crc, buf, n); } if (crc != sh->nextHeaderCRC) { QZ_ERROR("End header CRC failed\n"); return -1; } fseek(fp, 0, SEEK_SET); return 0; } void freePropertyInfo(Qz7zArchiveProperty_T *info) { Qz7zArchiveProperty_T *cur = info; while (cur) { free(cur->data); cur = cur->next; } qzFree(info); } void freePackInfo(Qz7zPackInfo_T *info) { if (info) { qzFree(info->PackSize); qzFree(info); } } void freeCodersInfo(Qz7zCodersInfo_T *info) { if (info) { if (info->folders) { for (int i = 0; i < info->numFolders; ++i) { Qz7zCoder_T *cur = info->folders[i].coder_list; while (cur) { qzFree(cur->codecID); cur = cur->next; } qzFree(info->folders[i].coder_list); } qzFree(info->folders); } qzFree(info->unPackSize); qzFree(info); } } void freeSubstreamsInfo(Qz7zSubstreamsInfo_T *info) { if (info) { qzFree(info->numUnPackStreams); qzFree(info->unPackSize); if (info->digests) { qzFree(info->digests->crc); qzFree(info->digests); } qzFree(info); } } void freeStreamsInfo(Qz7zStreamsInfo_T *info) { if (info) { freePackInfo(info->packInfo); freeCodersInfo(info->codersInfo); freeSubstreamsInfo(info->substreamsInfo); free(info); } } void freeFilesInfo(Qz7zFilesInfo_T *info) { qzFree(info); } void freeFilesDecInfo(Qz7zFilesInfo_Dec_T *info) { if (info) { qzFree(info->items); qzFree(info); } } void freeEndHeader(Qz7zEndHeader_T *h, int is_compress) { freePropertyInfo(h->propertyInfo); freeStreamsInfo(h->streamsInfo); if (is_compress) { freeFilesInfo(h->filesInfo); } else { freeFilesDecInfo(h->filesInfo_Dec); } free(h); } static int convertToSymlink(const char *name) { char resolved_path[PATH_MAX + 1]; FILE *file = fopen(name, "rb"); if (file) { char buf[1000 + 1]; char *ret = fgets(buf, sizeof(buf) - 1, file); fclose(file); /* To avoid CWE-22: Improper Limitation of a Pathname to a Restricted Directory * ('Path Traversal') attacks. * http://cwe.mitre.org/data/definitions/22.htm */ if (!realpath(name, resolved_path)) { return -1; } if (ret) { int ir = unlink(name); if (ir == 0) { ir = symlink(buf, name); } return ir; } } return -1; } int doDecompressFile(QzSession_T *sess, const char *src_file_name) { int ret = OK; struct stat src_file_stat; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; unsigned int saved_dst_buffer_size = 0; off_t src_file_size = 0, dst_file_size = 0, file_remaining = 0; unsigned char *src_buffer = NULL; unsigned char *src_buffer_orig = NULL; unsigned char *dst_buffer = NULL; FILE *src_file = NULL; FILE *dst_file = NULL; unsigned int bytes_read = 0; unsigned int ratio_idx = 0; const unsigned int ratio_limit = sizeof(g_bufsz_expansion_ratio) / sizeof(unsigned int); unsigned int read_more = 0; int src_fd = -1; Qz7zFileItem_T *p = NULL; uint64_t dir_num = 0; uint64_t fil_num = 0; uint64_t file_index = 0; int is_last; int n_part; // how much parts can the src file be splitted int n_part_i; Qz7zSignatureHeader_T *sheader = NULL; Qz7zEndHeader_T *eheader = NULL; RunTimeList_T *run_time = NULL; \ RunTimeList_T *time_node = NULL; RunTimeList_T *time_list_head = malloc(sizeof(RunTimeList_T)); if (!time_list_head) { QZ_DEBUG("malloc RunTimeList_T error\n"); ret = QZ7Z_ERR_OOM; goto exit; } gettimeofday(&time_list_head->time_s, NULL); time_list_head->time_e = time_list_head->time_s; time_list_head->next = NULL; time_node = time_list_head; run_time = calloc(1, sizeof(RunTimeList_T)); if (!run_time) { QZ_DEBUG("malloc RunTimeList_T error\n"); ret = QZ7Z_ERR_OOM; goto exit; } run_time->next = NULL; time_node->next = run_time; time_node = run_time; gettimeofday(&run_time->time_s, NULL); src_file = fopen(src_file_name, "r"); if (src_file == NULL) { QZ_ERROR("cannot open file %s: %d\n", src_file_name, errno); ret = QZ7Z_ERR_OPEN; goto exit; } sheader = resolveSignatureHeader(src_file); if (!sheader) { QZ_ERROR("Resolve signature header\n"); ret = QZ7Z_ERR_SIG_HEADER; goto exit; } #ifdef QZ7Z_DEBUG print_signature_header(sheader); #endif if (checkHeaderCRC(sheader, src_file) < 0) { QZ_ERROR("Header error: CRC check failed\n"); ret = QZ7Z_ERR_HEADER_CRC; goto exit; } eheader = resolveEndHeader(src_file, sheader); if (!eheader) { QZ_ERROR("Cannot resolve end header\n"); ret = QZ7Z_ERR_RESOLVE_END_HEADER; goto exit; } fclose(src_file); src_file = NULL; // decode the dir p = eheader->filesInfo_Dec->items; dir_num = eheader->filesInfo_Dec->dir_num; fil_num = eheader->filesInfo_Dec->file_num; decompressEmptyfilesAndDirectories(eheader->filesInfo_Dec); // decode the content if (eheader->streamsInfo) { uint64_t folder_num = eheader->streamsInfo->codersInfo->numFolders; Qz7zFileItem_T *file_items = eheader->filesInfo_Dec->items + eheader->filesInfo_Dec->dir_num; for (int i = 0; i < folder_num; ++i) { uint64_t num_files_in_folder = eheader->streamsInfo->substreamsInfo->numUnPackStreams[i]; uint64_t total_unPack_size = eheader->streamsInfo->codersInfo->unPackSize[i]; for (int j = 0; j < num_files_in_folder - 1; ++file_index, ++j) { (file_items + file_index)->size = eheader->streamsInfo->substreamsInfo->unPackSize[j]; total_unPack_size -= (file_items + file_index)->size; } (file_items + file_index)->size = total_unPack_size; } src_fd = open(src_file_name, O_RDONLY); if (src_fd < 0) { QZ_PRINT("Open input file %s failed\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } ret = fstat(src_fd, &src_file_stat); assert(!ret); if (S_ISBLK(src_file_stat.st_mode)) { if (ioctl(src_fd, BLKGETSIZE, &src_file_size) < 0) { perror(src_file_name); ret = QZ7Z_ERR_IOCTL; goto exit; } src_file_size *= 512; } else { src_file_size = src_file_stat.st_size; } src_file_size -= sheader->nextHeaderSize; src_file_size -= 32; src_buffer_size = (src_file_size > SRC_BUFF_LEN) ? SRC_BUFF_LEN : src_file_size; dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; saved_dst_buffer_size = dst_buffer_size; src_buffer = malloc(src_buffer_size); if (!src_buffer) { QZ_ERROR("malloc error\n"); goto exit; } src_buffer_orig = src_buffer; dst_buffer = malloc(dst_buffer_size); if (!dst_buffer) { QZ_ERROR("malloc error\n"); goto exit; } src_file = fopen(src_file_name, "r"); if (!src_file) { QZ_ERROR("file open error: %s\n", src_file_name); ret = QZ7Z_ERR_OPEN; goto exit; } // skip the signature header fseek(src_file, 32, SEEK_SET); int i = 0; // file index file_remaining = src_file_size; read_more = 1; n_part = src_file_size / SRC_BUFF_LEN; n_part = (src_file_size % SRC_BUFF_LEN) ? n_part + 1 : n_part; is_last = 0; n_part_i = 1; off_t cur_offset; cur_offset = 0; off_t file_read_processed_size = 0; int need_check_file_with_same_name = 1; do { is_last = (n_part_i++ == n_part); if (read_more) { src_buffer = src_buffer_orig; bytes_read = fread(src_buffer, 1, src_buffer_size, src_file); QZ_PRINT("Reading input file %s (%u Bytes)\n", src_file_name, bytes_read); } else { bytes_read = file_remaining; } puts("Decompressing..."); if (n_part > 1 && is_last) bytes_read -= sheader->nextHeaderSize; int buffer_remaining = bytes_read; do { unsigned int bytes_processed = buffer_remaining; ret = doDecompressBuffer(sess, src_buffer, &bytes_processed, dst_buffer, &dst_buffer_size, time_list_head, is_last); file_read_processed_size += bytes_processed; src_buffer += bytes_processed; buffer_remaining -= bytes_processed; if (QZ_DATA_ERROR == ret || QZ_BUF_ERROR == ret) { if (0 != bytes_processed) { if (-1 == fseek(src_file, file_read_processed_size, SEEK_SET)) { ret = ERROR; goto exit; } read_more = 1; } else if (QZ_BUF_ERROR == ret) { //dest buffer not long enough if (ratio_limit == ratio_idx) { QZ_ERROR("Could not expand more" "destination buffer\n"); ret = ERROR; goto exit; } free(dst_buffer); dst_buffer_size = src_buffer_size * g_bufsz_expansion_ratio[ratio_idx++]; dst_buffer = malloc(dst_buffer_size); if (NULL == dst_buffer) { QZ_ERROR("Fail to allocate destination buffer " "with size %u\n", dst_buffer_size); ret = ERROR; goto exit; } read_more = 0; } else { // corrupt data ret = ERROR; goto exit; } } else if (QZ_OK != ret) { QZ_ERROR("Process file error: %d\n", ret); ret = ERROR; goto exit; } else { read_more = 1; unsigned int dst_left; unsigned char *dst_write; size_t n_written; unsigned int st_mode; Qz7zFileItem_T *cur_file; dst_write = dst_buffer; dst_left = dst_buffer_size; dst_file_size += dst_buffer_size; while (dst_left) { cur_file = p + dir_num + i; st_mode = (cur_file->attribute) >> 16; if (need_check_file_with_same_name) { dst_file = fopen(cur_file->fileName, "w+"); } else { dst_file = fopen(cur_file->fileName, "a"); } if (NULL == dst_file) { if (S_ISLNK(st_mode)) { QZ_DEBUG("open an broken soft-link file, " "need to delete it\n"); if (!remove(cur_file->fileName)) { QZ_DEBUG("remove file %s error\n", cur_file->fileName); ret = ERROR; goto exit; } dst_file = fopen(cur_file->fileName, "a"); if (NULL == dst_file) { QZ_DEBUG("open file %s error\n", cur_file->fileName); ret = ERROR; goto exit; } } else { QZ_DEBUG("open file error\n"); ret = ERROR; goto exit; } } if (cur_file->size - cur_offset <= dst_left) { n_written = fwrite(dst_write, 1, cur_file->size - cur_offset, dst_file); if (n_written == cur_file->size - cur_offset) { ++i; need_check_file_with_same_name = 1; cur_offset = 0; } else { need_check_file_with_same_name = 0; cur_offset += n_written; } dst_left -= n_written; dst_write += n_written; } else { n_written = fwrite(dst_write, 1, dst_left, dst_file); dst_write = dst_buffer; cur_offset += dst_left; dst_left = 0; need_check_file_with_same_name = 0; } fclose(dst_file); dst_file = NULL; if (need_check_file_with_same_name) { if (S_ISLNK(st_mode)) { convertToSymlink(cur_file->fileName); } } }// end while dst_buffer_size = saved_dst_buffer_size; } } while (buffer_remaining); file_remaining -= bytes_read; } while (file_remaining > 0); } else { QZ_PRINT("Decompressing...\n"); } gettimeofday(&run_time->time_e, NULL); // restore the time struct utimbuf tb; for (int i = 0; i < dir_num + fil_num; ++i) { tb.actime = p[i].atime; tb.modtime = p[i].mtime; utime(p[i].fileName, &tb); } // restore the attribute for (int i = 0; i < dir_num + fil_num; ++i) { __mode_t mode = p[i].attribute >> 16; /* * If the file is a symbolic link, don't change it mode and skip it. * Otherwise, it will change the mode of linked file. */ if (S_ISLNK(mode)) continue; chmod(p[i].fileName, p[i].attribute >> 16); } displayStats(time_list_head, src_file_size, dst_file_size, 0/* is_compress */); exit: if (dst_file) { fclose(dst_file); } if (src_file) { fclose(src_file); } if (dst_buffer) { free(dst_buffer); } if (src_buffer_orig) { free(src_buffer_orig); } if (eheader) { freeEndHeader(eheader, 0); } if (sheader) { qzFree(sheader); } if (src_fd >= 0) { close(src_fd); } freeTimeList(time_list_head); if (!g_keep && OK == ret) { int re = remove(src_file_name); if (re != 0) { QZ_ERROR("deleteSourceFile error: %d\n", re); return re; } } return ret; } /* * the main decompress API for 7z file */ int qz7zDecompress(QzSession_T *sess, const char *archive) { return doDecompressFile(sess, archive); } /* * calculate a file's crc */ static int64_t calculateCRC(char *filename, size_t n) { FILE *fp; uint32_t crc = 0; size_t ret; size_t remaining = n; size_t len; unsigned char *buf; buf = malloc(SRC_BUFF_LEN); if (!buf) { QZ_ERROR("oom\n"); return QZ7Z_ERR_OOM; } fp = fopen(filename, "r"); if (!fp) { QZ_ERROR("filename open error\n"); free(buf); return QZ7Z_ERR_OPEN; } while (remaining > 0) { if (remaining > SRC_BUFF_LEN) len = SRC_BUFF_LEN; else len = remaining; ret = fread(buf, 1, len, fp); CHECK_FREAD_RETURN(ret, len) crc = crc32(crc, buf, len); remaining -= len; } free(buf); fclose(fp); QZ_DEBUG("%s crc: %08x\n", filename, crc); return crc; } void qzListDestroy(QzListHead_T *head) { Qz7zFileItem_T *fi; QzListNode_T *node, *tmp_node; node = head->next; do { for (int j = 0; j < node->used; ++j) { fi = node->items[j]; if (fi) { if (fi->fileName) { free(fi->fileName); fi->fileName = NULL; } free(fi); fi = NULL; } } free(node->items); tmp_node = node; node = node->next; free(tmp_node); } while (node); free(head); } void itemListDestroy(Qz7zItemList_T *p) { QzListHead_T *h; for (int i = 0; i < 2; ++i) { h = p->items[i]; qzListDestroy(h); } QzCatagoryTable_T *table = p->table; QzCatagory_T cat; if (table) { for (int i = 0; i < table->cat_num; ++i) { cat = table->catas[i]; free(cat.cat_files->next->items); free(cat.cat_files->next); free(cat.cat_files); } free(table->catas); free(table); } free(p); } static uint32_t calculateSymCRC(char *filename, size_t n) { uint32_t crc = 0; char *buf; buf = malloc(PATH_MAX + 1); if (!buf) { QZ_ERROR("oom\n"); return 0; } ssize_t size = readlink(filename, buf, PATH_MAX); if ((unsigned int)size != (unsigned int)n) { QZ_ERROR("readlink error\n"); free(buf); return 0; } crc = crc32(crc, (unsigned char *)buf, n); free(buf); return crc; } Qz7zFileItem_T *fileItemCreate(char *f) { Qz7zFileItem_T *p = malloc(sizeof(Qz7zFileItem_T)); if (p) { memset(p, 0, sizeof(Qz7zFileItem_T)); p->nameLength = strlen(f) + 1; p->fileName = (char *)malloc(p->nameLength); if (!p->fileName) { QZ_ERROR("oom\n"); free(p); return NULL; } memset(p->fileName, 0, p->nameLength); strcpy(p->fileName, f); struct stat buf; if (lstat(p->fileName, &buf) < 0) { QZ_ERROR("stat func error\n"); free(p->fileName); free(p); return NULL; } if (S_ISLNK(buf.st_mode)) { p->isSymLink = 1; p->crc = calculateSymCRC(p->fileName, buf.st_size); p->size = buf.st_size; } else if (S_ISDIR(buf.st_mode)) { p->isDir = 1; } else { p->size = buf.st_size; p->isEmpty = buf.st_size ? 0 : 1; p->crc = calculateCRC(p->fileName, p->size); } p->mtime = buf.st_mtime; p->mtime_nano = buf.st_mtim.tv_nsec; p->atime = buf.st_atime; p->atime_nano = buf.st_atim.tv_nsec; //p-7zip use 0x80000 as a unix file flag p->attribute = buf.st_mode << 16 | (0x8000); } return p; } #define QZ7Z_LIST_DEFAULT_NUM_PER_NODE 1000 void qzListAdd(QzListHead_T *head, void **fi) { // let cur points to the first node QzListNode_T *cur = head->next; QzListNode_T *last = cur; while (cur && cur->used == cur->num) { last = cur; cur = cur->next; } if (cur) { // this node is not full #ifdef QZ7Z_DEBUG QZ_DEBUG("Before Add : head num: %d total: %d last->used: %d\n", head->num, head->total, cur->used); #endif cur->items[cur->used++] = *fi; head->total++; } else { cur = (QzListNode_T *)malloc(head->num * sizeof(QzListNode_T)); CHECK_ALLOC_RETURN_VALUE(cur); cur->num = head->num; cur->used = 0; cur->next = NULL; #ifdef QZ7Z_DEBUG QZ_DEBUG("applying a new node\n"); #endif cur->items = (void **)malloc(head->num * sizeof(void *)); CHECK_ALLOC_RETURN_VALUE(cur->items) last->next = cur; #ifdef QZ7Z_DEBUG QZ_DEBUG("Before Add : head num: %d total: %d cur->used: %d\n", head->num, head->total, cur->used); #endif cur->items[cur->used++] = *fi; head->total++; } #ifdef QZ7Z_DEBUG QZ_DEBUG(" add %s to list %p : total: %u\n", ((Qz7zFileItem_T *)(*fi))->fileName, (void *)head, head->total); QZ_DEBUG("After Add : head num: %d total: %d last->used: %d\n", head->num, head->total, cur->used); #endif } void *qzListGet(QzListHead_T *head, int index) { int i; if (index >= head->total) { QZ_ERROR("qzListGet: index out of total\n"); return NULL; } QzListNode_T *cur = head->next; int steps = index / head->num; for (i = 0; i < steps; ++i) { cur = cur->next; } return cur->items[index % head->num]; } QzListHead_T *qzListCreate(int num_per_node) { QzListNode_T *node; if (num_per_node <= 0) { num_per_node = QZ7Z_LIST_DEFAULT_NUM_PER_NODE; } QzListHead_T *p = (QzListHead_T *)malloc(sizeof(QzListHead_T)); CHECK_ALLOC_RETURN_VALUE(p) node = (QzListNode_T *)malloc(sizeof(QzListNode_T)); CHECK_ALLOC_RETURN_VALUE(node) node->items = (void **)malloc(num_per_node * sizeof(void *)); CHECK_ALLOC_RETURN_VALUE(node->items) node->num = num_per_node; node->used = 0; node->next = NULL; p->next = node; p->num = num_per_node; p->total = 0; return p; } Qz7zSignatureHeader_T *generateSignatureHeader() { Qz7zSignatureHeader_T *header = qzMalloc(sizeof(Qz7zSignatureHeader_T), 0, PINNED_MEM); if (!header) { QZ_ERROR("malloc error\n"); return NULL; } for (int i = 0; i < 6; ++i) { header->signature[i] = g_header_signature[i]; } header->majorVersion = G_7ZHEADER_MAJOR_VERSION; header->minorVersion = G_7ZHEADER_MINOR_VERSION; return header; } Qz7zPackInfo_T *generatePackInfo(Qz7zItemList_T *the_list, size_t compressed_size) { Qz7zPackInfo_T *pack = qzMalloc(sizeof(Qz7zPackInfo_T), 0, PINNED_MEM); if (!pack) { QZ_ERROR("malloc error\n"); return NULL; } memset(pack, 0, sizeof(Qz7zPackInfo_T)); pack->PackPos = 0; pack->NumPackStreams = the_list->table->cat_num; pack->PackSize = qzMalloc(pack->NumPackStreams * sizeof(uint64_t), 0, PINNED_MEM); if (!pack->PackSize) { qzFree(pack); return NULL; } pack->PackSize[0] = compressed_size; pack->PackStreamDigests = NULL; return pack; } static Qz7zCoder_T *generateCoder() { Qz7zCoder_T *coder = qzMalloc(sizeof(Qz7zCoder_T), 0, PINNED_MEM); if (!coder) { QZ_ERROR("malloc error\n"); return NULL; } coder->coderFirstByte.uc = 0x03; /* 0000 0011 */ coder->codecID = qzMalloc(3 * sizeof(unsigned char), 0, PINNED_MEM); if (!coder->codecID) { QZ_ERROR("malloc error\n"); return NULL; } memcpy((char *)coder->codecID, g_deflate_codecId, 3); coder->numInStreams = 0; coder->numOutStreams = 0; coder->propertySize = 0; coder->properties = NULL; coder->next = NULL; return coder; } Qz7zFolderInfo_T *generateFolderInfo(Qz7zItemList_T *the_list, int n_folders) { if (n_folders <= 0) { n_folders = 1; } Qz7zFolderInfo_T *folders = qzMalloc(n_folders * sizeof(Qz7zFolderInfo_T), 0, PINNED_MEM); if (!folders) { QZ_ERROR("malloc error\n"); return NULL; } folders->items = the_list->items[1]; folders->numCoders = 1; folders->coder_list = generateCoder(); folders->numBindPairs = 0; folders->inIndex = NULL; folders->outIndex = NULL; folders->numPackedStreams = 0; folders->index = NULL; return folders; } Qz7zCodersInfo_T *generateCodersInfo(Qz7zItemList_T *the_list) { Qz7zCodersInfo_T *coders = qzMalloc(sizeof(Qz7zCodersInfo_T), 0, PINNED_MEM); if (!coders) { QZ_ERROR("malloc error\n"); return NULL; } coders->numFolders = the_list->table->cat_num; coders->folders = generateFolderInfo(the_list, coders->numFolders); if (!coders->folders) { QZ_ERROR("malloc error\n"); qzFree(coders); return NULL; } coders->unPackSize = qzMalloc(coders->numFolders * sizeof(uint64_t), 0, PINNED_MEM); if (!coders->unPackSize) { QZ_ERROR("malloc error\n"); qzFree(coders->folders); qzFree(coders); return NULL; } for (int i = 0; i < coders->numFolders; ++i) { QzCatagory_T *cat = &(the_list->table->catas[i]); coders->unPackSize[i] = 0; for (int j = 0; j < cat->cat_files->total; ++j) { Qz7zFileItem_T *p = (Qz7zFileItem_T *)qzListGet(cat->cat_files, j); coders->unPackSize[i] += p->size; } } coders->unPackDigests = NULL; /* not used */ return coders; } Qz7zDigest_T *generateDigestInfo(QzListHead_T *head) { Qz7zDigest_T *digests = qzMalloc(sizeof(Qz7zDigest_T), 0, PINNED_MEM); if (!digests) { QZ_ERROR("malloc error\n"); return NULL; } digests->allAreDefined = 1; digests->numStreams = head->total; digests->numDefined = head->total; digests->crc = qzMalloc(digests->numDefined * sizeof(uint32_t), 0, PINNED_MEM); if (!digests->crc) { QZ_ERROR("malloc error\n"); qzFree(digests); return NULL; } for (int i = 0; i < digests->numDefined; ++i) { Qz7zFileItem_T *p = (Qz7zFileItem_T *)qzListGet(head, i); (digests->crc)[i] = p->crc; } return digests; } Qz7zSubstreamsInfo_T *generateSubstreamsInfo(Qz7zItemList_T *the_list) { int index_of_file = 0; // index of all files in the list Qz7zFileItem_T *fi; Qz7zSubstreamsInfo_T *substreamsInfo = qzMalloc(sizeof(Qz7zSubstreamsInfo_T), 0, PINNED_MEM); if (!substreamsInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(substreamsInfo, 0, sizeof(Qz7zSubstreamsInfo_T)); QzListHead_T *h = the_list->items[1]; uint64_t total_files = h->total; if (!total_files) { qzFree(substreamsInfo); return NULL; } substreamsInfo->numFolders = the_list->table->cat_num; substreamsInfo->numUnPackStreams = qzMalloc(substreamsInfo->numFolders * sizeof(uint64_t), 0, PINNED_MEM); if (!substreamsInfo->numUnPackStreams) { QZ_ERROR("malloc error\n"); qzFree(substreamsInfo); return NULL; } // n_files - n_folder if (total_files != 1) { substreamsInfo->unPackSize = qzMalloc((total_files - 1) * sizeof(uint64_t), 0, PINNED_MEM); if (!substreamsInfo->unPackSize) { QZ_ERROR("malloc error\n"); qzFree(substreamsInfo->numUnPackStreams); qzFree(substreamsInfo); return NULL; } } for (int i = 0; i < substreamsInfo->numFolders; ++i) { h = the_list->table->catas[i].cat_files; substreamsInfo->numUnPackStreams[i] = h->total; if (h->total == 1 || total_files == 1) continue; // folder has one file, don't need the unpacksize for (int j = 0; j < h->total - 1; ++j) { fi = qzListGet(h, j); substreamsInfo->unPackSize[index_of_file++] = fi->size; } } substreamsInfo->digests = generateDigestInfo(h); if (!substreamsInfo->digests) { QZ_ERROR("malloc error\n"); if (substreamsInfo->unPackSize) { qzFree(substreamsInfo->unPackSize); } qzFree(substreamsInfo->numUnPackStreams); qzFree(substreamsInfo); return NULL; } return substreamsInfo; } Qz7zFilesInfo_T *generateFilesInfo(Qz7zItemList_T *the_list) { Qz7zFilesInfo_T *filesInfo = qzMalloc(sizeof(Qz7zFilesInfo_T), 0, PINNED_MEM); if (!filesInfo) { QZ_ERROR("malloc error\n"); return NULL; } memset(filesInfo, 0, sizeof(Qz7zFilesInfo_T)); filesInfo->num = the_list->items[0]->total + the_list->items[1]->total; filesInfo->head[0] = the_list->items[0]; filesInfo->head[1] = the_list->items[1]; return filesInfo; } Qz7zStreamsInfo_T *generateStreamsInfo(Qz7zItemList_T *the_list, size_t compressed_size) { uint64_t n = the_list->items[1]->total; if (!n) return NULL; Qz7zStreamsInfo_T *streams = malloc(sizeof(Qz7zStreamsInfo_T)); CHECK_ALLOC_RETURN_VALUE(streams) streams->packInfo = generatePackInfo(the_list, compressed_size); streams->codersInfo = generateCodersInfo(the_list); streams->substreamsInfo = generateSubstreamsInfo(the_list); return streams; } Qz7zArchiveProperty_T *generatePropertyInfo() { Qz7zArchiveProperty_T *property = qzMalloc(sizeof(Qz7zArchiveProperty_T), 0, PINNED_MEM); if (!property) { QZ_ERROR("malloc error\n"); return NULL; } property->id = QZ7Z_PROPERTY_ID_INTEL7Z_1001; property->size = sizeof(g_property_data); property->data = malloc(property->size * sizeof(unsigned char)); CHECK_ALLOC_RETURN_VALUE(property->data) memcpy(property->data, g_property_data, property->size); property->next = NULL; return property; } Qz7zEndHeader_T *generateEndHeader(Qz7zItemList_T *the_list, size_t compressed_size) { Qz7zEndHeader_T *header = malloc(sizeof(Qz7zEndHeader_T)); CHECK_ALLOC_RETURN_VALUE(header) header->propertyInfo = generatePropertyInfo(); header->streamsInfo = generateStreamsInfo(the_list, compressed_size); header->filesInfo = generateFilesInfo(the_list); return header; } QzCatagoryTable_T *createCatagoryList() { QzCatagoryTable_T *cat_tbl; cat_tbl = malloc(sizeof(QzCatagoryTable_T)); CHECK_ALLOC_RETURN_VALUE(cat_tbl) cat_tbl->cat_num = sizeof(g_category_names) / sizeof(g_category_names[0]); cat_tbl->catas = malloc(cat_tbl->cat_num * sizeof(QzCatagory_T)); CHECK_ALLOC_RETURN_VALUE(cat_tbl->catas) // the last one for all other files for (int i = 0; i < cat_tbl->cat_num; ++i) { cat_tbl->catas[i].cat_id = i; cat_tbl->catas[i].cat_name = g_category_names[i]; cat_tbl->catas[i].cat_files = qzListCreate(1000); } return cat_tbl; } int getCatagory(QzCatagoryTable_T *tbl, Qz7zFileItem_T *p) { return 0; } /* * return 0 success * -1 failed */ int scanFilesIntoCatagory(Qz7zItemList_T *the_list) { int cat_index; QzListHead_T *files = the_list->items[1]; QzCatagory_T *cat = the_list->table->catas; for (int i = 0; i < files->total; ++i) { Qz7zFileItem_T *p = qzListGet(files, i); // decide the category for the fileitem cat_index = getCatagory(the_list->table, p); // add to the category list qzListAdd(cat[cat_index].cat_files, (void **)&p); } return 0; } int writeSignatureHeader(Qz7zSignatureHeader_T *header, FILE *fp) { size_t n; n = fwrite(header->signature, 1, sizeof(header->signature), fp); CHECK_FWRITE_RETURN(n, sizeof(header->signature)) n = fwrite(&header->majorVersion, 1, sizeof(header->majorVersion), fp); CHECK_FWRITE_RETURN(n, sizeof(header->majorVersion)) n = fwrite(&header->minorVersion, 1, sizeof(header->minorVersion), fp); CHECK_FWRITE_RETURN(n, sizeof(header->minorVersion)) n = fwrite(&header->startHeaderCRC, 1, sizeof(header->startHeaderCRC), fp); CHECK_FWRITE_RETURN(n, sizeof(header->startHeaderCRC)) n = fwrite(&header->nextHeaderOffset, 1, sizeof(header->nextHeaderOffset), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderOffset)) n = fwrite(&header->nextHeaderSize, 1, sizeof(header->nextHeaderSize), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderSize)) n = fwrite(&header->nextHeaderCRC, 1, sizeof(header->nextHeaderCRC), fp); CHECK_FWRITE_RETURN(n, sizeof(header->nextHeaderCRC)) return QZ7Z_OK; } /* * write property structure to file * if crc is not null, return the crc of the bytes that have written * return the bytes of written */ size_t writeArchiveProperties(Qz7zArchiveProperty_T *property, FILE *fp, uint32_t *crc) { size_t size; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_ARCHIVE_PROPERTIES, fp, crc); total_size += writeNumber(property->id, fp, crc); total_size += writeNumber(property->size, fp, crc); size = fwrite(property->data, 1, property->size, fp); CHECK_FWRITE_RETURN(size, property->size) *crc = crc32(*crc, property->data, property->size); total_size += size; total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writePackInfo(Qz7zPackInfo_T *pack, FILE *fp, uint32_t *crc) { int i; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_PACKINFO, fp, crc); total_size += writeNumber(pack->PackPos, fp, crc); total_size += writeNumber(pack->NumPackStreams, fp, crc); total_size += writeTag(PROPERTY_ID_SIZE, fp, crc); for (i = 0; i < pack->NumPackStreams; ++i) { total_size += writeNumber(pack->PackSize[i], fp, crc); } total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeFolder(Qz7zFolderInfo_T *folder, FILE *fp, uint32_t *crc) { int i; size_t size; size_t total_size = 0; Qz7zCoder_T *coder = folder->coder_list; total_size += writeNumber(folder->numCoders, fp, crc); for (i = 0; i < folder->numCoders; ++i) { total_size += writeByte(coder->coderFirstByte.uc, fp, crc); size = fwrite(coder->codecID, sizeof(unsigned char), coder->coderFirstByte.st.CodecIdSize, fp); CHECK_FWRITE_RETURN(size, coder->coderFirstByte.st.CodecIdSize) total_size += size; *crc = crc32(*crc, coder->codecID, coder->coderFirstByte.st.CodecIdSize); } return total_size; } size_t writeCodersInfo(Qz7zCodersInfo_T *coders, FILE *fp, uint32_t *crc) { int i; size_t total_size = 0; total_size += writeTag(PROPERTY_ID_UNPACKINFO, fp, crc); total_size += writeTag(PROPERTY_ID_FOLDER, fp, crc); total_size += writeNumber(coders->numFolders, fp, crc); total_size += writeByte(0, fp, crc); // external = 0 for (i = 0; i < coders->numFolders; ++i) { total_size += writeFolder(&coders->folders[i], fp, crc); } total_size += writeTag(PROPERTY_ID_CODERS_UNPACK_SIZE, fp, crc); for (i = 0; i < coders->numFolders; ++i) { total_size += writeNumber(coders->unPackSize[i], fp, crc); } total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeDigestInfo(Qz7zDigest_T *digest, FILE *fp, uint32_t *crc) { int i; size_t size; size_t total_size = 0; total_size += writeByte(digest->allAreDefined, fp, crc); for (i = 0; i < digest->numStreams; ++i) { size = fwrite(&digest->crc[i], sizeof(digest->crc[i]), 1, fp); CHECK_FWRITE_RETURN(size, 1) total_size += size * sizeof(digest->crc[i]); *crc = crc32(*crc, (unsigned char *)&digest->crc[i], sizeof(digest->crc[i])); } return total_size; } size_t writeSubstreamsInfo(Qz7zSubstreamsInfo_T *substreams, FILE *fp, uint32_t *crc) { int i, j; int total_index = 0; size_t total_size = 0; if (!substreams) return 0; total_size += writeTag(PROPERTY_ID_SUBSTREAMSINFO, fp, crc); total_size += writeTag(PROPERTY_ID_NUM_UNPACK_STREAM, fp, crc); for (i = 0; i < substreams->numFolders; ++i) { total_size += writeNumber(substreams->numUnPackStreams[i], fp, crc); } total_size += writeTag(PROPERTY_ID_SIZE, fp, crc); for (i = 0; i < substreams->numFolders; ++i) { for (j = 0; j < substreams->numUnPackStreams[i] - 1; ++j) { total_size += writeNumber(substreams->unPackSize[total_index++], fp, crc); } } total_size += writeTag(PROPERTY_ID_CRC, fp, crc); total_size += writeDigestInfo(substreams->digests, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } size_t writeStreamsInfo(Qz7zStreamsInfo_T *streams, FILE *fp, uint32_t *crc) { size_t total_size = 0; if (!streams) return 0; total_size += writeTag(PROPERTY_ID_MAIN_STREAMSINFO, fp, crc); total_size += writePackInfo(streams->packInfo, fp, crc); total_size += writeCodersInfo(streams->codersInfo, fp, crc); total_size += writeSubstreamsInfo(streams->substreamsInfo, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } static unsigned char *calculateEmptyStreamProperty(int m, int n, uint64_t *size) { unsigned char *res; unsigned char sum = 0; *size = (!((m + n) % 8)) ? (m + n) / 8 : (m + n) / 8 + 1; res = malloc(*size); CHECK_ALLOC_RETURN_VALUE(res) memset(res, 0, *size); int i, j = 0, k; for (i = 0; i < m / 8; ++i) { res[j++] = 0xff; } for (i = 0, k = 7; i < m % 8; ++i, --k) { sum += 1 << k; } res[j++] = sum; return res; } static unsigned char *calculateEmptyFileProperty(Qz7zFilesInfo_T *files, int m, uint64_t *size) { int i, j; *size = (!((m) % 8)) ? (m) / 8 : ((m) / 8 + 1); unsigned char *res = malloc(*size); CHECK_ALLOC_RETURN_VALUE(res) memset(res, 0, *size); int total_index = 0; for (i = 0; i < *size; ++i) { for (j = 7; j >= 0; --j) { Qz7zFileItem_T *p = qzListGet(files->head[0], total_index++); if (!p) { QZ_ERROR("Cannot get the file from list\n"); free(res); return NULL; } if (p->isEmpty) { QZ_DEBUG("%s is empty stream: i=%d j=%d\n", p->fileName, i, j); res[i] += 1 << j; } if (total_index == m) break; } } return res; } static unsigned char *genNamesPart(QzListHead_T *head_dir, QzListHead_T *head_file, uint64_t *size) { int i; int j; // for buf index int k; uint64_t n_dir = head_dir->total; uint64_t n_file = head_file->total; Qz7zFileItem_T *p; unsigned char *buf; int buf_len = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); buf_len += 2 * (p->nameLength - p->baseNameLength); } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); buf_len += 2 * (p->nameLength - p->baseNameLength); } buf = malloc(buf_len + 1); CHECK_ALLOC_RETURN_VALUE(buf) k = 0; buf[k++] = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); for (j = p->baseNameLength; j < p->nameLength; ++j) { buf[k++] = p->fileName[j]; buf[k++] = 0; } } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); for (j = p->baseNameLength; j < p->nameLength; ++j) { buf[k++] = p->fileName[j]; buf[k++] = 0; } } *size = k; return buf; } static uint32_t *genAttributes(QzListHead_T *head_dir, QzListHead_T *head_file) { int i; int k; uint64_t n_dir = head_dir->total; uint64_t n_file = head_file->total; Qz7zFileItem_T *p; uint32_t *buf; buf = malloc(sizeof(((Qz7zFileItem_T *)0)->attribute) * (n_dir + n_file)); CHECK_ALLOC_RETURN_VALUE(buf) k = 0; for (i = 0; i < n_dir; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_dir, i); buf[k++] = p->attribute; } for (i = 0; i < n_file; ++i) { p = (Qz7zFileItem_T *)qzListGet(head_file, i); buf[k++] = p->attribute; } return buf; } static int checkZerobyteFiles(Qz7zFilesInfo_T *files) { Qz7zFileItem_T *pfile; int i; int n = files->head[0]->total; for (i = 0; i < n; ++i) { pfile = qzListGet(files->head[0], i); if (!pfile) { QZ_ERROR("Cannot get file from list\n"); exit(ERROR); } if (pfile->isEmpty) return 1; } return 0; } size_t writeFilesInfo(Qz7zFilesInfo_T *files, FILE *fp, uint32_t *crc) { int n_emptystream = files->head[0]->total; int n_file = files->head[1]->total; uint64_t size = 0; size_t ret_size; unsigned char *p; uint64_t total_size = 0; unsigned char *buf; uint32_t *attributes; int has_zerobyte_file = 0; total_size += writeTag(PROPERTY_ID_FILESINFO, fp, crc); total_size += writeNumber(files->num, fp, crc); total_size += writeTag(PROPERTY_ID_EMPTY_STREAM, fp, crc); p = calculateEmptyStreamProperty(n_emptystream, n_file, &size); total_size += writeNumber(size, fp, crc); ret_size = fwrite(p, 1, size, fp); CHECK_FWRITE_RETURN(size, ret_size) total_size += ret_size; *crc = crc32(*crc, p, size); free(p); p = NULL; has_zerobyte_file = checkZerobyteFiles(files); if (n_emptystream && has_zerobyte_file) { total_size += writeTag(PROPERTY_ID_EMPTY_FILE, fp, crc); p = calculateEmptyFileProperty(files, n_emptystream, &size); if (!p) { QZ_ERROR("Cannot calculate emptyfile property\n"); exit(ERROR); } total_size += writeNumber(size, fp, crc); ret_size = fwrite(p, 1, size, fp); CHECK_FWRITE_RETURN(size, ret_size) total_size += ret_size; *crc = crc32(*crc, p, size); free(p); p = NULL; } total_size += writeTag(PROPERTY_ID_DUMMY, fp, crc); total_size += writeNumber(2, fp, crc); total_size += writeByte(PROPERTY_CONTENT_DUMMY, fp, crc); total_size += writeByte(PROPERTY_CONTENT_DUMMY, fp, crc); total_size += writeTag(PROPERTY_ID_NAME, fp, crc); buf = genNamesPart(files->head[0], files->head[1], &size); total_size += writeNumber(size, fp, crc); ret_size = fwrite(buf, 1, size, fp); CHECK_FWRITE_RETURN(ret_size, size) total_size += ret_size; *crc = crc32(*crc, buf, size); free(buf); int i; Qz7zFileItem_T *pfile; FILETIME_T win_time; total_size += writeTag(PROPERTY_ID_MTIME, fp, crc); total_size += writeNumber((n_emptystream + n_file) * 8 + 2, fp, crc); total_size += writeTag(1, fp, crc); total_size += writeTag(0, fp, crc); for (i = 0; i < n_emptystream; ++i) { pfile = (Qz7zFileItem_T *)qzListGet(files->head[0], i); win_time = unixtimeToFiletime(pfile->mtime, pfile->mtime_nano); total_size += writeTime(win_time.low, fp, crc); total_size += writeTime(win_time.high, fp, crc); } for (i = 0; i < n_file; ++i) { pfile = (Qz7zFileItem_T *)qzListGet(files->head[1], i); win_time = unixtimeToFiletime(pfile->mtime, pfile->mtime_nano); total_size += writeTime(win_time.low, fp, crc); total_size += writeTime(win_time.high, fp, crc); } total_size += writeTag(PROPERTY_ID_ATTRIBUTES, fp, crc); attributes = genAttributes(files->head[0], files->head[1]); size = 2 + 4 * (n_emptystream + n_file); total_size += writeNumber(size, fp, crc); total_size += writeByte(FLAG_ATTR_DEFINED_SET, fp, crc); total_size += writeByte(FLAG_ATTR_EXTERNAL_UNSET, fp, crc); for (i = 0; i < n_emptystream + n_file; ++i) { total_size += writeTime(attributes[i], fp, crc); } free(attributes); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } /** * return total size that has written */ size_t writeEndHeader(Qz7zEndHeader_T *header, FILE *fp, uint32_t *crc) { size_t total_size = 0; if (!crc) { QZ_ERROR("bad crc param\n"); return 0; } total_size += writeTag(PROPERTY_ID_HEADER, fp, crc); total_size += writeArchiveProperties(header->propertyInfo, fp, crc); total_size += writeStreamsInfo(header->streamsInfo, fp, crc); total_size += writeFilesInfo(header->filesInfo, fp, crc); total_size += writeTag(PROPERTY_ID_END, fp, crc); return total_size; } Qz7zItemList_T *itemListCreate(int n, char **files) { int i; uint32_t dir_index = 0; // the index of next processing directory in the dir list Qz7zFileItem_T *fi = NULL; DIR *dirp = NULL; char *dirc = NULL; char *absolute_path; char dir_name[PATH_MAX + 1] = {0}; char path[PATH_MAX]; Qz7zItemList_T *res = calloc(1, sizeof(Qz7zItemList_T)); if (!res) { QZ_ERROR("malloc error\n"); return NULL; } res->items[0] = qzListCreate(QZ_DIRLIST_DEFAULT_NUM_PER_NODE); res->items[1] = qzListCreate(QZ_FILELIST_DEFAULT_NUM_PER_NODE); QzListHead_T *dirs_head = res->items[0]; QZ_DEBUG("dirs_head : %p\n", (void *)dirs_head); QzListHead_T *files_head = res->items[1]; QZ_DEBUG("files_head : %p\n", (void *)files_head); for (i = 0; i < n; ++i) { #ifdef QZ7Z_DEBUG QZ_DEBUG("process %dth parameter: %s\n", i + 1, files[optind]); #endif absolute_path = realpath(files[optind], path); if (NULL == absolute_path) { goto error; } strncpy(dir_name, absolute_path, PATH_MAX); dirc = dirname(dir_name); fi = fileItemCreate(absolute_path); if (!fi) { QZ_ERROR("Cannot create file\n"); goto error; } if (strcmp(dirc, "/")) { fi->baseNameLength = strlen(dirc) + 1; } else { fi->baseNameLength = strlen(dirc); } if (fi->isDir || fi->isEmpty) { qzListAdd(dirs_head, (void **)&fi); // add it to directory list while (dir_index < dirs_head->total) { Qz7zFileItem_T *processing = (Qz7zFileItem_T *)qzListGet(dirs_head, dir_index); if (processing == NULL) { QZ_DEBUG("qzListGet got NULL!\n"); goto error; } QZ_DEBUG("processing: %s\n", processing->fileName); if (processing->isDir) { struct dirent *dentry; dirp = opendir(processing->fileName); if (!dirp) { QZ_ERROR("errors ocurs: %s \n", strerror(errno)); goto error; } while ((dentry = readdir(dirp))) { char file_path[PATH_MAX + 1]; memset(file_path, 0, PATH_MAX + 1); if (!strcmp(dentry->d_name, ".")) continue; if (!strcmp(dentry->d_name, "..")) continue; snprintf(file_path, sizeof file_path, "%s/%s", processing->fileName, dentry->d_name); QZ_DEBUG(" file_path: %s\n", file_path); Qz7zFileItem_T *anotherfile = fileItemCreate(file_path); if (!anotherfile) { QZ_ERROR("Cannot create file\n"); closedir(dirp); goto error; } if (strcmp(dirc, "/")) { anotherfile->baseNameLength = strlen(dirc) + 1; } else { anotherfile->baseNameLength = strlen(dirc); } if (anotherfile->isDir || anotherfile->isEmpty) { qzListAdd(dirs_head, (void **)&anotherfile); } else { qzListAdd(files_head, (void **)&anotherfile); } } closedir(dirp); } dir_index++; } } else { qzListAdd(files_head, (void **)&fi); } optind++; }// end for /* now the res->items has been resolved successfully */ res->table = createCatagoryList(); scanFilesIntoCatagory(res); return res; error: if (res) { itemListDestroy(res); } return NULL; } /** * return 1 if 7z archive is good, others if not */ int check7zArchive(const char *archive) { int sig_wrong; size_t n; unsigned char buf[8]; FILE *fp = fopen(archive, "r"); if (!fp) { perror(archive); return QZ7Z_ERR_OPEN; } n = fread(buf, 1, sizeof(buf), fp); if (n < sizeof(buf)) { fclose(fp); return -1; } if ((sig_wrong = memcmp(buf, g_header_signature, sizeof(g_header_signature)))) { QZ_ERROR("The archive signature header is broken\n"); fclose(fp); return QZ7Z_ERR_SIG_HEADER_BROKEN; } if (buf[6] != 0 || buf[7] != 4) { QZ_DEBUG("Warning: The 7z archive version is not 0.4\n"); QZ_DEBUG("Warning: Maybe has some issues for other version\n"); } fclose(fp); return 1; } /* * 1 if filename is dir, 0 if not */ int checkDirectory(const char *filename) { struct stat buf; stat(filename, &buf); if (S_ISDIR(buf.st_mode)) { return 1; } else { return 0; } } QATzip-1.2.1/utils/qzip_main.c000066400000000000000000000272611465165016500161770ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2007-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzip.h" int main(int argc, char **argv) { int ret = QZ_OK; int arg_count; /* number of files or directories to process */ g_program_name = qzipBaseName(argv[0]); char *out_name = NULL; FILE *stream_out = NULL; int option_f = 0; Qz7zItemList_T *the_list; int is_good_7z = 0; int is_dir = 0; int recursive_mode = 0; errno = 0; int is_format_set = 0; char resolved_path[PATH_MAX]; while (true) { int optc; int long_idx = -1; char *stop = NULL; optc = getopt_long(argc, argv, g_short_opts, g_long_opts, &long_idx); if (optc < 0) { break; } switch (optc) { case 'd': g_decompress = 1; break; case 'h': help(); exit(OK); break; case 'k': g_keep = 1; break; case 'V': version(); exit(OK); break; case 'R': recursive_mode = 1; break; case 'A': if (strcmp(optarg, "deflate") == 0) { g_params_th.comp_algorithm = QZ_DEFLATE; } else if (strcmp(optarg, "lz4") == 0) { g_params_th.comp_algorithm = QZ_LZ4; } else if (strcmp(optarg, "lz4s") == 0) { g_params_th.comp_algorithm = QZ_LZ4s; } else if (strcmp(optarg, "zstd") == 0) { g_params_th.comp_algorithm = QZ_ZSTD; } else { QZ_ERROR("Error service arg: %s\n", optarg); return -1; } break; case 'H': if (strcmp(optarg, "static") == 0) { g_params_th.huffman_hdr = QZ_STATIC_HDR; } else if (strcmp(optarg, "dynamic") == 0) { g_params_th.huffman_hdr = QZ_DYNAMIC_HDR; } else { QZ_ERROR("Error huffman arg: %s\n", optarg); return -1; } break; case 'O': if (strcmp(optarg, "gzip") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_GZIP; } else if (strcmp(optarg, "gzipext") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_GZIP_EXT; } else if (strcmp(optarg, "7z") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_RAW; } else if (strcmp(optarg, "deflate_4B") == 0) { g_params_th.data_fmt = QZIP_DEFLATE_4B; } else if (strcmp(optarg, "lz4") == 0) { g_params_th.data_fmt = QZIP_LZ4_FH; } else if (strcmp(optarg, "lz4s") == 0) { g_params_th.data_fmt = QZIP_LZ4S_BK; } else { QZ_ERROR("Error gzip header format arg: %s\n", optarg); return -1; } is_format_set = 1; break; case 'o': out_name = optarg; break; case 'L': g_params_th.comp_lvl = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || ERANGE == errno || g_params_th.comp_lvl > QZ_DEFLATE_COMP_LVL_MAXIMUM || g_params_th.comp_lvl <= 0) { QZ_ERROR("Error compLevel arg: %s\n", optarg); return -1; } break; case 'C': g_params_th.hw_buff_sz = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || ERANGE == errno || g_params_th.hw_buff_sz > USDM_ALLOC_MAX_SZ / 2) { printf("Error chunk size arg: %s\n", optarg); return -1; } break; case 'r': g_params_th.req_cnt_thrshold = QZIP_GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (*stop != '\0' || errno) { printf("Error request count threshold: %s\n", optarg); return -1; } break; case 'f': option_f = 1; break; case 'P': if (strcmp(optarg, "busy") == 0) { g_params_th.polling_mode = QZ_BUSY_POLLING; } else { printf("Error set polling mode: %s\n", optarg); return -1; } break; default: tryHelp(); } } arg_count = argc - optind; if (0 == arg_count && isatty(fileno((FILE *)stdin))) { help(); exit(OK); } if (g_decompress) { if (g_params_th.data_fmt == QZIP_LZ4S_BK) { QZ_ERROR("Don't support lz4s decompression.\n"); exit(ERROR); } g_params_th.direction = QZ_DIR_DECOMPRESS; } else { g_params_th.direction = QZ_DIR_COMPRESS; } if (0 == arg_count) { if (isatty(fileno((FILE *)stdout)) && 0 == option_f && 0 == g_decompress) { printf("qzip: compressed data not written to a terminal. " "Use -f to force compression.\n"); printf("For help, type: qzip -h\n"); } else { if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } stream_out = stdout; stdout = freopen(NULL, "w", stdout); processStream(&g_sess, stdin, stream_out, g_decompress == 0); } } else if (g_params_th.data_fmt == QZIP_DEFLATE_RAW && !g_decompress) { //compress into 7z QZ_DEBUG("going to compress files into 7z archive ...\n"); if (!out_name) { QZ_ERROR("Should use '-o' to specify an output name\n"); help(); exit(ERROR); } if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } for (int i = 0, j = optind; i < arg_count; ++i, ++j) { if (access(argv[j], F_OK)) { QZ_ERROR("%s: No such file or directory\n", argv[j]); exit(ERROR); } } the_list = itemListCreate(arg_count, argv); if (!the_list) { exit(ERROR); } ret = qz7zCompress(&g_sess, the_list, out_name); itemListDestroy(the_list); } else { // decompress from 7z; compress into gz; decompress from gz while (optind < argc) { /* To avoid CWE-22: Improper Limitation of a Pathname to a Restricted Directory * ('Path Traversal') attacks. * http://cwe.mitre.org/data/definitions/22.html */ if (!realpath(argv[optind], resolved_path)) { QZ_ERROR("%s: No such file or directory\n", argv[optind]); exit(ERROR); } QzSuffix_T suffix = getSuffix(argv[optind]); is_dir = checkDirectory(argv[optind]); if (g_decompress && !is_dir) { QzSuffixCheckStatus_T check_res = checkSuffix(suffix, is_format_set); if (E_CHECK_SUFFIX_UNSUPPORT == check_res) { QZ_ERROR("Error: %s: Wrong suffix. Supported suffix: 7z/gz/lz4.\n", argv[optind]); exit(ERROR); } if (E_CHECK_SUFFIX_FORMAT_UNMATCH == check_res) { QZ_ERROR("Error: %s: Suffix is not matched with format\n", argv[optind]); exit(ERROR); } } if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } if (g_decompress) { if (!recursive_mode) { if (suffix == E_SUFFIX_7Z) { is_good_7z = check7zArchive(argv[optind]); if (is_good_7z < 0) { exit(ERROR); } if (arg_count > 1) { fprintf(stderr, "only support decompressing ONE 7z " "archive for ONE command!\n"); exit(ERROR); } QZ_DEBUG(" this is a 7z archive, " "going to decompress ... \n"); g_params_th.data_fmt = QZIP_DEFLATE_RAW; if (qatzipSetup(&g_sess, &g_params_th)) { fprintf(stderr, "qatzipSetup session failed\n"); exit(ERROR); } ret = qz7zDecompress(&g_sess, argv[optind++]); } else if (suffix == E_SUFFIX_GZ) { processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } else if (suffix == E_SUFFIX_LZ4) { if (g_params_th.data_fmt != QZIP_LZ4_FH) { QZ_ERROR("Error: Suffix(.lz4) doesn't match the data format," "please confirm the data format\n"); exit(ERROR); } processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } else { QZ_ERROR("Error: %s: Wrong suffix. Supported suffix: " "7z/gz/lz4.\n", argv[optind]); exit(ERROR); } } else { processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } } else { // compress processFile(&g_sess, argv[optind++], out_name, g_decompress == 0); } } } if (qatzipClose(&g_sess)) { exit(ERROR); } return ret; } QATzip-1.2.1/utils/qzstd.c000066400000000000000000000433561465165016500153600ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include "qzstd.h" QzSession_T qzstd_g_sess; QzSessionParamsLZ4S_T g_sess_params = {{0}}; QzSessionParamsLZ4S_T sess_params_zstd_default = { .common_params.direction = QZ_DIR_COMPRESS, .common_params.comp_lvl = QZ_COMP_LEVEL_DEFAULT, .common_params.comp_algorithm = QZ_LZ4s, .common_params.max_forks = QZ_MAX_FORK_DEFAULT, .common_params.sw_backup = QZ_SW_BACKUP_DEFAULT, .common_params.hw_buff_sz = QZ_HW_BUFF_SZ, .common_params.strm_buff_sz = QZ_STRM_BUFF_SZ_DEFAULT, .common_params.input_sz_thrshold = QZ_COMP_THRESHOLD_DEFAULT, .common_params.req_cnt_thrshold = 32, .common_params.wait_cnt_thrshold = QZ_WAIT_CNT_THRESHOLD_DEFAULT, .common_params.polling_mode = QZ_PERIODICAL_POLLING, .lz4s_mini_match = 3, .qzCallback = zstdCallBack, .qzCallback_external = NULL }; static unsigned int LZ4MINMATCH = 2; void qzstd_help() { static char const *const help_msg[] = { "Compress or uncompress a file with zstandard format.", "", " -d, decompress", " -h, show help information", " -L, set compression level of QAT", " -o, set output file name", " -C, set zstd block size && QAT hw buffer size", " -r, set max in-flight request number", " -P, set polling mode, only supports busy polling settings", " -m, set the mini match size for the lz4s search algorithm, \ only support mini_match 3 and 4", "", "Only support one input file.", 0 }; char const *const *p = help_msg; while (*p) { printf("%s\n", *p++); } } static double get_time_diff(struct timeval time_e, struct timeval time_s) { unsigned long us_begin = time_s.tv_sec * 1000000 + time_s.tv_usec; unsigned long us_end = time_e.tv_sec * 1000000 + time_e.tv_usec; return us_end - us_begin; } unsigned qzstd_isLittleEndian(void) { const union { U32 u; BYTE c[4]; } one = {1}; /* don't use static : performance detrimental */ return one.c[0]; } static U16 qzstd_read16(const void *memPtr) { U16 val; memcpy(&val, memPtr, sizeof(val)); return val; } U16 qzstd_readLE16(const void *memPtr) { if (qzstd_isLittleEndian()) { return qzstd_read16(memPtr); } else { const BYTE *p = (const BYTE *)memPtr; return (U16)((U16)p[0] + (p[1] << 8)); } } void decLz4Block(unsigned char *lz4s, int lz4sSize, ZSTD_Sequence *zstdSeqs, unsigned int *seq_offset) { unsigned char *ip = lz4s; unsigned char *endip = lz4s + lz4sSize; while (ip < endip && lz4sSize > 0) { size_t length = 0; size_t offset = 0; unsigned int literalLen = 0, matchlen = 0; /* get literal length */ unsigned const token = *ip++; if ((length = (token >> ML_BITS)) == RUN_MASK) { unsigned s; do { s = *ip++; length += s; } while (s == 255); } literalLen = (unsigned short)length; ip += length; if (ip == endip) { // Meet the end of the LZ4 sequence /* update ZSTD_Sequence */ zstdSeqs[*seq_offset].litLength += literalLen; continue; } /* get matchPos */ offset = qzstd_readLE16(ip); ip += 2; /* get match length */ length = token & ML_MASK; if (length == ML_MASK) { unsigned s; do { s = *ip++; length += s; } while (s == 255); } if (length != 0) { length += LZ4MINMATCH; matchlen = (unsigned short)length; /* update ZSTD_Sequence */ zstdSeqs[*seq_offset].offset = offset; zstdSeqs[*seq_offset].litLength += literalLen; zstdSeqs[*seq_offset].matchLength = matchlen; ++(*seq_offset); assert(*seq_offset <= ZSTD_SEQUENCES_SIZE); } else { if (literalLen > 0) { /* When match length is 0, the literalLen needs to be temporarily stored and processed together with the next data block. If also ip == endip, need to convert sequences to seqStore.*/ zstdSeqs[*seq_offset].litLength += literalLen; } } } assert(ip == endip); } inline int getLz4FrameHeaderSz() { return QZ_LZ4_HEADER_SIZE; } inline int getLz4BlkHeaderSz() { return QZ_LZ4_BLK_HEADER_SIZE; } inline int getLZ4FooterSz() { return QZ_LZ4_FOOTER_SIZE; } int getContentSize(unsigned char *const ptr) { QzLZ4H_T *hdr = NULL; hdr = (QzLZ4H_T *)ptr; assert(hdr->magic == QZ_LZ4_MAGIC); return hdr->cnt_size; } unsigned int getBlockSize(unsigned char *const ptr) { unsigned int blk_sz = *(unsigned int *)ptr; return blk_sz; } int zstdCallBack(void *external, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, int *ExtStatus) { int ret = QZ_OK; //copied data is used to decode //original data will be overwrote by ZSTD_compressSequences unsigned char *dest_data = (unsigned char *)malloc(*dest_len); assert(dest_data != NULL); memcpy(dest_data, dest, *dest_len); unsigned char *cur = dest_data; unsigned char *end = dest_data + *dest_len; ZSTD_Sequence *zstd_seqs = (ZSTD_Sequence *)calloc(ZSTD_SEQUENCES_SIZE, sizeof(ZSTD_Sequence)); assert(zstd_seqs != NULL); ZSTD_CCtx *zc = (ZSTD_CCtx *)external; unsigned int produced = 0; unsigned int consumed = 0; unsigned int cnt_sz = 0, blk_sz = 0; //content size and block size unsigned int dec_offset = 0; while (cur < end && *dest_len > 0) { //decode block header and get block size blk_sz = getBlockSize(cur); cur += getLz4BlkHeaderSz(); //decode lz4s sequences into zstd sequences decLz4Block(cur, blk_sz, zstd_seqs, &dec_offset); cur += blk_sz; cnt_sz = 0; for (unsigned int i = 0; i < dec_offset + 1 ; i++) { cnt_sz += (zstd_seqs[i].litLength + zstd_seqs[i].matchLength) ; } assert(cnt_sz <= MAX_BLOCK_SIZE); // compress sequence to zstd frame int compressed_sz = ZSTD_compressSequences(zc, dest + produced, ZSTD_compressBound(cnt_sz), zstd_seqs, dec_offset + 1, src + consumed, cnt_sz); if (compressed_sz < 0) { ret = QZ_POST_PROCESS_ERROR; *ExtStatus = compressed_sz; QZ_ERROR("%s : ZSTD API ZSTD_compressSequences failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, *ExtStatus, DECODE_ZSTD_ERROR_CODE(*ExtStatus)); goto done; } //reuse zstd_seqs memset(zstd_seqs, 0, ZSTD_SEQUENCES_SIZE * sizeof(ZSTD_Sequence)); dec_offset = 0; produced += compressed_sz; consumed += cnt_sz; } *dest_len = produced; done: free(dest_data); free(zstd_seqs); return ret; } int qzZstdGetDefaults(QzSessionParamsLZ4S_T *defaults) { if (defaults == NULL) { QZ_ERROR("%s : QzSessionParams ptr is empty\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } QZ_MEMCPY(defaults, &sess_params_zstd_default, sizeof(QzSessionParamsLZ4S_T), sizeof(QzSessionParamsLZ4S_T)); return QZSTD_OK; } int compressFile(int in_file, int out_file) { long input_file_size = 0; long output_file_size = 0; unsigned int src_buffer_size = 0; unsigned int dst_buffer_size = 0; unsigned int max_dst_buffer_size = 0; unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; unsigned int block_size = ZSRC_BUFF_LEN; long file_remaining = 0; unsigned int bytes_read = 0; int rc = QZSTD_OK; int is_compress = 1; uint64_t callback_error_code = 0; //initial zstd context ZSTD_CCtx *zc = ZSTD_createCCtx(); if (zc == NULL) { QZ_ERROR("%s : ZSTD_createCCtx failed\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } ZSTD_CCtx_setParameter(zc, ZSTD_c_blockDelimiters, ZSTD_sf_explicitBlockDelimiters); g_sess_params.qzCallback_external = (void *)zc; /* Different mini_match would use different LZ4MINMATCH to decode * lz4s sequence. note that when it is mini_match is 4, the LZ4MINMATCH * should be 3. if mini match is 3, then LZ4MINMATCH should be 2*/ LZ4MINMATCH = g_sess_params.lz4s_mini_match == 4 ? 3 : 2; /* Align zstd minmatch to the QAT minmatch */ ZSTD_CCtx_setParameter( zc, ZSTD_c_minMatch, g_sess_params.lz4s_mini_match >= 4 ? 4 : 3 ); //setup session int ret = qzInit(&qzstd_g_sess, g_sess_params.common_params.sw_backup); if (ret != QZ_OK && ret != QZ_DUPLICATE) { QZ_ERROR("%s : qzInit failed with error code %d\n", QZ_ERROR_TYPE, ret); return QZSTD_ERROR; } ret = qzSetupSessionLZ4S(&qzstd_g_sess, &g_sess_params); if (ret != QZ_OK) { QZ_ERROR("%s : qzSetupSession failed with error code %d\n", QZ_ERROR_TYPE, ret); return QZSTD_ERROR; } //get input file size input_file_size = lseek(in_file, 0, SEEK_END); lseek(in_file, 0, SEEK_SET); src_buffer_size = (input_file_size > block_size) ? block_size : input_file_size; int max_zstd_sz = ZSTD_compressBound(src_buffer_size); int max_lz4_sz = LZ4_compressBound(src_buffer_size); max_dst_buffer_size = (max_zstd_sz > max_lz4_sz) ? max_zstd_sz * 2 : max_lz4_sz * 2; src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(max_dst_buffer_size); assert(dst_buffer != NULL); file_remaining = input_file_size; struct timeval time_s; struct timeval time_e; double time = 0.0f; do { bytes_read = read(in_file, src_buffer, src_buffer_size); QZ_PRINT("Reading input file (%u Bytes)\n", bytes_read); puts("compressing..."); dst_buffer_size = max_dst_buffer_size; gettimeofday(&time_s, NULL); if (bytes_read < g_sess_params.common_params.input_sz_thrshold) { //goto sw compress dst_buffer_size = ZSTD_compressCCtx(zc, dst_buffer, dst_buffer_size, src_buffer, bytes_read, 1); if ((int)dst_buffer_size <= 0) { QZ_ERROR("%s : ZSTD API ZSTD_compressCCtx failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, dst_buffer_size, DECODE_ZSTD_ERROR_CODE(dst_buffer_size)); rc = QZSTD_ERROR; goto done; } } else { //compress by qat int ret = qzCompressExt(&qzstd_g_sess, src_buffer, (unsigned int *)(&bytes_read), dst_buffer, &dst_buffer_size, 1, &callback_error_code); if (QZ_BUF_ERROR == ret && 0 != bytes_read) { if (-1 == lseek(in_file, bytes_read - src_buffer_size, SEEK_CUR)) { QZ_ERROR("%s : failed to re-seek input file\n", QZSTD_ERROR_TYPE); rc = QZSTD_ERROR; goto done; } } else if (QZ_POST_PROCESS_ERROR == ret) { QZ_ERROR("%s : ZSTD API ZSTD_compressSequences failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE((size_t)callback_error_code)); rc = QZSTD_ERROR; goto done; } else if (QZ_OK != ret) { QZ_ERROR("%s : qzCompress failed with error code %d\n", QZ_ERROR_TYPE, ret); rc = QZSTD_ERROR; goto done; } } gettimeofday(&time_e, NULL); time += get_time_diff(time_e, time_s); size_t write_size = write(out_file, dst_buffer, dst_buffer_size); if (write_size != dst_buffer_size) { QZ_ERROR("%s : failed to write output data into file\n", QZSTD_ERROR_TYPE); rc = QZSTD_ERROR; goto done; } output_file_size += write_size; file_remaining -= bytes_read; src_buffer_size = (src_buffer_size < file_remaining) ? src_buffer_size : file_remaining; } while (file_remaining > 0); QzstdDisplayStats(time, input_file_size, output_file_size, is_compress); done: //release resource if (zc != NULL) { ZSTD_freeCCtx(zc); } free(src_buffer); free(dst_buffer); qzTeardownSession(&qzstd_g_sess); qzClose(&qzstd_g_sess); return rc; } int decompressFile(int in_file, int out_file) { long input_file_size = 0; long output_file_size = 0; size_t src_buffer_size = ZSTD_DStreamInSize(); size_t dst_buffer_size = ZSTD_DStreamOutSize(); unsigned char *src_buffer = NULL; unsigned char *dst_buffer = NULL; int rc = QZSTD_OK; int is_compress = 0; struct timeval time_s; struct timeval time_e; double time = 0.0f; //get input file size input_file_size = lseek(in_file, 0, SEEK_END); lseek(in_file, 0, SEEK_SET); src_buffer = malloc(src_buffer_size); assert(src_buffer != NULL); dst_buffer = malloc(dst_buffer_size); assert(dst_buffer != NULL); ZSTD_DCtx *zstd_dctx = ZSTD_createDCtx(); assert(zstd_dctx != NULL); size_t bytes_read = 0; size_t bytes_write = 0; long file_remaining = 0; file_remaining = input_file_size; int ret = 0; do { bytes_read = read(in_file, src_buffer, src_buffer_size); QZ_PRINT("Reading input file (%lu Bytes)\n", bytes_read); puts("Decompressing..."); ZSTD_inBuffer input = { src_buffer, bytes_read, 0 }; while (input.pos < input.size) { ZSTD_outBuffer output = { dst_buffer, dst_buffer_size, 0 }; gettimeofday(&time_s, NULL); ret = ZSTD_decompressStream(zstd_dctx, &output, &input); if (ret < 0) { QZ_ERROR("%s : ZSTD API ZSTD_decompressStream failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE(ret)); rc = QZSTD_ERROR; goto done; } gettimeofday(&time_e, NULL); time += get_time_diff(time_e, time_s); bytes_write = write(out_file, dst_buffer, output.pos); output_file_size += bytes_write; } file_remaining -= bytes_read; src_buffer_size = (src_buffer_size < file_remaining) ? src_buffer_size : file_remaining; } while (file_remaining > 0); if (ret != 0) { QZ_ERROR("%s : ZSTD API ZSTD_decompressStream failed with error code, %d, %s\n", ZSTD_ERROR_TYPE, ret, DECODE_ZSTD_ERROR_CODE(ret)); rc = QZSTD_ERROR; goto done; } QzstdDisplayStats(time, input_file_size, output_file_size, is_compress); done: ZSTD_freeDCtx(zstd_dctx); free(src_buffer); free(dst_buffer); return rc; } void QzstdDisplayStats(double time, off_t insize, off_t outsize, int is_compress) { if (insize && outsize) { assert(0 != time); double size = (is_compress) ? insize : outsize; double throughput = (size * CHAR_BIT) / time; /* in MB (megabytes) */ double compressionRatio = ((double)insize) / ((double)outsize); double spaceSavings = 1 - ((double)outsize) / ((double)insize); QZ_PRINT("Time taken: %9.3lf ms\n", time / 1000); QZ_PRINT("Throughput: %9.3lf Mbit/s\n", throughput); if (is_compress) { QZ_PRINT("Space Savings: %9.3lf %%\n", spaceSavings * 100.0); QZ_PRINT("Compression ratio: %.3lf : 1\n", compressionRatio); } } } QATzip-1.2.1/utils/qzstd.h000066400000000000000000000107241465165016500153560ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #ifndef _UTILS_QZSTD_H #define _UTILS_QZSTD_H #define ZSTD_STATIC_LINKING_ONLY #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_QAT_HEADERS #include #else #include #endif #include /* For qzstd app, there are three types of return errors. * 1. The errors are from top layer software stack * e.g read/write file and app input parameter error. * 2. The errors are from qatzip lib. * e.g QZ_DUPLICATE or QZ_NOSW_NO_HW, error code defined * in qatzip.h * 3. The errors come from zstd lib. * e.g ZSTD_ErrorCode list. error code defined in zstd_error.h * * Note: * Because different type of error may have the same error code * value, To avoid app return value confusion in shell. Use * QZ_ERROR function to print error type and error code. */ // app return status #define QZSTD_OK 0 #define QZSTD_ERROR 1 // Error type for log capture. #define QZSTD_ERROR_TYPE "[QZSTD_ERROR]" #define QZ_ERROR_TYPE "[QZ_LIB_ERROR]" #define ZSTD_ERROR_TYPE "[ZSTD_LIB_ERROR]" #define KB (1024) #define MB (KB * KB) #define ZSTD_SEQUENCES_SIZE (1024 * 32) #define ML_BITS 4 #define ML_MASK ((1U << ML_BITS) - 1) #define RUN_BITS (8 - ML_BITS) #define RUN_MASK ((1U << RUN_BITS) - 1) typedef uint8_t BYTE; typedef uint16_t U16; typedef int16_t S16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; typedef int64_t S64; #define QATZIP_MAX_HW_SZ (512 * KB) #define ZSRC_BUFF_LEN (512 * MB) #define MAX_BLOCK_SIZE (128 * KB) #define DECODE_ZSTD_ERROR_CODE(error_code) \ ZSTD_getErrorString(ZSTD_getErrorCode((size_t)error_code)) void QzstdDisplayStats(double time, off_t insize, off_t outsize, int is_compress); void qzstd_help(); void decLz4Block(unsigned char *lz4s, int lz4sSize, ZSTD_Sequence *zstdSeqs, unsigned int *seq_offset); int qzZstdGetDefaults(QzSessionParamsLZ4S_T *defaults); int compressFile(int in_file, int out_file); int decompressFile(int in_file, int out_file); int zstdCallBack(void *external, const unsigned char *src, unsigned int *src_len, unsigned char *dest, unsigned int *dest_len, int *ExtStatus); int getLz4FrameHeaderSz(); int getLz4BlkHeaderSz(); int getLZ4FooterSz(); int getContentSize(unsigned char *const ptr); unsigned int getBlockSize(unsigned char *const ptr); #endif QATzip-1.2.1/utils/qzstd_main.c000066400000000000000000000157271465165016500163650ustar00rootroot00000000000000/*************************************************************************** * * BSD LICENSE * * Copyright(c) 2021-2024 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ /* sample zstd-qat application */ #include #include #include #include #include #include #include "qzstd.h" extern QzSessionParamsLZ4S_T g_sess_params; int main(int argc, char **argv) { int decompress = 0; struct stat in_file_state; char out_path [PATH_MAX] = {0}; char in_path[PATH_MAX] = {0}; char *out_filename = NULL; char *in_filename = NULL; int in_file = -1; int out_file = -1; char *tmp = NULL; char *suffix = NULL; if (qzZstdGetDefaults(&g_sess_params) != QZ_OK) { return QZSTD_ERROR; } const char *optPatten = "dhC:L:o:r:P:m:"; char *stop = NULL; int ch; while ((ch = getopt(argc, argv, optPatten)) >= 0) { switch (ch) { case 'd': decompress = 1; break; case 'C': g_sess_params.common_params.hw_buff_sz = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); // make sure chunk size smaller than 128kB to fit zstd block size limitation. if (g_sess_params.common_params.hw_buff_sz > 128 * KB) { QZ_ERROR("%s : block size can't bigger than 128 KB\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } break; case 'h': qzstd_help(); return QZSTD_OK; case 'L': g_sess_params.common_params.comp_lvl = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); break; case 'o': out_filename = optarg; break; case 'r': g_sess_params.common_params.req_cnt_thrshold = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); break; case 'P': if (strcmp(optarg, "busy") == 0) { g_sess_params.common_params.polling_mode = QZ_BUSY_POLLING; } else { QZ_ERROR("%s : set wrong polling mode: %s\n", QZSTD_ERROR_TYPE, optarg); return QZSTD_ERROR; } break; case 'm': g_sess_params.lz4s_mini_match = GET_LOWER_32BITS(strtoul(optarg, &stop, 0)); if (g_sess_params.lz4s_mini_match != 3 && g_sess_params.lz4s_mini_match != 4) { QZ_ERROR("%s : mini_match can only set 3 or 4!\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } break; default: qzstd_help(); return QZSTD_OK; } } int arg_count = argc - optind; if (arg_count == 0 || arg_count > 1) { QZ_ERROR("%s : only support one file as input\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } /* argv[optind] is the input file name, need to check the input filename */ in_filename = argv[optind]; in_filename = realpath(in_filename, in_path); if (!in_filename) { QZ_ERROR("Please check input file name %s\n", in_filename); return QZSTD_ERROR; } /* * For compression, if the output file name is not be specified * we need to suffix the input filename with .zst as the output filename */ if (!decompress && !out_filename) { tmp = strrchr(in_filename, '/'); assert(tmp); strncpy(out_path, tmp + 1, PATH_MAX - 1); strcat(out_path, ".zst"); out_filename = &out_path[0]; } /* check the input filename suffix for decompression, * if output file name is not specified, we need to unsuffix the * input filename as the output filename */ if (decompress) { suffix = strrchr(in_filename, '.'); if (suffix == NULL) { QZ_ERROR("%s : unsupported file format\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } if (strcmp(suffix, ".zst")) { QZ_ERROR("%s : unsupported file format\n", QZSTD_ERROR_TYPE); return QZSTD_ERROR; } if (!out_filename) { tmp = strrchr(in_filename, '/'); assert(tmp); strncpy(out_path, tmp + 1, PATH_MAX - 1); suffix = strrchr(out_path, '.'); assert(suffix); suffix[0] = '\0'; out_filename = &out_path[0]; } } in_file = open(in_filename, O_RDONLY); if (in_file < 0) { perror("Cannot open input file"); return QZSTD_ERROR; } if (fstat(in_file, &in_file_state)) { perror("Cannot get file stat"); close(in_file); return QZSTD_ERROR; } out_file = open(out_filename, O_CREAT | O_WRONLY, in_file_state.st_mode); if (out_file == -1) { perror("Cannot open output file"); close(in_file); return QZSTD_ERROR; } if (!decompress) { int rc = compressFile(in_file, out_file); if (rc != QZSTD_OK) { close(in_file); close(out_file); return QZSTD_ERROR; } } else { int rc = decompressFile(in_file, out_file); if (rc != QZSTD_OK) { close(in_file); close(out_file); return QZSTD_ERROR; } } close(in_file); close(out_file); return QZSTD_OK; }