git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / zstd-1.5.5 / contrib / linux-kernel / test / test.c
CommitLineData
648db22b 1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 * All rights reserved.
4 *
5 * This source code is licensed under both the BSD-style license (found in the
6 * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7 * in the COPYING file in the root directory of this source tree).
8 * You may select, at your option, one of the above-listed licenses.
9 */
10#include <stddef.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <linux/zstd.h>
16
17#define CONTROL(x) \
18 do { \
19 if (!(x)) { \
20 fprintf(stderr, "%s:%u: %s failed!\n", __FUNCTION__, __LINE__, #x); \
21 abort(); \
22 } \
23 } while (0)
24
25typedef struct {
26 char *data;
27 char *data2;
28 size_t dataSize;
29 char *comp;
30 size_t compSize;
31} test_data_t;
32
33static test_data_t create_test_data(void) {
34 test_data_t data;
35 data.dataSize = 128 * 1024;
36 data.data = (char*)malloc(data.dataSize);
37 CONTROL(data.data != NULL);
38 data.data2 = (char*)malloc(data.dataSize);
39 CONTROL(data.data2 != NULL);
40 data.compSize = zstd_compress_bound(data.dataSize);
41 data.comp = (char*)malloc(data.compSize);
42 CONTROL(data.comp != NULL);
43 memset(data.data, 0, data.dataSize);
44 return data;
45}
46
47static void free_test_data(test_data_t const *data) {
48 free(data->data);
49 free(data->data2);
50 free(data->comp);
51}
52
53#define MIN(a, b) ((a) < (b) ? (a) : (b))
54#define MAX(a, b) ((a) > (b) ? (a) : (b))
55
56static void test_btrfs(test_data_t const *data) {
57 size_t const size = MIN(data->dataSize, 128 * 1024);
58 fprintf(stderr, "testing btrfs use cases... ");
59 for (int level = -1; level < 16; ++level) {
60 zstd_parameters params = zstd_get_params(level, size);
61 size_t const workspaceSize =
62 MAX(zstd_cstream_workspace_bound(&params.cParams),
63 zstd_dstream_workspace_bound(size));
64 void *workspace = malloc(workspaceSize);
65
66 char const *ip = data->data;
67 char const *iend = ip + size;
68 char *op = data->comp;
69 char *oend = op + data->compSize;
70
71 CONTROL(params.cParams.windowLog <= 17);
72 CONTROL(workspace != NULL);
73 {
74 zstd_cstream *cctx = zstd_init_cstream(&params, size, workspace, workspaceSize);
75 zstd_out_buffer out = {NULL, 0, 0};
76 zstd_in_buffer in = {NULL, 0, 0};
77 CONTROL(cctx != NULL);
78 for (;;) {
79 if (in.pos == in.size) {
80 in.src = ip;
81 in.size = MIN(4096, iend - ip);
82 in.pos = 0;
83 ip += in.size;
84 }
85
86 if (out.pos == out.size) {
87 out.dst = op;
88 out.size = MIN(4096, oend - op);
89 out.pos = 0;
90 op += out.size;
91 }
92
93 if (ip != iend || in.pos < in.size) {
94 CONTROL(!zstd_is_error(zstd_compress_stream(cctx, &out, &in)));
95 } else {
96 size_t const ret = zstd_end_stream(cctx, &out);
97 CONTROL(!zstd_is_error(ret));
98 if (ret == 0) {
99 break;
100 }
101 }
102 }
103 op += out.pos;
104 }
105
106 ip = data->comp;
107 iend = op;
108 op = data->data2;
109 oend = op + size;
110 {
111 zstd_dstream *dctx = zstd_init_dstream(1ULL << params.cParams.windowLog, workspace, workspaceSize);
112 zstd_out_buffer out = {NULL, 0, 0};
113 zstd_in_buffer in = {NULL, 0, 0};
114 CONTROL(dctx != NULL);
115 for (;;) {
116 if (in.pos == in.size) {
117 in.src = ip;
118 in.size = MIN(4096, iend - ip);
119 in.pos = 0;
120 ip += in.size;
121 }
122
123 if (out.pos == out.size) {
124 out.dst = op;
125 out.size = MIN(4096, oend - op);
126 out.pos = 0;
127 op += out.size;
128 }
129 {
130 size_t const ret = zstd_decompress_stream(dctx, &out, &in);
131 CONTROL(!zstd_is_error(ret));
132 if (ret == 0) {
133 break;
134 }
135 }
136 }
137 }
138 CONTROL((size_t)(op - data->data2) == data->dataSize);
139 CONTROL(!memcmp(data->data, data->data2, data->dataSize));
140 free(workspace);
141 }
142 fprintf(stderr, "Ok\n");
143}
144
145static void test_decompress_unzstd(test_data_t const *data) {
146 size_t cSize;
147 fprintf(stderr, "Testing decompress unzstd... ");
148 {
149 zstd_parameters params = zstd_get_params(19, 0);
150 size_t const wkspSize = zstd_cctx_workspace_bound(&params.cParams);
151 void* wksp = malloc(wkspSize);
152 zstd_cctx* cctx = zstd_init_cctx(wksp, wkspSize);
153 CONTROL(wksp != NULL);
154 CONTROL(cctx != NULL);
155 cSize = zstd_compress_cctx(cctx, data->comp, data->compSize, data->data, data->dataSize, &params);
156 CONTROL(!zstd_is_error(cSize));
157 free(wksp);
158 }
159 {
160 size_t const wkspSize = zstd_dctx_workspace_bound();
161 void* wksp = malloc(wkspSize);
162 zstd_dctx* dctx = zstd_init_dctx(wksp, wkspSize);
163 CONTROL(wksp != NULL);
164 CONTROL(dctx != NULL);
165 {
166 size_t const dSize = zstd_decompress_dctx(dctx, data->data2, data->dataSize, data->comp, cSize);
167 CONTROL(!zstd_is_error(dSize));
168 CONTROL(dSize == data->dataSize);
169 }
170 CONTROL(!memcmp(data->data, data->data2, data->dataSize));
171 free(wksp);
172 }
173 fprintf(stderr, "Ok\n");
174}
175
176static void test_f2fs(void) {
177 fprintf(stderr, "testing f2fs uses... ");
178 CONTROL(zstd_min_clevel() < 0);
179 CONTROL(zstd_max_clevel() == 22);
180 fprintf(stderr, "Ok\n");
181}
182
183static char *g_stack = NULL;
184
185static void __attribute__((noinline)) use(void *x) {
186 asm volatile("" : "+r"(x));
187}
188
189static void __attribute__((noinline)) fill_stack(void) {
190 memset(g_stack, 0x33, 8192);
191}
192
193static void __attribute__((noinline)) set_stack(void) {
194
195 char stack[8192];
196 g_stack = stack;
197 use(g_stack);
198}
199
200static void __attribute__((noinline)) check_stack(void) {
201 size_t cleanStack = 0;
202 while (cleanStack < 8192 && g_stack[cleanStack] == 0x33) {
203 ++cleanStack;
204 }
205 {
206 size_t const stackSize = 8192 - cleanStack;
207 fprintf(stderr, "Maximum stack size: %zu\n", stackSize);
208 CONTROL(stackSize <= 2048 + 512);
209 }
210}
211
212static void test_stack_usage(test_data_t const *data) {
213 set_stack();
214 fill_stack();
215 test_f2fs();
216 test_btrfs(data);
217 test_decompress_unzstd(data);
218 check_stack();
219}
220
221int main(void) {
222 test_data_t data = create_test_data();
223 test_f2fs();
224 test_btrfs(&data);
225 test_decompress_unzstd(&data);
226 test_stack_usage(&data);
227 free_test_data(&data);
228 return 0;
229}