linux/tools/testing/selftests/size/get_size.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2014 Sony Mobile Communications Inc.
   4 *
   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 *
  14 * It should be statically linked, with startup libs avoided.
  15 * It uses no library calls, and only the following 3 syscalls:
  16 *   sysinfo(), write(), and _exit()
  17 *
  18 * For output, it avoids printf (which in some C libraries
  19 * has large external dependencies) by  implementing it's own
  20 * number output and print routines, and using __builtin_strlen()
  21 */
  22
  23#include <sys/sysinfo.h>
  24#include <unistd.h>
  25
  26#define STDOUT_FILENO 1
  27
  28static int print(const char *s)
  29{
  30        return write(STDOUT_FILENO, s, __builtin_strlen(s));
  31}
  32
  33static inline char *num_to_str(unsigned long num, char *buf, int len)
  34{
  35        unsigned int digit;
  36
  37        /* put digits in buffer from back to front */
  38        buf += len - 1;
  39        *buf = 0;
  40        do {
  41                digit = num % 10;
  42                *(--buf) = digit + '0';
  43                num /= 10;
  44        } while (num > 0);
  45
  46        return buf;
  47}
  48
  49static int print_num(unsigned long num)
  50{
  51        char num_buf[30];
  52
  53        return print(num_to_str(num, num_buf, sizeof(num_buf)));
  54}
  55
  56static int print_k_value(const char *s, unsigned long num, unsigned long units)
  57{
  58        unsigned long long temp;
  59        int ccode;
  60
  61        print(s);
  62
  63        temp = num;
  64        temp = (temp * units)/1024;
  65        num = temp;
  66        ccode = print_num(num);
  67        print("\n");
  68        return ccode;
  69}
  70
  71/* this program has no main(), as startup libraries are not used */
  72void _start(void)
  73{
  74        int ccode;
  75        struct sysinfo info;
  76        unsigned long used;
  77        static const char *test_name = " get runtime memory use\n";
  78
  79        print("TAP version 13\n");
  80        print("# Testing system size.\n");
  81
  82        ccode = sysinfo(&info);
  83        if (ccode < 0) {
  84                print("not ok 1");
  85                print(test_name);
  86                print(" ---\n reason: \"could not get sysinfo\"\n ...\n");
  87                _exit(ccode);
  88        }
  89        print("ok 1");
  90        print(test_name);
  91
  92        /* ignore cache complexities for now */
  93        used = info.totalram - info.freeram - info.bufferram;
  94        print("# System runtime memory report (units in Kilobytes):\n");
  95        print(" ---\n");
  96        print_k_value(" Total:  ", info.totalram, info.mem_unit);
  97        print_k_value(" Free:   ", info.freeram, info.mem_unit);
  98        print_k_value(" Buffer: ", info.bufferram, info.mem_unit);
  99        print_k_value(" In use: ", used, info.mem_unit);
 100        print(" ...\n");
 101        print("1..1\n");
 102
 103        _exit(0);
 104}
 105