Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2014 Sony Mobile Communications Inc.
0004  *
0005  * Selftest for runtime system size
0006  *
0007  * Prints the amount of RAM that the currently running system is using.
0008  *
0009  * This program tries to be as small as possible itself, to
0010  * avoid perturbing the system memory utilization with its
0011  * own execution.  It also attempts to have as few dependencies
0012  * on kernel features as possible.
0013  *
0014  * It should be statically linked, with startup libs avoided.  It uses
0015  * no library calls except the syscall() function for the following 3
0016  * syscalls:
0017  *   sysinfo(), write(), and _exit()
0018  *
0019  * For output, it avoids printf (which in some C libraries
0020  * has large external dependencies) by  implementing it's own
0021  * number output and print routines, and using __builtin_strlen()
0022  *
0023  * The test may crash if any of the above syscalls fails because in some
0024  * libc implementations (e.g. the GNU C Library) errno is saved in
0025  * thread-local storage, which does not get initialized due to avoiding
0026  * startup libs.
0027  */
0028 
0029 #include <sys/sysinfo.h>
0030 #include <unistd.h>
0031 #include <sys/syscall.h>
0032 
0033 #define STDOUT_FILENO 1
0034 
0035 static int print(const char *s)
0036 {
0037     size_t len = 0;
0038 
0039     while (s[len] != '\0')
0040         len++;
0041 
0042     return syscall(SYS_write, STDOUT_FILENO, s, len);
0043 }
0044 
0045 static inline char *num_to_str(unsigned long num, char *buf, int len)
0046 {
0047     unsigned int digit;
0048 
0049     /* put digits in buffer from back to front */
0050     buf += len - 1;
0051     *buf = 0;
0052     do {
0053         digit = num % 10;
0054         *(--buf) = digit + '0';
0055         num /= 10;
0056     } while (num > 0);
0057 
0058     return buf;
0059 }
0060 
0061 static int print_num(unsigned long num)
0062 {
0063     char num_buf[30];
0064 
0065     return print(num_to_str(num, num_buf, sizeof(num_buf)));
0066 }
0067 
0068 static int print_k_value(const char *s, unsigned long num, unsigned long units)
0069 {
0070     unsigned long long temp;
0071     int ccode;
0072 
0073     print(s);
0074 
0075     temp = num;
0076     temp = (temp * units)/1024;
0077     num = temp;
0078     ccode = print_num(num);
0079     print("\n");
0080     return ccode;
0081 }
0082 
0083 /* this program has no main(), as startup libraries are not used */
0084 void _start(void)
0085 {
0086     int ccode;
0087     struct sysinfo info;
0088     unsigned long used;
0089     static const char *test_name = " get runtime memory use\n";
0090 
0091     print("TAP version 13\n");
0092     print("# Testing system size.\n");
0093 
0094     ccode = syscall(SYS_sysinfo, &info);
0095     if (ccode < 0) {
0096         print("not ok 1");
0097         print(test_name);
0098         print(" ---\n reason: \"could not get sysinfo\"\n ...\n");
0099         syscall(SYS_exit, ccode);
0100     }
0101     print("ok 1");
0102     print(test_name);
0103 
0104     /* ignore cache complexities for now */
0105     used = info.totalram - info.freeram - info.bufferram;
0106     print("# System runtime memory report (units in Kilobytes):\n");
0107     print(" ---\n");
0108     print_k_value(" Total:  ", info.totalram, info.mem_unit);
0109     print_k_value(" Free:   ", info.freeram, info.mem_unit);
0110     print_k_value(" Buffer: ", info.bufferram, info.mem_unit);
0111     print_k_value(" In use: ", used, info.mem_unit);
0112     print(" ...\n");
0113     print("1..1\n");
0114 
0115     syscall(SYS_exit, 0);
0116 }