Seregon/zftpd

Zero-copy FTP/HTTP Daemon compatible with all POSIX systems

C/11.0 KB/No license
tests/test_alloc.c
zftpd / tests / test_alloc.c
1#include "pal_alloc.h"
2#include <pthread.h>
3#include <stdint.h>
4#include <string.h>
5 
6#define THREADS 6
7#define ITERS 4000
8#define SLOTS 256
9#define TEST_ARENA_SIZE (64U * 1024U * 1024U)
10 
11static _Alignas(4096) uint8_t g_test_arena[TEST_ARENA_SIZE];
12 
13static uint32_t xs32(uint32_t *s)
14{
15 uint32_t x = *s;
16 x ^= x << 13;
17 x ^= x >> 17;
18 x ^= x << 5;
19 *s = x;
20 return x;
21}
22 
23typedef struct {
24 uint32_t seed;
25} worker_arg_t;
26 
27static void *worker(void *arg)
28{
29 worker_arg_t *w = (worker_arg_t *)arg;
30 void *slots[SLOTS] = {0};
31 size_t sizes[SLOTS] = {0};
32 
33 for (int i = 0; i < ITERS; i++) {
34 uint32_t r = xs32(&w->seed);
35 uint32_t idx = r % SLOTS;
36 if (slots[idx] != NULL) {
37 uint8_t *p = (uint8_t *)slots[idx];
38 size_t sz = sizes[idx];
39 if (sz > 0U) {
40 if (p[0] != (uint8_t)(idx & 0xFFU)) {
41 return (void *)1;
42 }
43 if (p[sz - 1U] != (uint8_t)((idx ^ 0xAAU) & 0xFFU)) {
44 return (void *)2;
45 }
46 }
47 pal_free(slots[idx]);
48 slots[idx] = NULL;
49 sizes[idx] = 0U;
50 } else {
51 size_t sz = (size_t)(r % 65536U) + 1U;
52 void *p = pal_malloc(sz);
53 if (p == NULL) {
54 return (void *)3;
55 }
56 memset(p, (int)(idx & 0xFFU), 1U);
57 ((uint8_t *)p)[sz - 1U] = (uint8_t)((idx ^ 0xAAU) & 0xFFU);
58 slots[idx] = p;
59 sizes[idx] = sz;
60 }
61 }
62 
63 for (uint32_t i = 0; i < SLOTS; i++) {
64 if (slots[i] != NULL) {
65 pal_free(slots[i]);
66 }
67 }
68 
69 return NULL;
70}
71 
72int main(void)
73{
74 if (pal_alloc_init(g_test_arena, sizeof(g_test_arena)) != 0) {
75 return 10;
76 }
77 pal_alloc_reset_stats();
78 
79 pthread_t th[THREADS];
80 worker_arg_t args[THREADS];
81 
82 for (int i = 0; i < THREADS; i++) {
83 args[i].seed = (uint32_t)(0xC001D00DU ^ (uint32_t)i);
84 if (pthread_create(&th[i], NULL, worker, &args[i]) != 0) {
85 return 11;
86 }
87 }
88 
89 for (int i = 0; i < THREADS; i++) {
90 void *ret = NULL;
91 (void)pthread_join(th[i], &ret);
92 if (ret != NULL) {
93 return 12;
94 }
95 }
96 
97 void *p = pal_calloc(128U, 16U);
98 if (p == NULL) {
99 return 13;
100 }
101 for (size_t i = 0U; i < 2048U; i++) {
102 if (((uint8_t *)p)[i] != 0U) {
103 return 14;
104 }
105 }
106 p = pal_realloc(p, 8192U);
107 if (p == NULL) {
108 return 15;
109 }
110 pal_free(p);
111 
112 void *a = pal_aligned_alloc(4096U, 123U);
113 if (a == NULL) {
114 return 16;
115 }
116 if (((uintptr_t)a & (4096U - 1U)) != 0U) {
117 return 17;
118 }
119 pal_free(a);
120 
121 void *m = NULL;
122 if (pal_posix_memalign(&m, 64U, 77U) != 0) {
123 return 18;
124 }
125 if (((uintptr_t)m & 63U) != 0U) {
126 return 19;
127 }
128 pal_free(m);
129 
130 pal_alloc_stats_t st;
131 pal_alloc_get_stats(&st);
132 if (st.failures != 0U) {
133 return 20;
134 }
135 if (st.bytes_in_use != 0U) {
136 return 21;
137 }
138 return 0;
139}
140