Commit | Line | Data |
---|---|---|
4f19048f | 1 | // SPDX-License-Identifier: GPL-2.0-only |
3ce51050 TB |
2 | /* |
3 | * Copyright 2014 Sony Mobile Communications Inc. | |
4 | * | |
3ce51050 TB |
5 | * Selftest for runtime system size |
6 | * | |
7 | * Prints the amount of RAM that the currently running system is using. | |
8 | * | |
9 | * This program tries to be as small as possible itself, to | |
10 | * avoid perturbing the system memory utilization with its | |
11 | * own execution. It also attempts to have as few dependencies | |
12 | * on kernel features as possible. | |
13 | * | |
6b64a650 SP |
14 | * It should be statically linked, with startup libs avoided. It uses |
15 | * no library calls except the syscall() function for the following 3 | |
16 | * syscalls: | |
3ce51050 TB |
17 | * sysinfo(), write(), and _exit() |
18 | * | |
19 | * For output, it avoids printf (which in some C libraries | |
20 | * has large external dependencies) by implementing it's own | |
21 | * number output and print routines, and using __builtin_strlen() | |
6b64a650 SP |
22 | * |
23 | * The test may crash if any of the above syscalls fails because in some | |
24 | * libc implementations (e.g. the GNU C Library) errno is saved in | |
25 | * thread-local storage, which does not get initialized due to avoiding | |
26 | * startup libs. | |
3ce51050 TB |
27 | */ |
28 | ||
29 | #include <sys/sysinfo.h> | |
30 | #include <unistd.h> | |
6b64a650 | 31 | #include <sys/syscall.h> |
3ce51050 TB |
32 | |
33 | #define STDOUT_FILENO 1 | |
34 | ||
35 | static int print(const char *s) | |
36 | { | |
6b64a650 SP |
37 | size_t len = 0; |
38 | ||
39 | while (s[len] != '\0') | |
40 | len++; | |
41 | ||
42 | return syscall(SYS_write, STDOUT_FILENO, s, len); | |
3ce51050 TB |
43 | } |
44 | ||
45 | static inline char *num_to_str(unsigned long num, char *buf, int len) | |
46 | { | |
47 | unsigned int digit; | |
48 | ||
49 | /* put digits in buffer from back to front */ | |
50 | buf += len - 1; | |
51 | *buf = 0; | |
52 | do { | |
53 | digit = num % 10; | |
54 | *(--buf) = digit + '0'; | |
55 | num /= 10; | |
56 | } while (num > 0); | |
57 | ||
58 | return buf; | |
59 | } | |
60 | ||
61 | static int print_num(unsigned long num) | |
62 | { | |
63 | char num_buf[30]; | |
64 | ||
65 | return print(num_to_str(num, num_buf, sizeof(num_buf))); | |
66 | } | |
67 | ||
68 | static int print_k_value(const char *s, unsigned long num, unsigned long units) | |
69 | { | |
70 | unsigned long long temp; | |
71 | int ccode; | |
72 | ||
73 | print(s); | |
74 | ||
75 | temp = num; | |
76 | temp = (temp * units)/1024; | |
77 | num = temp; | |
78 | ccode = print_num(num); | |
79 | print("\n"); | |
80 | return ccode; | |
81 | } | |
82 | ||
83 | /* this program has no main(), as startup libraries are not used */ | |
84 | void _start(void) | |
85 | { | |
86 | int ccode; | |
87 | struct sysinfo info; | |
88 | unsigned long used; | |
48e42f91 | 89 | static const char *test_name = " get runtime memory use\n"; |
3ce51050 | 90 | |
48e42f91 TB |
91 | print("TAP version 13\n"); |
92 | print("# Testing system size.\n"); | |
3ce51050 | 93 | |
6b64a650 | 94 | ccode = syscall(SYS_sysinfo, &info); |
3ce51050 | 95 | if (ccode < 0) { |
48e42f91 TB |
96 | print("not ok 1"); |
97 | print(test_name); | |
98 | print(" ---\n reason: \"could not get sysinfo\"\n ...\n"); | |
6b64a650 | 99 | syscall(SYS_exit, ccode); |
3ce51050 | 100 | } |
48e42f91 TB |
101 | print("ok 1"); |
102 | print(test_name); | |
103 | ||
3ce51050 TB |
104 | /* ignore cache complexities for now */ |
105 | used = info.totalram - info.freeram - info.bufferram; | |
3ce51050 | 106 | print("# System runtime memory report (units in Kilobytes):\n"); |
48e42f91 TB |
107 | print(" ---\n"); |
108 | print_k_value(" Total: ", info.totalram, info.mem_unit); | |
109 | print_k_value(" Free: ", info.freeram, info.mem_unit); | |
110 | print_k_value(" Buffer: ", info.bufferram, info.mem_unit); | |
111 | print_k_value(" In use: ", used, info.mem_unit); | |
112 | print(" ...\n"); | |
113 | print("1..1\n"); | |
3ce51050 | 114 | |
6b64a650 | 115 | syscall(SYS_exit, 0); |
3ce51050 | 116 | } |