Home | History | Annotate | Download | only in size
      1 /*
      2  * Copyright 2014 Sony Mobile Communications Inc.
      3  *
      4  * Licensed under the terms of the GNU GPL License version 2
      5  *
      6  * Selftest for runtime system size
      7  *
      8  * Prints the amount of RAM that the currently running system is using.
      9  *
     10  * This program tries to be as small as possible itself, to
     11  * avoid perturbing the system memory utilization with its
     12  * own execution.  It also attempts to have as few dependencies
     13  * on kernel features as possible.
     14  *
     15  * It should be statically linked, with startup libs avoided.
     16  * It uses no library calls, and only the following 3 syscalls:
     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()
     22  */
     23 
     24 #include <sys/sysinfo.h>
     25 #include <unistd.h>
     26 
     27 #define STDOUT_FILENO 1
     28 
     29 static int print(const char *s)
     30 {
     31 	return write(STDOUT_FILENO, s, __builtin_strlen(s));
     32 }
     33 
     34 static inline char *num_to_str(unsigned long num, char *buf, int len)
     35 {
     36 	unsigned int digit;
     37 
     38 	/* put digits in buffer from back to front */
     39 	buf += len - 1;
     40 	*buf = 0;
     41 	do {
     42 		digit = num % 10;
     43 		*(--buf) = digit + '0';
     44 		num /= 10;
     45 	} while (num > 0);
     46 
     47 	return buf;
     48 }
     49 
     50 static int print_num(unsigned long num)
     51 {
     52 	char num_buf[30];
     53 
     54 	return print(num_to_str(num, num_buf, sizeof(num_buf)));
     55 }
     56 
     57 static int print_k_value(const char *s, unsigned long num, unsigned long units)
     58 {
     59 	unsigned long long temp;
     60 	int ccode;
     61 
     62 	print(s);
     63 
     64 	temp = num;
     65 	temp = (temp * units)/1024;
     66 	num = temp;
     67 	ccode = print_num(num);
     68 	print("\n");
     69 	return ccode;
     70 }
     71 
     72 /* this program has no main(), as startup libraries are not used */
     73 void _start(void)
     74 {
     75 	int ccode;
     76 	struct sysinfo info;
     77 	unsigned long used;
     78 	static const char *test_name = " get runtime memory use\n";
     79 
     80 	print("TAP version 13\n");
     81 	print("# Testing system size.\n");
     82 
     83 	ccode = sysinfo(&info);
     84 	if (ccode < 0) {
     85 		print("not ok 1");
     86 		print(test_name);
     87 		print(" ---\n reason: \"could not get sysinfo\"\n ...\n");
     88 		_exit(ccode);
     89 	}
     90 	print("ok 1");
     91 	print(test_name);
     92 
     93 	/* ignore cache complexities for now */
     94 	used = info.totalram - info.freeram - info.bufferram;
     95 	print("# System runtime memory report (units in Kilobytes):\n");
     96 	print(" ---\n");
     97 	print_k_value(" Total:  ", info.totalram, info.mem_unit);
     98 	print_k_value(" Free:   ", info.freeram, info.mem_unit);
     99 	print_k_value(" Buffer: ", info.bufferram, info.mem_unit);
    100 	print_k_value(" In use: ", used, info.mem_unit);
    101 	print(" ...\n");
    102 	print("1..1\n");
    103 
    104 	_exit(0);
    105 }
    106