summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/zstd/contrib/linux-kernel/test
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/zstd/contrib/linux-kernel/test')
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/Makefile49
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/asm/unaligned.h187
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/compiler.h23
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/errno.h15
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/kernel.h19
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/limits.h15
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/math64.h15
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/module.h20
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/printk.h15
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/stddef.h15
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/swab.h16
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/types.h16
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/include/linux/xxhash.h745
-rwxr-xr-x3rdparty/zstd/contrib/linux-kernel/test/macro-test.sh44
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/static_test.c52
-rw-r--r--3rdparty/zstd/contrib/linux-kernel/test/test.c229
16 files changed, 1475 insertions, 0 deletions
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/Makefile b/3rdparty/zstd/contrib/linux-kernel/test/Makefile
new file mode 100644
index 00000000000..67b55e66504
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/Makefile
@@ -0,0 +1,49 @@
+# ################################################################
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+# All rights reserved.
+#
+# This source code is licensed under both the BSD-style license (found in the
+# LICENSE file in the root directory of this source tree) and the GPLv2 (found
+# in the COPYING file in the root directory of this source tree).
+# You may select, at your option, one of the above-listed licenses.
+# ################################################################
+
+LINUX := ../linux
+LINUX_ZSTDLIB := $(LINUX)/lib/zstd
+
+CPPFLAGS += -I$(LINUX)/include -I$(LINUX_ZSTDLIB) -Iinclude -DNDEBUG -Wno-deprecated-declarations
+# Don't poison the workspace, it currently doesn't work with static allocation and workspace reuse
+CPPFLAGS += -DZSTD_ASAN_DONT_POISON_WORKSPACE
+
+LINUX_ZSTD_MODULE := $(wildcard $(LINUX_ZSTDLIB)/*.c)
+LINUX_ZSTD_COMMON := $(wildcard $(LINUX_ZSTDLIB)/common/*.c)
+LINUX_ZSTD_COMPRESS := $(wildcard $(LINUX_ZSTDLIB)/compress/*.c)
+LINUX_ZSTD_DECOMPRESS := $(wildcard $(LINUX_ZSTDLIB)/decompress/*.c $(LINUX_ZSTDLIB)/decompress/*.S)
+LINUX_ZSTD_FILES := $(LINUX_ZSTD_MODULE) $(LINUX_ZSTD_COMMON) $(LINUX_ZSTD_COMPRESS) $(LINUX_ZSTD_DECOMPRESS)
+LINUX_ZSTD_OBJECTS0 := $(LINUX_ZSTD_FILES:.c=.o)
+LINUX_ZSTD_OBJECTS := $(LINUX_ZSTD_OBJECTS0:.S=.o)
+
+%.o: %.S
+ $(COMPILE.S) $(OUTPUT_OPTION) $<
+
+liblinuxzstd.a: $(LINUX_ZSTD_OBJECTS)
+ $(AR) $(ARFLAGS) $@ $^
+
+test: test.c liblinuxzstd.a
+ $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $^ -o $@
+
+static_test: static_test.c
+ $(CC) $(LDFLAGS) $(CPPFLAGS) $(CFLAGS) $^ -o $@
+
+run-test: test static_test
+ ./macro-test.sh
+ ./test
+ ./static_test
+
+.PHONY:
+clean:
+ $(RM) -f $(LINUX_ZSTDLIB)/*.o
+ $(RM) -f $(LINUX_ZSTDLIB)/**/*.o
+ $(RM) -f *.o *.a
+ $(RM) -f static_test
+ $(RM) -f test
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/asm/unaligned.h b/3rdparty/zstd/contrib/linux-kernel/test/include/asm/unaligned.h
new file mode 100644
index 00000000000..86ec4ca3899
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/asm/unaligned.h
@@ -0,0 +1,187 @@
+#ifndef ASM_UNALIGNED_H
+#define ASM_UNALIGNED_H
+
+#include <assert.h>
+#include <linux/types.h>
+
+#ifndef __LITTLE_ENDIAN
+# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN__)
+# define __LITTLE_ENDIAN 1
+# endif
+#endif
+
+#ifdef __LITTLE_ENDIAN
+# define _IS_LITTLE_ENDIAN 1
+#else
+# define _IS_LITTLE_ENDIAN 0
+#endif
+
+static unsigned _isLittleEndian(void)
+{
+ const union { uint32_t u; uint8_t c[4]; } one = { 1 };
+ assert(_IS_LITTLE_ENDIAN == one.c[0]);
+ (void)one;
+ return _IS_LITTLE_ENDIAN;
+}
+
+static uint16_t _swap16(uint16_t in)
+{
+ return ((in & 0xF) << 8) + ((in & 0xF0) >> 8);
+}
+
+static uint32_t _swap32(uint32_t in)
+{
+ return __builtin_bswap32(in);
+}
+
+static uint64_t _swap64(uint64_t in)
+{
+ return __builtin_bswap64(in);
+}
+
+/* Little endian */
+static uint16_t get_unaligned_le16(const void* memPtr)
+{
+ uint16_t val;
+ __builtin_memcpy(&val, memPtr, sizeof(val));
+ if (!_isLittleEndian()) _swap16(val);
+ return val;
+}
+
+static uint32_t get_unaligned_le32(const void* memPtr)
+{
+ uint32_t val;
+ __builtin_memcpy(&val, memPtr, sizeof(val));
+ if (!_isLittleEndian()) _swap32(val);
+ return val;
+}
+
+static uint64_t get_unaligned_le64(const void* memPtr)
+{
+ uint64_t val;
+ __builtin_memcpy(&val, memPtr, sizeof(val));
+ if (!_isLittleEndian()) _swap64(val);
+ return val;
+}
+
+static void put_unaligned_le16(uint16_t value, void* memPtr)
+{
+ if (!_isLittleEndian()) value = _swap16(value);
+ __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_le32(uint32_t value, void* memPtr)
+{
+ if (!_isLittleEndian()) value = _swap32(value);
+ __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_le64(uint64_t value, void* memPtr)
+{
+ if (!_isLittleEndian()) value = _swap64(value);
+ __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+/* big endian */
+static uint32_t get_unaligned_be32(const void* memPtr)
+{
+ uint32_t val;
+ __builtin_memcpy(&val, memPtr, sizeof(val));
+ if (_isLittleEndian()) _swap32(val);
+ return val;
+}
+
+static uint64_t get_unaligned_be64(const void* memPtr)
+{
+ uint64_t val;
+ __builtin_memcpy(&val, memPtr, sizeof(val));
+ if (_isLittleEndian()) _swap64(val);
+ return val;
+}
+
+static void put_unaligned_be32(uint32_t value, void* memPtr)
+{
+ if (_isLittleEndian()) value = _swap32(value);
+ __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+static void put_unaligned_be64(uint64_t value, void* memPtr)
+{
+ if (_isLittleEndian()) value = _swap64(value);
+ __builtin_memcpy(memPtr, &value, sizeof(value));
+}
+
+/* generic */
+extern void __bad_unaligned_access_size(void);
+
+#define __get_unaligned_le(ptr) ((typeof(*(ptr)))({ \
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
+ __bad_unaligned_access_size())))); \
+ }))
+
+#define __get_unaligned_be(ptr) ((typeof(*(ptr)))({ \
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
+ __bad_unaligned_access_size())))); \
+ }))
+
+#define __put_unaligned_le(val, ptr) \
+ ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(uint8_t *)__gu_p = (uint8_t)(val); \
+ break; \
+ case 2: \
+ put_unaligned_le16((uint16_t)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_le32((uint32_t)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_le64((uint64_t)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; \
+ })
+
+#define __put_unaligned_be(val, ptr) \
+ ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(uint8_t *)__gu_p = (uint8_t)(val); \
+ break; \
+ case 2: \
+ put_unaligned_be16((uint16_t)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_be32((uint32_t)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_be64((uint64_t)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; \
+ })
+
+#if _IS_LITTLE_ENDIAN
+# define get_unaligned __get_unaligned_le
+# define put_unaligned __put_unaligned_le
+#else
+# define get_unaligned __get_unaligned_be
+# define put_unaligned __put_unaligned_be
+#endif
+
+#endif // ASM_UNALIGNED_H
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/compiler.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/compiler.h
new file mode 100644
index 00000000000..988ce4a20ff
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/compiler.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_COMPILER_H
+#define LINUX_COMPILER_H
+
+#ifndef inline
+#define inline __inline __attribute__((unused))
+#endif
+
+#ifndef noinline
+#define noinline __attribute__((noinline))
+#endif
+
+#define fallthrough __attribute__((__fallthrough__))
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/errno.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/errno.h
new file mode 100644
index 00000000000..b4bdcba0ea6
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/errno.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_ERRNO_H
+#define LINUX_ERRNO_H
+
+#define EINVAL 22
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/kernel.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/kernel.h
new file mode 100644
index 00000000000..a4d791cd1d5
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/kernel.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_KERNEL_H
+#define LINUX_KERNEL_H
+
+#define WARN_ON(x)
+
+#define PTR_ALIGN(p, a) (typeof(p))ALIGN((unsigned long long)(p), (a))
+#define ALIGN(x, a) ALIGN_MASK((x), (a) - 1)
+#define ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/limits.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/limits.h
new file mode 100644
index 00000000000..574aa7b343f
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/limits.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_LIMITS_H
+#define LINUX_LIMITS_H
+
+#include <limits.h>
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/math64.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/math64.h
new file mode 100644
index 00000000000..7f6713e73bc
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/math64.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_MATH64_H
+#define LINUX_MATH64_H
+
+#define div_u64(dividend, divisor) ((dividend) / (divisor))
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/module.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/module.h
new file mode 100644
index 00000000000..06ef56f9ebe
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/module.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_MODULE_H
+#define LINUX_MODULE_H
+
+#define EXPORT_SYMBOL(symbol) \
+ void* __##symbol = symbol
+#define EXPORT_SYMBOL_GPL(symbol) \
+ void* __##symbol = symbol
+#define MODULE_LICENSE(license)
+#define MODULE_DESCRIPTION(description)
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/printk.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/printk.h
new file mode 100644
index 00000000000..92a25278e71
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/printk.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_PRINTK_H
+#define LINUX_PRINTK_H
+
+#define pr_debug(...)
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/stddef.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/stddef.h
new file mode 100644
index 00000000000..15c7408fcdf
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/stddef.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_STDDEF_H
+#define LINUX_STDDEF_H
+
+#include <stddef.h>
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/swab.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/swab.h
new file mode 100644
index 00000000000..2b48b434c97
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/swab.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_SWAB_H
+#define LINUX_SWAB_H
+
+#define swab32(x) __builtin_bswap32((x))
+#define swab64(x) __builtin_bswap64((x))
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/types.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/types.h
new file mode 100644
index 00000000000..b413db6f983
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/types.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#ifndef LINUX_TYPES_H
+#define LINUX_TYPES_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#endif
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/include/linux/xxhash.h b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/xxhash.h
new file mode 100644
index 00000000000..d41cbd93318
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/include/linux/xxhash.h
@@ -0,0 +1,745 @@
+/*
+ * xxHash - Extremely Fast Hash algorithm
+ * Copyright (C) 2012-2016, Yann Collet.
+ *
+ * BSD 2-Clause License (https://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.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation. This program is dual-licensed; you may select
+ * either version 2 of the GNU General Public License ("GPL") or BSD license
+ * ("BSD").
+ *
+ * You can contact the author at:
+ * - xxHash homepage: https://cyan4973.github.io/xxHash/
+ * - xxHash source repository: https://github.com/Cyan4973/xxHash
+ */
+
+/*
+ * Notice extracted from xxHash homepage:
+ *
+ * xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+ * It also successfully passes all tests from the SMHasher suite.
+ *
+ * Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2
+ * Duo @3GHz)
+ *
+ * Name Speed Q.Score Author
+ * xxHash 5.4 GB/s 10
+ * CrapWow 3.2 GB/s 2 Andrew
+ * MumurHash 3a 2.7 GB/s 10 Austin Appleby
+ * SpookyHash 2.0 GB/s 10 Bob Jenkins
+ * SBox 1.4 GB/s 9 Bret Mulvey
+ * Lookup3 1.2 GB/s 9 Bob Jenkins
+ * SuperFastHash 1.2 GB/s 1 Paul Hsieh
+ * CityHash64 1.05 GB/s 10 Pike & Alakuijala
+ * FNV 0.55 GB/s 5 Fowler, Noll, Vo
+ * CRC32 0.43 GB/s 9
+ * MD5-32 0.33 GB/s 10 Ronald L. Rivest
+ * SHA1-32 0.28 GB/s 10
+ *
+ * Q.Score is a measure of quality of the hash function.
+ * It depends on successfully passing SMHasher test set.
+ * 10 is a perfect score.
+ *
+ * A 64-bits version, named xxh64 offers much better speed,
+ * but for 64-bits applications only.
+ * Name Speed on 64 bits Speed on 32 bits
+ * xxh64 13.8 GB/s 1.9 GB/s
+ * xxh32 6.8 GB/s 6.0 GB/s
+ */
+
+#ifndef XXHASH_H
+#define XXHASH_H
+
+#include <linux/types.h>
+
+#define XXH_API static inline __attribute__((unused))
+/*-****************************
+ * Simple Hash Functions
+ *****************************/
+
+/**
+ * xxh32() - calculate the 32-bit hash of the input with a given seed.
+ *
+ * @input: The data to hash.
+ * @length: The length of the data to hash.
+ * @seed: The seed can be used to alter the result predictably.
+ *
+ * Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
+ *
+ * Return: The 32-bit hash of the data.
+ */
+XXH_API uint32_t xxh32(const void *input, size_t length, uint32_t seed);
+
+/**
+ * xxh64() - calculate the 64-bit hash of the input with a given seed.
+ *
+ * @input: The data to hash.
+ * @length: The length of the data to hash.
+ * @seed: The seed can be used to alter the result predictably.
+ *
+ * This function runs 2x faster on 64-bit systems, but slower on 32-bit systems.
+ *
+ * Return: The 64-bit hash of the data.
+ */
+XXH_API uint64_t xxh64(const void *input, size_t length, uint64_t seed);
+
+/**
+ * xxhash() - calculate wordsize hash of the input with a given seed
+ * @input: The data to hash.
+ * @length: The length of the data to hash.
+ * @seed: The seed can be used to alter the result predictably.
+ *
+ * If the hash does not need to be comparable between machines with
+ * different word sizes, this function will call whichever of xxh32()
+ * or xxh64() is faster.
+ *
+ * Return: wordsize hash of the data.
+ */
+
+static inline unsigned long xxhash(const void *input, size_t length,
+ uint64_t seed)
+{
+ if (sizeof(size_t) == 8)
+ return xxh64(input, length, seed);
+ else
+ return xxh32(input, length, seed);
+}
+
+/*-****************************
+ * Streaming Hash Functions
+ *****************************/
+
+/*
+ * These definitions are only meant to allow allocation of XXH state
+ * statically, on stack, or in a struct for example.
+ * Do not use members directly.
+ */
+
+/**
+ * struct xxh32_state - private xxh32 state, do not use members directly
+ */
+struct xxh32_state {
+ 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;
+};
+
+/**
+ * struct xxh32_state - private xxh64 state, do not use members directly
+ */
+struct xxh64_state {
+ uint64_t total_len;
+ uint64_t v1;
+ uint64_t v2;
+ uint64_t v3;
+ uint64_t v4;
+ uint64_t mem64[4];
+ uint32_t memsize;
+};
+
+/**
+ * xxh32_reset() - reset the xxh32 state to start a new hashing operation
+ *
+ * @state: The xxh32 state to reset.
+ * @seed: Initialize the hash state with this seed.
+ *
+ * Call this function on any xxh32_state to prepare for a new hashing operation.
+ */
+XXH_API void xxh32_reset(struct xxh32_state *state, uint32_t seed);
+
+/**
+ * xxh32_update() - hash the data given and update the xxh32 state
+ *
+ * @state: The xxh32 state to update.
+ * @input: The data to hash.
+ * @length: The length of the data to hash.
+ *
+ * After calling xxh32_reset() call xxh32_update() as many times as necessary.
+ *
+ * Return: Zero on success, otherwise an error code.
+ */
+XXH_API int xxh32_update(struct xxh32_state *state, const void *input, size_t length);
+
+/**
+ * xxh32_digest() - produce the current xxh32 hash
+ *
+ * @state: Produce the current xxh32 hash of this state.
+ *
+ * A hash value can be produced at any time. It is still possible to continue
+ * inserting input into the hash state after a call to xxh32_digest(), and
+ * generate new hashes later on, by calling xxh32_digest() again.
+ *
+ * Return: The xxh32 hash stored in the state.
+ */
+XXH_API uint32_t xxh32_digest(const struct xxh32_state *state);
+
+/**
+ * xxh64_reset() - reset the xxh64 state to start a new hashing operation
+ *
+ * @state: The xxh64 state to reset.
+ * @seed: Initialize the hash state with this seed.
+ */
+XXH_API void xxh64_reset(struct xxh64_state *state, uint64_t seed);
+
+/**
+ * xxh64_update() - hash the data given and update the xxh64 state
+ * @state: The xxh64 state to update.
+ * @input: The data to hash.
+ * @length: The length of the data to hash.
+ *
+ * After calling xxh64_reset() call xxh64_update() as many times as necessary.
+ *
+ * Return: Zero on success, otherwise an error code.
+ */
+XXH_API int xxh64_update(struct xxh64_state *state, const void *input, size_t length);
+
+/**
+ * xxh64_digest() - produce the current xxh64 hash
+ *
+ * @state: Produce the current xxh64 hash of this state.
+ *
+ * A hash value can be produced at any time. It is still possible to continue
+ * inserting input into the hash state after a call to xxh64_digest(), and
+ * generate new hashes later on, by calling xxh64_digest() again.
+ *
+ * Return: The xxh64 hash stored in the state.
+ */
+XXH_API uint64_t xxh64_digest(const struct xxh64_state *state);
+
+/*-**************************
+ * Utils
+ ***************************/
+
+/**
+ * xxh32_copy_state() - copy the source state into the destination state
+ *
+ * @src: The source xxh32 state.
+ * @dst: The destination xxh32 state.
+ */
+XXH_API void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src);
+
+/**
+ * xxh64_copy_state() - copy the source state into the destination state
+ *
+ * @src: The source xxh64 state.
+ * @dst: The destination xxh64 state.
+ */
+XXH_API void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src);
+
+/*
+ * xxHash - Extremely Fast Hash algorithm
+ * Copyright (C) 2012-2016, Yann Collet.
+ *
+ * BSD 2-Clause License (https://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.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation. This program is dual-licensed; you may select
+ * either version 2 of the GNU General Public License ("GPL") or BSD license
+ * ("BSD").
+ *
+ * You can contact the author at:
+ * - xxHash homepage: https://cyan4973.github.io/xxHash/
+ * - xxHash source repository: https://github.com/Cyan4973/xxHash
+ */
+
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/xxhash.h>
+
+/*-*************************************
+ * Macros
+ **************************************/
+#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r)))
+#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r)))
+
+#ifdef __LITTLE_ENDIAN
+# define XXH_CPU_LITTLE_ENDIAN 1
+#else
+# define XXH_CPU_LITTLE_ENDIAN 0
+#endif
+
+/*-*************************************
+ * Constants
+ **************************************/
+static const uint32_t PRIME32_1 = 2654435761U;
+static const uint32_t PRIME32_2 = 2246822519U;
+static const uint32_t PRIME32_3 = 3266489917U;
+static const uint32_t PRIME32_4 = 668265263U;
+static const uint32_t PRIME32_5 = 374761393U;
+
+static const uint64_t PRIME64_1 = 11400714785074694791ULL;
+static const uint64_t PRIME64_2 = 14029467366897019727ULL;
+static const uint64_t PRIME64_3 = 1609587929392839161ULL;
+static const uint64_t PRIME64_4 = 9650029242287828579ULL;
+static const uint64_t PRIME64_5 = 2870177450012600261ULL;
+
+/*-**************************
+ * Utils
+ ***************************/
+XXH_API void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
+{
+ __builtin_memcpy(dst, src, sizeof(*dst));
+}
+
+XXH_API void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
+{
+ __builtin_memcpy(dst, src, sizeof(*dst));
+}
+
+/*-***************************
+ * Simple Hash Functions
+ ****************************/
+static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
+{
+ seed += input * PRIME32_2;
+ seed = xxh_rotl32(seed, 13);
+ seed *= PRIME32_1;
+ return seed;
+}
+
+XXH_API uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
+{
+ const uint8_t *p = (const uint8_t *)input;
+ const uint8_t *b_end = p + len;
+ uint32_t h32;
+
+ if (len >= 16) {
+ const uint8_t *const limit = b_end - 16;
+ uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
+ uint32_t v2 = seed + PRIME32_2;
+ uint32_t v3 = seed + 0;
+ uint32_t v4 = seed - PRIME32_1;
+
+ do {
+ v1 = xxh32_round(v1, get_unaligned_le32(p));
+ p += 4;
+ v2 = xxh32_round(v2, get_unaligned_le32(p));
+ p += 4;
+ v3 = xxh32_round(v3, get_unaligned_le32(p));
+ p += 4;
+ v4 = xxh32_round(v4, get_unaligned_le32(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 += (uint32_t)len;
+
+ while (p + 4 <= b_end) {
+ h32 += get_unaligned_le32(p) * PRIME32_3;
+ h32 = xxh_rotl32(h32, 17) * PRIME32_4;
+ p += 4;
+ }
+
+ while (p < b_end) {
+ h32 += (*p) * PRIME32_5;
+ h32 = xxh_rotl32(h32, 11) * PRIME32_1;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
+{
+ acc += input * PRIME64_2;
+ acc = xxh_rotl64(acc, 31);
+ acc *= PRIME64_1;
+ return acc;
+}
+
+static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
+{
+ val = xxh64_round(0, val);
+ acc ^= val;
+ acc = acc * PRIME64_1 + PRIME64_4;
+ return acc;
+}
+
+XXH_API uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
+{
+ const uint8_t *p = (const uint8_t *)input;
+ const uint8_t *const b_end = p + len;
+ uint64_t h64;
+
+ if (len >= 32) {
+ const uint8_t *const limit = b_end - 32;
+ uint64_t v1 = seed + PRIME64_1 + PRIME64_2;
+ uint64_t v2 = seed + PRIME64_2;
+ uint64_t v3 = seed + 0;
+ uint64_t v4 = seed - PRIME64_1;
+
+ do {
+ v1 = xxh64_round(v1, get_unaligned_le64(p));
+ p += 8;
+ v2 = xxh64_round(v2, get_unaligned_le64(p));
+ p += 8;
+ v3 = xxh64_round(v3, get_unaligned_le64(p));
+ p += 8;
+ v4 = xxh64_round(v4, get_unaligned_le64(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_merge_round(h64, v1);
+ h64 = xxh64_merge_round(h64, v2);
+ h64 = xxh64_merge_round(h64, v3);
+ h64 = xxh64_merge_round(h64, v4);
+
+ } else {
+ h64 = seed + PRIME64_5;
+ }
+
+ h64 += (uint64_t)len;
+
+ while (p + 8 <= b_end) {
+ const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
+
+ h64 ^= k1;
+ h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
+ p += 8;
+ }
+
+ if (p + 4 <= b_end) {
+ h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
+ h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+ p += 4;
+ }
+
+ while (p < b_end) {
+ h64 ^= (*p) * PRIME64_5;
+ h64 = xxh_rotl64(h64, 11) * PRIME64_1;
+ p++;
+ }
+
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+
+ return h64;
+}
+
+/*-**************************************************
+ * Advanced Hash Functions
+ ***************************************************/
+XXH_API void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
+{
+ /* use a local state for memcpy() to avoid strict-aliasing warnings */
+ struct xxh32_state state;
+
+ __builtin_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;
+ __builtin_memcpy(statePtr, &state, sizeof(state));
+}
+
+XXH_API void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
+{
+ /* use a local state for memcpy() to avoid strict-aliasing warnings */
+ struct xxh64_state state;
+
+ __builtin_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;
+ __builtin_memcpy(statePtr, &state, sizeof(state));
+}
+
+XXH_API int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
+{
+ const uint8_t *p = (const uint8_t *)input;
+ const uint8_t *const b_end = p + len;
+
+ if (input == NULL)
+ return -EINVAL;
+
+ state->total_len_32 += (uint32_t)len;
+ state->large_len |= (len >= 16) | (state->total_len_32 >= 16);
+
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
+ __builtin_memcpy((uint8_t *)(state->mem32) + state->memsize, input, len);
+ state->memsize += (uint32_t)len;
+ return 0;
+ }
+
+ if (state->memsize) { /* some data left from previous update */
+ const uint32_t *p32 = state->mem32;
+
+ __builtin_memcpy((uint8_t *)(state->mem32) + state->memsize, input,
+ 16 - state->memsize);
+
+ state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32));
+ p32++;
+ state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32));
+ p32++;
+ state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32));
+ p32++;
+ state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32));
+ p32++;
+
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= b_end - 16) {
+ const uint8_t *const limit = b_end - 16;
+ uint32_t v1 = state->v1;
+ uint32_t v2 = state->v2;
+ uint32_t v3 = state->v3;
+ uint32_t v4 = state->v4;
+
+ do {
+ v1 = xxh32_round(v1, get_unaligned_le32(p));
+ p += 4;
+ v2 = xxh32_round(v2, get_unaligned_le32(p));
+ p += 4;
+ v3 = xxh32_round(v3, get_unaligned_le32(p));
+ p += 4;
+ v4 = xxh32_round(v4, get_unaligned_le32(p));
+ p += 4;
+ } while (p <= limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < b_end) {
+ __builtin_memcpy(state->mem32, p, (size_t)(b_end-p));
+ state->memsize = (uint32_t)(b_end-p);
+ }
+
+ return 0;
+}
+
+XXH_API uint32_t xxh32_digest(const struct xxh32_state *state)
+{
+ const uint8_t *p = (const uint8_t *)state->mem32;
+ const uint8_t *const b_end = (const uint8_t *)(state->mem32) +
+ state->memsize;
+ uint32_t 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;
+
+ while (p + 4 <= b_end) {
+ h32 += get_unaligned_le32(p) * PRIME32_3;
+ h32 = xxh_rotl32(h32, 17) * PRIME32_4;
+ p += 4;
+ }
+
+ while (p < b_end) {
+ h32 += (*p) * PRIME32_5;
+ h32 = xxh_rotl32(h32, 11) * PRIME32_1;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+XXH_API int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
+{
+ const uint8_t *p = (const uint8_t *)input;
+ const uint8_t *const b_end = p + len;
+
+ if (input == NULL)
+ return -EINVAL;
+
+ state->total_len += len;
+
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
+ __builtin_memcpy(((uint8_t *)state->mem64) + state->memsize, input, len);
+ state->memsize += (uint32_t)len;
+ return 0;
+ }
+
+ if (state->memsize) { /* tmp buffer is full */
+ uint64_t *p64 = state->mem64;
+
+ __builtin_memcpy(((uint8_t *)p64) + state->memsize, input,
+ 32 - state->memsize);
+
+ state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64));
+ p64++;
+ state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64));
+ p64++;
+ state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64));
+ p64++;
+ state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64));
+
+ p += 32 - state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p + 32 <= b_end) {
+ const uint8_t *const limit = b_end - 32;
+ uint64_t v1 = state->v1;
+ uint64_t v2 = state->v2;
+ uint64_t v3 = state->v3;
+ uint64_t v4 = state->v4;
+
+ do {
+ v1 = xxh64_round(v1, get_unaligned_le64(p));
+ p += 8;
+ v2 = xxh64_round(v2, get_unaligned_le64(p));
+ p += 8;
+ v3 = xxh64_round(v3, get_unaligned_le64(p));
+ p += 8;
+ v4 = xxh64_round(v4, get_unaligned_le64(p));
+ p += 8;
+ } while (p <= limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < b_end) {
+ __builtin_memcpy(state->mem64, p, (size_t)(b_end-p));
+ state->memsize = (uint32_t)(b_end - p);
+ }
+
+ return 0;
+}
+
+XXH_API uint64_t xxh64_digest(const struct xxh64_state *state)
+{
+ const uint8_t *p = (const uint8_t *)state->mem64;
+ const uint8_t *const b_end = (const uint8_t *)state->mem64 +
+ state->memsize;
+ uint64_t h64;
+
+ if (state->total_len >= 32) {
+ const uint64_t v1 = state->v1;
+ const uint64_t v2 = state->v2;
+ const uint64_t v3 = state->v3;
+ const uint64_t v4 = state->v4;
+
+ h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
+ xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
+ h64 = xxh64_merge_round(h64, v1);
+ h64 = xxh64_merge_round(h64, v2);
+ h64 = xxh64_merge_round(h64, v3);
+ h64 = xxh64_merge_round(h64, v4);
+ } else {
+ h64 = state->v3 + PRIME64_5;
+ }
+
+ h64 += (uint64_t)state->total_len;
+
+ while (p + 8 <= b_end) {
+ const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
+
+ h64 ^= k1;
+ h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
+ p += 8;
+ }
+
+ if (p + 4 <= b_end) {
+ h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
+ h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+ p += 4;
+ }
+
+ while (p < b_end) {
+ h64 ^= (*p) * PRIME64_5;
+ h64 = xxh_rotl64(h64, 11) * PRIME64_1;
+ p++;
+ }
+
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+
+ return h64;
+}
+
+#endif /* XXHASH_H */
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/macro-test.sh b/3rdparty/zstd/contrib/linux-kernel/test/macro-test.sh
new file mode 100755
index 00000000000..9ea84aa66b1
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/macro-test.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env sh
+
+set -e
+
+SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+INCLUDE_DIR="$SCRIPT_DIR/../linux/include"
+LIB_DIR="$SCRIPT_DIR/../linux/lib"
+
+
+print() {
+ printf '%b' "${*}"
+}
+
+println() {
+ printf '%b\n' "${*}"
+}
+
+die() {
+ println "$@" 1>&2
+ exit 1
+}
+
+test_not_present() {
+ print "Testing that '$1' is not present... "
+ grep -r $1 "$INCLUDE_DIR" "$LIB_DIR" && die "Fail!"
+ println "Okay"
+}
+
+println "This test checks that the macro removal process worked as expected"
+println "If this test fails, then freestanding.py wasn't able to remove one of these"
+println "macros from the source code completely. You'll either need to rewrite the check"
+println "or improve freestanding.py."
+println ""
+
+test_not_present "ZSTD_NO_INTRINSICS"
+test_not_present "ZSTD_NO_UNUSED_FUNCTIONS"
+test_not_present "ZSTD_LEGACY_SUPPORT"
+test_not_present "STATIC_BMI2"
+test_not_present "ZSTD_DLL_EXPORT"
+test_not_present "ZSTD_DLL_IMPORT"
+test_not_present "__ICCARM__"
+test_not_present "_MSC_VER"
+test_not_present "_WIN32"
+test_not_present "__linux__"
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/static_test.c b/3rdparty/zstd/contrib/linux-kernel/test/static_test.c
new file mode 100644
index 00000000000..ba4a420d417
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/static_test.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "decompress_sources.h"
+#include <linux/zstd.h>
+
+#define CONTROL(x) \
+ do { \
+ if (!(x)) { \
+ fprintf(stderr, "%s:%u: %s failed!\n", __FUNCTION__, __LINE__, #x); \
+ abort(); \
+ } \
+ } while (0)
+
+
+static const char kEmptyZstdFrame[] = {
+ 0x28, 0xb5, 0x2f, 0xfd, 0x24, 0x00, 0x01, 0x00, 0x00, 0x99, 0xe9, 0xd8, 0x51
+};
+
+static void test_decompress_unzstd(void) {
+ fprintf(stderr, "Testing decompress unzstd... ");
+ {
+ size_t const wkspSize = zstd_dctx_workspace_bound();
+ void* wksp = malloc(wkspSize);
+ ZSTD_DCtx* dctx = zstd_init_dctx(wksp, wkspSize);
+ CONTROL(wksp != NULL);
+ CONTROL(dctx != NULL);
+ {
+ size_t const dSize = zstd_decompress_dctx(dctx, NULL, 0, kEmptyZstdFrame, sizeof(kEmptyZstdFrame));
+ CONTROL(!zstd_is_error(dSize));
+ CONTROL(dSize == 0);
+ }
+ free(wksp);
+ }
+ fprintf(stderr, "Ok\n");
+}
+
+int main(void) {
+ test_decompress_unzstd();
+ return 0;
+}
diff --git a/3rdparty/zstd/contrib/linux-kernel/test/test.c b/3rdparty/zstd/contrib/linux-kernel/test/test.c
new file mode 100644
index 00000000000..0f4ba3f45ef
--- /dev/null
+++ b/3rdparty/zstd/contrib/linux-kernel/test/test.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ * You may select, at your option, one of the above-listed licenses.
+ */
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <linux/zstd.h>
+
+#define CONTROL(x) \
+ do { \
+ if (!(x)) { \
+ fprintf(stderr, "%s:%u: %s failed!\n", __FUNCTION__, __LINE__, #x); \
+ abort(); \
+ } \
+ } while (0)
+
+typedef struct {
+ char *data;
+ char *data2;
+ size_t dataSize;
+ char *comp;
+ size_t compSize;
+} test_data_t;
+
+static test_data_t create_test_data(void) {
+ test_data_t data;
+ data.dataSize = 128 * 1024;
+ data.data = (char*)malloc(data.dataSize);
+ CONTROL(data.data != NULL);
+ data.data2 = (char*)malloc(data.dataSize);
+ CONTROL(data.data2 != NULL);
+ data.compSize = zstd_compress_bound(data.dataSize);
+ data.comp = (char*)malloc(data.compSize);
+ CONTROL(data.comp != NULL);
+ memset(data.data, 0, data.dataSize);
+ return data;
+}
+
+static void free_test_data(test_data_t const *data) {
+ free(data->data);
+ free(data->data2);
+ free(data->comp);
+}
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+static void test_btrfs(test_data_t const *data) {
+ size_t const size = MIN(data->dataSize, 128 * 1024);
+ fprintf(stderr, "testing btrfs use cases... ");
+ for (int level = -1; level < 16; ++level) {
+ zstd_parameters params = zstd_get_params(level, size);
+ size_t const workspaceSize =
+ MAX(zstd_cstream_workspace_bound(&params.cParams),
+ zstd_dstream_workspace_bound(size));
+ void *workspace = malloc(workspaceSize);
+
+ char const *ip = data->data;
+ char const *iend = ip + size;
+ char *op = data->comp;
+ char *oend = op + data->compSize;
+
+ CONTROL(params.cParams.windowLog <= 17);
+ CONTROL(workspace != NULL);
+ {
+ zstd_cstream *cctx = zstd_init_cstream(&params, size, workspace, workspaceSize);
+ zstd_out_buffer out = {NULL, 0, 0};
+ zstd_in_buffer in = {NULL, 0, 0};
+ CONTROL(cctx != NULL);
+ for (;;) {
+ if (in.pos == in.size) {
+ in.src = ip;
+ in.size = MIN(4096, iend - ip);
+ in.pos = 0;
+ ip += in.size;
+ }
+
+ if (out.pos == out.size) {
+ out.dst = op;
+ out.size = MIN(4096, oend - op);
+ out.pos = 0;
+ op += out.size;
+ }
+
+ if (ip != iend || in.pos < in.size) {
+ CONTROL(!zstd_is_error(zstd_compress_stream(cctx, &out, &in)));
+ } else {
+ size_t const ret = zstd_end_stream(cctx, &out);
+ CONTROL(!zstd_is_error(ret));
+ if (ret == 0) {
+ break;
+ }
+ }
+ }
+ op += out.pos;
+ }
+
+ ip = data->comp;
+ iend = op;
+ op = data->data2;
+ oend = op + size;
+ {
+ zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize);
+ zstd_out_buffer out = {NULL, 0, 0};
+ zstd_in_buffer in = {NULL, 0, 0};
+ CONTROL(dctx != NULL);
+ for (;;) {
+ if (in.pos == in.size) {
+ in.src = ip;
+ in.size = MIN(4096, iend - ip);
+ in.pos = 0;
+ ip += in.size;
+ }
+
+ if (out.pos == out.size) {
+ out.dst = op;
+ out.size = MIN(4096, oend - op);
+ out.pos = 0;
+ op += out.size;
+ }
+ {
+ size_t const ret = zstd_decompress_stream(dctx, &out, &in);
+ CONTROL(!zstd_is_error(ret));
+ if (ret == 0) {
+ break;
+ }
+ }
+ }
+ }
+ CONTROL((size_t)(op - data->data2) == data->dataSize);
+ CONTROL(!memcmp(data->data, data->data2, data->dataSize));
+ free(workspace);
+ }
+ fprintf(stderr, "Ok\n");
+}
+
+static void test_decompress_unzstd(test_data_t const *data) {
+ size_t cSize;
+ fprintf(stderr, "Testing decompress unzstd... ");
+ {
+ zstd_parameters params = zstd_get_params(19, 0);
+ size_t const wkspSize = zstd_cctx_workspace_bound(&params.cParams);
+ void* wksp = malloc(wkspSize);
+ zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize);
+ CONTROL(wksp != NULL);
+ CONTROL(cctx != NULL);
+ cSize = zstd_compress_cctx(cctx, data->comp, data->compSize, data->data, data->dataSize, &params);
+ CONTROL(!zstd_is_error(cSize));
+ free(wksp);
+ }
+ {
+ size_t const wkspSize = zstd_dctx_workspace_bound();
+ void* wksp = malloc(wkspSize);
+ zstd_dctx* dctx = zstd_init_dctx(wksp, wkspSize);
+ CONTROL(wksp != NULL);
+ CONTROL(dctx != NULL);
+ {
+ size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize);
+ CONTROL(!zstd_is_error(dSize));
+ CONTROL(dSize == data->dataSize);
+ }
+ CONTROL(!memcmp(data->data, data->data2, data->dataSize));
+ free(wksp);
+ }
+ fprintf(stderr, "Ok\n");
+}
+
+static void test_f2fs(void) {
+ fprintf(stderr, "testing f2fs uses... ");
+ CONTROL(zstd_min_clevel() < 0);
+ CONTROL(zstd_max_clevel() == 22);
+ fprintf(stderr, "Ok\n");
+}
+
+static char *g_stack = NULL;
+
+static void __attribute__((noinline)) use(void *x) {
+ asm volatile("" : "+r"(x));
+}
+
+static void __attribute__((noinline)) fill_stack(void) {
+ memset(g_stack, 0x33, 8192);
+}
+
+static void __attribute__((noinline)) set_stack(void) {
+
+ char stack[8192];
+ g_stack = stack;
+ use(g_stack);
+}
+
+static void __attribute__((noinline)) check_stack(void) {
+ size_t cleanStack = 0;
+ while (cleanStack < 8192 && g_stack[cleanStack] == 0x33) {
+ ++cleanStack;
+ }
+ {
+ size_t const stackSize = 8192 - cleanStack;
+ fprintf(stderr, "Maximum stack size: %zu\n", stackSize);
+ CONTROL(stackSize <= 2048 + 512);
+ }
+}
+
+static void test_stack_usage(test_data_t const *data) {
+ set_stack();
+ fill_stack();
+ test_f2fs();
+ test_btrfs(data);
+ test_decompress_unzstd(data);
+ check_stack();
+}
+
+int main(void) {
+ test_data_t data = create_test_data();
+ test_f2fs();
+ test_btrfs(&data);
+ test_decompress_unzstd(&data);
+ test_stack_usage(&data);
+ free_test_data(&data);
+ return 0;
+}