Commit | Line | Data |
---|---|---|
d273fd4b MD |
1 | // SPDX-License-Identifier: MIT |
2 | // SPDX-FileCopyrightText: 2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
3 | /* | |
4 | * rseq memory pool test. | |
5 | */ | |
6 | ||
7 | #ifndef _GNU_SOURCE | |
8 | #define _GNU_SOURCE | |
9 | #endif | |
10 | #include <assert.h> | |
11 | #include <sched.h> | |
12 | #include <signal.h> | |
13 | #include <stdio.h> | |
14 | #include <string.h> | |
15 | #include <sys/time.h> | |
16 | #include <inttypes.h> | |
17 | #include <stdlib.h> | |
18 | ||
19 | #include <rseq/mempool.h> | |
20 | ||
21 | #include "list.h" | |
22 | #include "tap.h" | |
23 | ||
24 | struct test_data { | |
25 | uintptr_t value; | |
26 | struct test_data __rseq_percpu *backref; | |
27 | struct list_head node; | |
28 | }; | |
29 | ||
30 | static void test_mempool_fill(size_t len) | |
31 | { | |
32 | struct test_data __rseq_percpu *ptr; | |
84a5a73a | 33 | struct test_data *iter, *tmp; |
d273fd4b MD |
34 | struct rseq_percpu_pool *mempool; |
35 | struct rseq_pool_attr *attr; | |
36 | uint64_t count = 0; | |
37 | LIST_HEAD(list); | |
38 | int ret, i; | |
39 | ||
40 | attr = rseq_pool_attr_create(); | |
a8ad787a | 41 | ok(attr, "Create pool attribute"); |
d273fd4b MD |
42 | ret = rseq_pool_attr_set_robust(attr); |
43 | ok(ret == 0, "Setting mempool robust attribute"); | |
44 | ||
45 | mempool = rseq_percpu_pool_create("test_data", | |
46 | sizeof(struct test_data), | |
47 | len, CPU_SETSIZE, attr); | |
48 | ok(mempool, "Create mempool of size %zu", len); | |
49 | rseq_pool_attr_destroy(attr); | |
50 | ||
51 | for (;;) { | |
52 | struct test_data *cpuptr; | |
53 | ||
54 | ptr = (struct test_data __rseq_percpu *) rseq_percpu_zmalloc(mempool); | |
55 | if (!ptr) | |
56 | break; | |
57 | /* Link items in cpu 0. */ | |
58 | cpuptr = rseq_percpu_ptr(ptr, 0); | |
59 | cpuptr->backref = ptr; | |
60 | /* Randomize items in list. */ | |
61 | if (count & 1) | |
62 | list_add(&cpuptr->node, &list); | |
63 | else | |
64 | list_add_tail(&cpuptr->node, &list); | |
65 | count++; | |
66 | } | |
67 | ||
68 | ok(count * sizeof(struct test_data) == len, "Allocated %" PRIu64 " objects in pool", count); | |
69 | ||
70 | list_for_each_entry(iter, &list, node) { | |
71 | ptr = iter->backref; | |
72 | for (i = 0; i < CPU_SETSIZE; i++) { | |
73 | struct test_data *cpuptr = rseq_percpu_ptr(ptr, i); | |
74 | ||
75 | if (cpuptr->value != 0) | |
76 | abort(); | |
77 | cpuptr->value++; | |
78 | } | |
79 | } | |
80 | ||
81 | ok(1, "Check for pool content corruption"); | |
82 | ||
84a5a73a | 83 | list_for_each_entry_safe(iter, tmp, &list, node) { |
d273fd4b MD |
84 | ptr = iter->backref; |
85 | rseq_percpu_free(ptr); | |
86 | } | |
87 | ret = rseq_percpu_pool_destroy(mempool); | |
88 | ok(ret == 0, "Destroy mempool"); | |
89 | } | |
90 | ||
91 | int main(void) | |
92 | { | |
93 | size_t len; | |
94 | ||
579badcb MD |
95 | plan_no_plan(); |
96 | ||
d273fd4b MD |
97 | /* From 4kB to 4MB */ |
98 | for (len = 4096; len < 4096 * 1024; len <<= 1) { | |
99 | test_mempool_fill(len); | |
100 | } | |
101 | ||
102 | exit(exit_status()); | |
103 | } |