1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
6 Copyright 2013 Thomas H.P. Andersen
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 #include "parse-util.h"
31 #include "process-util.h"
32 #include "raw-clone.h"
34 #include "string-util.h"
37 static void test_align_power2(void) {
40 assert_se(ALIGN_POWER2(0) == 0);
41 assert_se(ALIGN_POWER2(1) == 1);
42 assert_se(ALIGN_POWER2(2) == 2);
43 assert_se(ALIGN_POWER2(3) == 4);
44 assert_se(ALIGN_POWER2(12) == 16);
46 assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
47 assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
48 assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
49 assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
50 assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);
52 for (i = 1; i < 131071; ++i) {
53 for (p2 = 1; p2 < i; p2 <<= 1)
56 assert_se(ALIGN_POWER2(i) == p2);
59 for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
60 for (p2 = 1; p2 && p2 < i; p2 <<= 1)
63 assert_se(ALIGN_POWER2(i) == p2);
67 static void test_max(void) {
70 int b[CONST_MAX(10, 100)];
72 .a = CONST_MAX(10, 100),
76 assert_cc(sizeof(val1.b) == sizeof(int) * 100);
78 /* CONST_MAX returns (void) instead of a value if the passed arguments
79 * are not of the same type or not constant expressions. */
80 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 10)), int));
81 assert_cc(__builtin_types_compatible_p(typeof(CONST_MAX(1, 1U)), void));
83 assert_se(val1.a == 100);
84 assert_se(MAX(++d, 0) == 1);
87 assert_cc(MAXSIZE(char[3], uint16_t) == 3);
88 assert_cc(MAXSIZE(char[3], uint32_t) == 4);
89 assert_cc(MAXSIZE(char, long) == sizeof(long));
91 assert_se(MAX(-5, 5) == 5);
92 assert_se(MAX(5, 5) == 5);
93 assert_se(MAX(MAX(1, MAX(2, MAX(3, 4))), 5) == 5);
94 assert_se(MAX(MAX(1, MAX(2, MAX(3, 2))), 1) == 3);
95 assert_se(MAX(MIN(1, MIN(2, MIN(3, 4))), 5) == 5);
96 assert_se(MAX(MAX(1, MIN(2, MIN(3, 2))), 1) == 2);
97 assert_se(LESS_BY(8, 4) == 4);
98 assert_se(LESS_BY(8, 8) == 0);
99 assert_se(LESS_BY(4, 8) == 0);
100 assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
101 assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
102 assert_se(CLAMP(-5, 0, 1) == 0);
103 assert_se(CLAMP(5, 0, 1) == 1);
104 assert_se(CLAMP(5, -10, 1) == 1);
105 assert_se(CLAMP(5, -10, 10) == 5);
106 assert_se(CLAMP(CLAMP(0, -10, 10), CLAMP(-5, 10, 20), CLAMP(100, -5, 20)) == 10);
109 #pragma GCC diagnostic push
111 # pragma GCC diagnostic ignored "-Waddress-of-packed-member"
114 static void test_container_of(void) {
120 } _packed_ myval = { };
122 assert_cc(sizeof(myval) == 17);
123 assert_se(container_of(&myval.v1, struct mytype, v1) == &myval);
124 assert_se(container_of(&myval.v2, struct mytype, v2) == &myval);
125 assert_se(container_of(&container_of(&myval.v2,
132 #pragma GCC diagnostic pop
134 static void test_div_round_up(void) {
138 assert_se(DIV_ROUND_UP(0, 8) == 0);
139 assert_se(DIV_ROUND_UP(1, 8) == 1);
140 assert_se(DIV_ROUND_UP(8, 8) == 1);
141 assert_se(DIV_ROUND_UP(12, 8) == 2);
142 assert_se(DIV_ROUND_UP(16, 8) == 2);
144 /* test multiple evaluation */
146 assert_se(DIV_ROUND_UP(div++, 8) == 0 && div == 1);
147 assert_se(DIV_ROUND_UP(++div, 8) == 1 && div == 2);
148 assert_se(DIV_ROUND_UP(8, div++) == 4 && div == 3);
149 assert_se(DIV_ROUND_UP(8, ++div) == 2 && div == 4);
151 /* overflow test with exact division */
152 assert_se(sizeof(0U) == 4);
153 assert_se(0xfffffffaU % 10U == 0U);
154 assert_se(0xfffffffaU / 10U == 429496729U);
155 assert_se(DIV_ROUND_UP(0xfffffffaU, 10U) == 429496729U);
156 assert_se((0xfffffffaU + 10U - 1U) / 10U == 0U);
157 assert_se(0xfffffffaU / 10U + !!(0xfffffffaU % 10U) == 429496729U);
159 /* overflow test with rounded division */
160 assert_se(0xfffffffdU % 10U == 3U);
161 assert_se(0xfffffffdU / 10U == 429496729U);
162 assert_se(DIV_ROUND_UP(0xfffffffdU, 10U) == 429496730U);
163 assert_se((0xfffffffdU + 10U - 1U) / 10U == 0U);
164 assert_se(0xfffffffdU / 10U + !!(0xfffffffdU % 10U) == 429496730U);
167 static void test_u64log2(void) {
168 assert_se(u64log2(0) == 0);
169 assert_se(u64log2(8) == 3);
170 assert_se(u64log2(9) == 3);
171 assert_se(u64log2(15) == 3);
172 assert_se(u64log2(16) == 4);
173 assert_se(u64log2(1024*1024) == 20);
174 assert_se(u64log2(1024*1024+5) == 20);
177 static void test_protect_errno(void) {
183 assert_se(errno == 12);
186 static void test_in_set(void) {
187 assert_se(IN_SET(1, 1));
188 assert_se(IN_SET(1, 1, 2, 3, 4));
189 assert_se(IN_SET(2, 1, 2, 3, 4));
190 assert_se(IN_SET(3, 1, 2, 3, 4));
191 assert_se(IN_SET(4, 1, 2, 3, 4));
192 assert_se(!IN_SET(0, 1));
193 assert_se(!IN_SET(0, 1, 2, 3, 4));
196 static void test_log2i(void) {
197 assert_se(log2i(1) == 0);
198 assert_se(log2i(2) == 1);
199 assert_se(log2i(3) == 1);
200 assert_se(log2i(4) == 2);
201 assert_se(log2i(32) == 5);
202 assert_se(log2i(33) == 5);
203 assert_se(log2i(63) == 5);
204 assert_se(log2i(INT_MAX) == sizeof(int)*8-2);
207 #if 0 /// UNNEEDED by elogind
208 static void test_raw_clone(void) {
209 pid_t parent, pid, pid2;
212 log_info("before clone: getpid()→"PID_FMT, parent);
213 assert_se(raw_getpid() == parent);
219 log_info("raw_clone: "PID_FMT" getpid()→"PID_FMT" raw_getpid()→"PID_FMT,
220 pid, getpid(), pid2);
222 assert_se(pid2 != parent);
227 assert_se(pid2 == parent);
228 waitpid(pid, &status, __WCLONE);
229 assert_se(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
234 static void test_physical_memory(void) {
236 char buf[FORMAT_BYTES_MAX];
238 p = physical_memory();
240 assert_se(p < UINT64_MAX);
241 assert_se(p % page_size() == 0);
243 log_info("Memory: %s (%" PRIu64 ")", format_bytes(buf, sizeof(buf), p), p);
246 static void test_physical_memory_scale(void) {
249 p = physical_memory();
251 assert_se(physical_memory_scale(0, 100) == 0);
252 assert_se(physical_memory_scale(100, 100) == p);
254 log_info("Memory original: %" PRIu64, physical_memory());
255 log_info("Memory scaled by 50%%: %" PRIu64, physical_memory_scale(50, 100));
256 log_info("Memory divided by 2: %" PRIu64, physical_memory() / 2);
257 log_info("Page size: %zu", page_size());
259 /* There might be an uneven number of pages, hence permit these calculations to be half a page off... */
260 assert_se(page_size()/2 + physical_memory_scale(50, 100) - p/2 <= page_size());
261 assert_se(physical_memory_scale(200, 100) == p*2);
263 assert_se(physical_memory_scale(0, 1) == 0);
264 assert_se(physical_memory_scale(1, 1) == p);
265 assert_se(physical_memory_scale(2, 1) == p*2);
267 assert_se(physical_memory_scale(0, 2) == 0);
269 assert_se(page_size()/2 + physical_memory_scale(1, 2) - p/2 <= page_size());
270 assert_se(physical_memory_scale(2, 2) == p);
271 assert_se(physical_memory_scale(4, 2) == p*2);
273 assert_se(physical_memory_scale(0, UINT32_MAX) == 0);
274 assert_se(physical_memory_scale(UINT32_MAX, UINT32_MAX) == p);
277 assert_se(physical_memory_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
280 static void test_system_tasks_max(void) {
283 t = system_tasks_max();
285 assert_se(t < UINT64_MAX);
287 log_info("Max tasks: %" PRIu64, t);
290 static void test_system_tasks_max_scale(void) {
293 t = system_tasks_max();
295 assert_se(system_tasks_max_scale(0, 100) == 0);
296 assert_se(system_tasks_max_scale(100, 100) == t);
298 assert_se(system_tasks_max_scale(0, 1) == 0);
299 assert_se(system_tasks_max_scale(1, 1) == t);
300 assert_se(system_tasks_max_scale(2, 1) == 2*t);
302 assert_se(system_tasks_max_scale(0, 2) == 0);
303 assert_se(system_tasks_max_scale(1, 2) == t/2);
304 assert_se(system_tasks_max_scale(2, 2) == t);
305 assert_se(system_tasks_max_scale(3, 2) == (3*t)/2);
306 assert_se(system_tasks_max_scale(4, 2) == t*2);
308 assert_se(system_tasks_max_scale(0, UINT32_MAX) == 0);
309 assert_se(system_tasks_max_scale((UINT32_MAX-1)/2, UINT32_MAX-1) == t/2);
310 assert_se(system_tasks_max_scale(UINT32_MAX, UINT32_MAX) == t);
314 assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
317 int main(int argc, char *argv[]) {
318 log_parse_environment();
326 test_protect_errno();
329 #if 0 /// UNNEEDED by elogind
332 test_physical_memory();
333 test_physical_memory_scale();
334 test_system_tasks_max();
335 test_system_tasks_max_scale();