1 /*------------------------------------------------------------------------------
2 *
3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved.
4 * The YADIFA TM software product is provided under the BSD 3-clause license:
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of EURid nor the names of its contributors may be
16 * used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 *------------------------------------------------------------------------------
32 *
33 */
34
35 /** @defgroup test
36 * @ingroup test
37 * @brief skeleton file
38 *
39 * skeleton test program, will not be installed with a "make install"
40 *
41 * To create a new test based on the skeleton:
42 *
43 * _ copy the folder
44 * _ replace "skeleton" by the name of the test
45 * _ add the test to the top level Makefile.am and configure.ac
46 *
47 */
48
49 #include <dnscore/dnscore.h>
50 #include <dnscore/format.h>
51 #include <dnscore/shared-heap.h>
52 #include <dnscore/shared-heap-bytearray-output-stream.h>
53 #include <dnscore/random.h>
54 #include <dnscore/process.h>
55
56 #define MEMORY_HEAP_SIZE 0x40000000
57 #define LOOP_COUNT 4096
58
59 #define CHILDREN 4
60
61 #define FORK_LOOPS 64
62
63 #define L1_SIZE 64
64 #define L1_MASK (L1_SIZE - 1)
65
66 #define MEMORY_HEAP_L1_SLOTS (MEMORY_HEAP_SIZE / L1_SIZE)
67 #define FORK_LOOP_POINTER_ARRAY_SIZE (MEMORY_HEAP_L1_SLOTS * sizeof(void*))
68 #define FORK_LOOP_COUNT ((((MEMORY_HEAP_SIZE - FORK_LOOP_POINTER_ARRAY_SIZE)) / L1_SIZE) / 2)
69
70 static u8 *pointers[LOOP_COUNT];
71
72 static void** shared_blocs;
73
74 static char one_kb_string[1048] =
75 "BEGIN0123456789ABCDEFGHIJKLMNOPQ"
76 "RSTUVWXYZabcdefghijklmnopqrstuvw"
77 "xyz-j7YZ5sjpN2GPC6B870yZ3HJBIbpk"
78 "7v6hmzxHu6eAomRhAb9ikkfxSP1qy7S6"
79 "Q6cnNREREssBkSv8hlsEoD0GR0Ip1Tu1"
80 "yDQj2LhCpzTJacaJ1qxJ2TjoQxoVi6xe"
81 "m7DHzeUvyJca06wmuZOs0oKGQmJFRu9a"
82 "uz9f8fT8onBFjgBpBcPmzor7rEpqWrcK"
83 "NEtpoueRln6q1qSK6RUkULbYwLShTWgD"
84 "bMstlAEVp5EqUIPhlQXSf4eOpImJM4Yt"
85 "Lu4LFThG5GU8n9zNTk4WlxcGQCj8Emx1"
86 "pqtjHWx55lLiqoJCLgDYPDN99vjB8ukz"
87 "XfaXHQIjq44rnxvwpf7cEpMMxHCp7IOO"
88 "18nJ42O4CmxTfoKtIkJkuA0NczkitEeF"
89 "64Gtj3TubiBLtfRra8zBN8ByqfeeQZG1"
90 "XgHaO6s6covHabtb0gzLVV1GenCPvYfp"
91 "pivvH8lSWvkeH0xJ5zTjG19Voql883Ii"
92 "y28NCXTosBFe81DhvqHQgQ7FU7Njv96o"
93 "kiC9Cr8f6CEXp23qe8fL3A4iaEcMPg4f"
94 "iRZzUAQtblzzf3nryBpe7gHZiIjE1kUG"
95 "eMXJehH0LDFrWR4AmUhZNxR8aK1RSFKZ"
96 "Uy32zPIx6TMrTFncSTBgqluwObbFAk6R"
97 "1G6ToGPL1X75JNpwXhURN752RNQQUCGo"
98 "Vv1SMKBTzpMXH9hfy33wllyiru6ZAciJ"
99 "iAa0KmlE9vfqYIv6hA0PyMqIwP7twDRs"
100 "kuVI4tbBBY5ScHsa42SnsFpYEXBJuKk1"
101 "LFQ4sQED1Stvt5rtf7FDUx316eZ64qVB"
102 "1k1sO9YgNzrrv3gpip3vcHr6SWLybVMa"
103 "yw047f0YZhjfNXg2YOXPJaNmXvKaUiOe"
104 "SyeINNqCIQuDzCUYeLscEEWaoyx5NAyt"
105 "mj9hcK4v3S4zLpB3fs1xa5icmV9uz2SW"
106 "Uk75WhbSnQ3iW8kMcP1TYz9yDIufAz6m"
107 "THE-END";
108
109 int
main(int argc,char * argv[])110 main(int argc, char *argv[])
111 {
112 (void)argc;
113 (void)argv;
114 /* initializes the core library */
115
116 ya_result ret;
117
118 dnscore_init();
119
120 if(FAIL(ret = shared_heap_init()))
121 {
122 formatln("shared_heap_init() failed: %r", ret);
123 return 1;
124 }
125
126 if(FAIL(ret = shared_heap_create(MEMORY_HEAP_SIZE))) // 64MB
127 {
128 formatln("shared_heap_create() failed: %r", ret);
129 return 2;
130 }
131
132 u8 id = (u8)ret;
133
134 int count = LOOP_COUNT;
135
136 shared_heap_check(id);
137
138 for(int j = 11; j < 1023; ++j)
139 {
140 output_stream baos;
141 //output_stream baos2;
142 shared_heap_output_stream_context shos_context;
143 shared_heap_output_stream_init_ex_static(&baos, id, NULL, 48, SHARED_HEAP_DYNAMIC, &shos_context);
144 //shared_heap_output_stream_context shos_context2;
145 //shared_heap_output_stream_init_ex_static(&baos2, id, NULL, 48, SHARED_HEAP_DYNAMIC, &shos_context2);
146
147 for(int i = 0; i < j; ++i)
148 {
149 output_stream_write(&baos, one_kb_string, i & 1023);
150 //output_stream_write(&baos2, one_kb_string, 1023 - (i & 1023));
151
152 shared_heap_check(id);
153 }
154
155 output_stream_close(&baos);
156 //output_stream_close(&baos2);
157
158 shared_heap_check(id);
159
160 size_t total;
161 size_t count;
162
163 shared_heap_count_allocated(id, &total, &count);
164
165 assert((total == 0) && (count == 0));
166 }
167
168 for(int i = 0; i < count; ++i)
169 {
170 pointers[i] = (u8*)shared_heap_alloc(id, i);
171 if(pointers[i] == NULL)
172 {
173 formatln("failed to allocate %i bytes", i);
174 return 3;
175 }
176 shared_heap_check_ptr(id, pointers[i]);
177 shared_heap_check(id);
178 memset(pointers[i], i, i);
179 formatln("alloc: @%p: %i bytes", pointers[i], i);
180 }
181
182 shared_heap_check(id);
183
184 for(int i = 0; i < count; ++i)
185 {
186 formatln("---->: @%p: %i bytes", pointers[i], i);
187 shared_heap_check_ptr(id, pointers[i]);
188 shared_heap_free(/*id, */pointers[i]);
189 formatln("freed: @%p: %i bytes", pointers[i], i);
190 }
191
192 shared_heap_check(id);
193
194 pointers[0] = (u8*)shared_heap_alloc(id, 0);
195 shared_heap_free(/*id, */pointers[0]);
196
197 for(int i = 0; i < count; ++i)
198 {
199 pointers[i] = (u8*)shared_heap_alloc(id, i);
200 if(pointers[i] == NULL)
201 {
202 formatln("failed to allocate %i bytes", i);
203 return 3;
204 }
205 shared_heap_check_ptr(id, pointers[i]);
206 memset(pointers[i], i, i);
207 formatln("alloc: @%p: %i bytes", pointers[i], i);
208 }
209
210 shared_heap_check(id);
211
212 for(int i = count - 1; i >= 0; --i)
213 {
214 formatln("---->: @%p: %i bytes", pointers[i], i);
215 shared_heap_check_ptr(id, pointers[i]);
216 shared_heap_free(/*id, */pointers[i]);
217 formatln("freed: @%p: %i bytes", pointers[i], i);
218 }
219
220 shared_heap_check(id);
221
222 random_ctx rndctx = random_init(0);
223
224 int next_ptr = 0;
225 for(int i = 0; i < 1000000; ++i)
226 {
227 if(next_ptr < LOOP_COUNT)
228 {
229 shared_heap_check(id);
230 pointers[next_ptr] = (u8*)shared_heap_alloc(id, i & 1023);
231 shared_heap_check(id);
232
233 if(pointers[next_ptr] == NULL)
234 {
235 --next_ptr;
236 assert(next_ptr >= 0);
237 shared_heap_check(id);
238 shared_heap_free(pointers[next_ptr]);
239 shared_heap_check(id);
240 continue;
241 }
242
243 memset(pointers[next_ptr], i, i & 1023);
244 shared_heap_check(id);
245
246 ++next_ptr;
247 }
248
249 if(i & 1)
250 {
251 u32 r = random_next(rndctx);
252 if(r & 1)
253 {
254 r = random_next(rndctx);
255 r %= next_ptr;
256 shared_heap_check(id);
257 shared_heap_free(pointers[r]);
258 shared_heap_check(id);
259 pointers[r] = pointers[--next_ptr];
260 }
261 }
262 }
263
264 for(int i = 0; i < next_ptr; ++i)
265 {
266 shared_heap_free(pointers[i]);
267 shared_heap_check(id);
268 }
269
270 next_ptr = 0;
271
272 for(int i = 0; i < 1000000; ++i)
273 {
274 if(next_ptr < LOOP_COUNT)
275 {
276 shared_heap_check(id);
277 pointers[next_ptr] = (u8*)shared_heap_alloc(id, 48);
278 shared_heap_check(id);
279
280 if(pointers[next_ptr] == NULL)
281 {
282 --next_ptr;
283 assert(next_ptr >= 0);
284 shared_heap_check(id);
285 shared_heap_free(pointers[next_ptr]);
286 shared_heap_check(id);
287 continue;
288 }
289
290 memset(pointers[next_ptr], i, 48);
291 shared_heap_check(id);
292
293 ++next_ptr;
294 }
295
296 if(i & 1)
297 {
298 u32 r = random_next(rndctx);
299 if(r & 1)
300 {
301 r = random_next(rndctx);
302 r %= next_ptr;
303 shared_heap_check(id);
304 shared_heap_free(pointers[r]);
305 shared_heap_check(id);
306 pointers[r] = pointers[--next_ptr];
307 }
308 }
309 }
310
311 for(int i = 0; i < next_ptr; ++i)
312 {
313 shared_heap_free(pointers[i]);
314 shared_heap_check(id);
315 }
316
317 random_finalize(rndctx);
318
319 pointers[0] = (u8*)shared_heap_alloc(id, 0);
320 shared_heap_free(/*id, */pointers[0]);
321
322 shared_heap_check(id);
323
324 shared_blocs = (void**)shared_heap_alloc(id, LOOP_COUNT * sizeof(void*));
325 assert(shared_blocs != NULL);
326
327 for(int f = 0; f < FORK_LOOPS; ++f)
328 {
329 formatln("fork test %i/%i begin", f, FORK_LOOPS);
330 pid_t child[CHILDREN];
331 for(int i = 0; i < CHILDREN; ++i)
332 {
333 if((child[i] = fork_ex()) == 0)
334 {
335 formatln("[%5i] working", getpid_ex());
336
337 for(int j = 0; j < LOOP_COUNT; j += CHILDREN)
338 {
339 shared_blocs[i + j] = shared_heap_alloc(id, j);
340 //shared_heap_check_ptr(id, shared_blocs[i + j]);
341 memset(shared_blocs[i + j], 0xff, j);
342 formatln("[%5i] alloc: @%p: %i bytes", getpid_ex(), shared_blocs[i + j], j);
343 }
344
345 formatln("[%5i] done", getpid_ex());
346
347 flushout();
348
349 exit(0);
350 }
351 else if(child[i] < 0)
352 {
353 abort();
354 }
355 }
356
357 formatln("fork test %i/%i: waiting for children", f, FORK_LOOPS);
358
359 for(int i = 0; i < CHILDREN; ++i)
360 {
361 waitpid_ex(child[i], NULL, 0);
362 }
363
364 formatln("fork test %i/%i: integrity check before free", f, FORK_LOOPS);
365
366 shared_heap_check(id);
367
368 for(int i = 0; i < LOOP_COUNT; ++i)
369 {
370 formatln("---->: @%p: %i bytes", shared_blocs[i], i / CHILDREN);
371 shared_heap_check_ptr(id, shared_blocs[i]);
372 shared_heap_free(/*id, */shared_blocs[i]);
373 formatln("freed: @%p: %i bytes", shared_blocs[i], i);
374 }
375
376 formatln("fork test %i/%i: integrity check after free", f, FORK_LOOPS);
377
378 flushout();
379 }
380
381 shared_heap_free(/*id, */shared_blocs);
382
383 shared_heap_check(id);
384
385 println("and now for a bigger one");
386
387 pointers[0] = (u8*)shared_heap_alloc(id, 0);
388 shared_heap_free(/*id, */pointers[0]);
389
390 shared_heap_check(id);
391
392 shared_blocs = (void**)shared_heap_alloc(id, FORK_LOOP_POINTER_ARRAY_SIZE);
393 assert(shared_blocs != NULL);
394
395 for(int f = 0; f < FORK_LOOPS; ++f)
396 {
397 formatln("fork test %i/%i begin", f, FORK_LOOPS);
398 pid_t child[CHILDREN];
399 for(int i = 0; i < CHILDREN; ++i)
400 {
401 if((child[i] = fork_ex()) == 0)
402 {
403 formatln("[%5i] working", getpid_ex());
404
405 for(size_t j = 0; j < FORK_LOOP_COUNT; j += CHILDREN)
406 {
407 shared_blocs[i + j] = shared_heap_alloc(id, j & L1_MASK);
408 assert(shared_blocs[i + j] != NULL);
409 //shared_heap_check_ptr(id, shared_blocs[i + j]);
410 //formatln("[%5i] alloc: @%p: %i bytes", getpid_ex(), shared_blocs[i + j], j & L1_MASK);
411 }
412
413 formatln("[%5i] done", getpid_ex());
414
415 flushout();
416
417 exit(0);
418 }
419 else if(child[i] < 0)
420 {
421 abort();
422 }
423 }
424
425 formatln("fork test %i/%i: waiting for children", f, FORK_LOOPS);
426
427 for(int i = 0; i < CHILDREN; ++i)
428 {
429 waitpid_ex(child[i], NULL, 0);
430 }
431
432 formatln("fork test %i/%i: integrity check before free", f, FORK_LOOPS);
433
434 shared_heap_check(id);
435
436 for(size_t i = 0; i < FORK_LOOP_COUNT; ++i)
437 {
438 //formatln("---->: @%p: %i bytes", shared_blocs[i], i);
439 //shared_heap_check_ptr(id, shared_blocs[i]);
440 assert(shared_blocs[i] != NULL);
441 shared_heap_free(/*id, */shared_blocs[i]);
442 //formatln("freed: @%p: %i bytes", shared_blocs[i], i);
443 }
444
445 formatln("fork test %i/%i: integrity check after free", f, FORK_LOOPS);
446
447 flushout();
448 }
449
450 shared_heap_free(/*id, */shared_blocs);
451
452 shared_heap_check(id);
453
454 pointers[0] = (u8*)shared_heap_alloc(id, 0);
455 shared_heap_free(/*id, */pointers[0]);
456
457 flushout();
458 flusherr();
459 fflush(NULL);
460
461 dnscore_finalize();
462
463 return EXIT_SUCCESS;
464 }
465