This test shows the amount of memory used by the system.
Note that this is dependent on the user-space that is loaded
when this program runs. Optimally, this program would be
run as the init program itself.
The program is optimized for size itself, to avoid conflating
its own execution with that of the system software.
The code is compiled statically, with no stdlibs. On my x86_64 system,
this results in a statically linked binary of less than 5K.
Signed-off-by: Tim Bird <tim.bird-/MT0OVThwyLZJqsBc5GL+g@public.gmane.org>
---
Changes from v5:
- make most routines static
- replace strip with gcc -s
- remove explicit reference to _start
- change --static to -static
- remove explicit reference to LIBGCC
- fix test description for ok and not ok paths, for test 1
Changes from v4:
- add more human-readable output
- put libgcc reference into a variable in Makefile
Changes from v3:
- fix copyright string (again!)
- use __builtin_strlen instead of my own strlen
- replace main with _start
Changes from v2:
- add return values to print routines
- add .gitignore file
Changes from v1:
- use more correct Copyright string in get_size.c
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/size/.gitignore | 1 +
tools/testing/selftests/size/Makefile | 15 +++++
tools/testing/selftests/size/get_size.c | 111 ++++++++++++++++++++++++++++++++
4 files changed, 128 insertions(+)
create mode 100644 tools/testing/selftests/size/.gitignore
create mode 100644 tools/testing/selftests/size/Makefile
create mode 100644 tools/testing/selftests/size/get_size.c
@@ -0,0 +1,111 @@+/*+*Copyright2014SonyMobileCommunicationsInc.+*+*LicensedunderthetermsoftheGNUGPLLicenseversion2+*+*Selftestforruntimesystemsize+*+*PrintstheamountofRAMthatthecurrentlyrunningsystemisusing.+*+*Thisprogramtriestobeassmallaspossibleitself,to+*avoidperturbingthesystemmemoryutilizationwithits+*ownexecution.Italsoattemptstohaveasfewdependencies+*onkernelfeaturesaspossible.+*+*Itshouldbestaticallylinked,withstartuplibsavoided.+*Itusesnolibrarycalls,andonlythefollowing3syscalls:+*sysinfo(),write(),and_exit()+*+*Foroutput,itavoidsprintf(whichinsomeClibraries+*haslargeexternaldependencies)byimplementingit'sown+*numberoutputandprintroutines,andusing__builtin_strlen()+*/++#include<sys/sysinfo.h>+#include<unistd.h>++#define STDOUT_FILENO 1++staticintprint(constchar*s)+{+returnwrite(STDOUT_FILENO,s,__builtin_strlen(s));+}+++/*+*num_to_str-putdigitsfromnuminto*s,lefttoright+*dothisbydividingthenumberbypowersof10+*thetrickypartistoomitleadingzeros+*don'tprintzerosuntilwe'vestartedprintinganynumbersatall+*/+staticvoidnum_to_str(unsignedlongnum,char*s)+{+unsignedlonglongtemp,div;+intstarted;++temp=num;+div=1000000000000000000LL;+started=0;+while(div){+if(temp/div||started){+*s++=(unsignedchar)(temp/div+'0');+started=1;+}+temp-=(temp/div)*div;+div/=10;+}+*s=0;+}++staticintprint_num(unsignedlongnum)+{+charnum_buf[30];++num_to_str(num,num_buf);+returnprint(num_buf);+}++staticintprint_k_value(constchar*s,unsignedlongnum,unsignedlongunits)+{+unsignedlonglongtemp;+intccode;++print(s);++temp=num;+temp=(temp*units)/1024;+num=temp;+ccode=print_num(num);+print("\n");+returnccode;+}++/* this program has no main(), as startup libraries are not used */+void_start(void)+{+intccode;+structsysinfoinfo;+unsignedlongused;++print("Testing system size.\n");+print("1..1\n");++ccode=sysinfo(&info);+if(ccode<0){+print("not ok 1 get runtime memory use\n");+print("# could not get sysinfo\n");+_exit(ccode);+}+/* ignore cache complexities for now */+used=info.totalram-info.freeram-info.bufferram;+print_k_value("ok 1 get runtime memory use # size = ",used,+info.mem_unit);++print("# System runtime memory report (units in Kilobytes):\n");+print_k_value("# Total: ",info.totalram,info.mem_unit);+print_k_value("# Free: ",info.freeram,info.mem_unit);+print_k_value("# Buffer: ",info.bufferram,info.mem_unit);+print_k_value("# In use: ",used,info.mem_unit);++_exit(0);+}
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2014-12-03 03:43:15
On Tue, 2014-12-02 at 19:36 -0800, Tim Bird wrote:
This test shows the amount of memory used by the system.
Note that this is dependent on the user-space that is loaded
when this program runs. Optimally, this program would be
run as the init program itself.
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It allows optionally setting a custom CC, as well as optionally CROSS_COMPILE.
The only thing it doesn't do is choose gcc explicitly, but you shouldn't really
do that anyway - unless you absolutely require gcc. Let the user choose their
compiler by choosing where cc points.
cheers
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It is even more necessary that #ifndef and #endif don't exist in make.
They are just comments, and therefore, ignored. Seems like Tim does too
much C :-)
Best regards,
Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It is even more necessary that #ifndef and #endif don't exist in make.
They are just comments, and therefore, ignored. Seems like Tim does too
much C :-)
OK - that's hilarious. Saying 'Oops!' would be too casual for my degree of
embarrassment. :-)
Makefiles do have similar constructs. Those should have been
ifeq ($(CC),)
...
endif
This obviously got through via a failiure in testing - which is somewhat ironic.
Look for a v6 soon. (Geez, when is the merge window coming. I thought this trivial
program would get in pretty easily, but no... that's never the way. Of course
it helps if the submitter is not an idiot.)
-- Tim
On Tue, 2014-12-02 at 19:36 -0800, Tim Bird wrote:
quoted
This test shows the amount of memory used by the system.
Note that this is dependent on the user-space that is loaded
when this program runs. Optimally, this program would be
run as the init program itself.
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It allows optionally setting a custom CC, as well as optionally CROSS_COMPILE.
I'm not sure I follow this.
If CC is unset, you get only the CROSS_COMPILE prefix.
If CC is set to e.g. 'gcc', then you get a nicely formatted toolchain string.
But if CC already has the prefix applied, then this will result in
having it duplicated, which surely won't work correctly.
In the long run, I would hope that a higher level Makefile or environment setting
will be setting the toolchain string appropriately (as well as handling build flags)
which is why I wanted to use an ifndef (which Thomas correctly pointed out is just
wrong).
Actually, after getting this tiny program accepted, my next task was working on a
proper fix for handling cross compilation in a more generic (not case-by-case) way.
CROSS_COMPILE prefix usage looks a bit uncoordinated in the tools directory, but most
tests seem to be favoring $(CROSS_COMPILE)gcc.
$ cd tools ; mgrep CROSS
./vm/Makefile:CC = $(CROSS_COMPILE)gcc
./usb/Makefile:CC = $(CROSS_COMPILE)gcc
./testing/selftests/net/Makefile:CC = $(CROSS_COMPILE)gcc
./testing/selftests/vm/Makefile:CC = $(CROSS_COMPILE)gcc
./testing/selftests/efivarfs/Makefile:CC = $(CROSS_COMPILE)gcc
./testing/selftests/size/Makefile: CC = $(CROSS_COMPILE)gcc
./testing/selftests/powerpc/Makefile:CC := $(CROSS_COMPILE)$(CC)
./hv/Makefile:CC = $(CROSS_COMPILE)gcc
./perf/config/feature-checks/Makefile:CC := $(CROSS_COMPILE)gcc -MD
./perf/config/feature-checks/Makefile:PKG_CONFIG := $(CROSS_COMPILE)pkg-config
./lib/api/Makefile:CC = $(CROSS_COMPILE)gcc
./lib/api/Makefile:AR = $(CROSS_COMPILE)ar
./lib/lockdep/Makefile:# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
./lib/lockdep/Makefile:$(call allow-override,CC,$(CROSS_COMPILE)gcc)
./lib/lockdep/Makefile:$(call allow-override,AR,$(CROSS_COMPILE)ar)
./lib/lockdep/Makefile:TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
./lib/traceevent/Makefile:# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
./lib/traceevent/Makefile:$(call allow-override,CC,$(CROSS_COMPILE)gcc)
./lib/traceevent/Makefile:$(call allow-override,AR,$(CROSS_COMPILE)ar)
./lib/traceevent/Makefile:TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
./cgroup/Makefile:CC = $(CROSS_COMPILE)gcc
./power/acpi/Makefile:CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
./power/acpi/Makefile:CC = $(CROSS)gcc
./power/acpi/Makefile:LD = $(CROSS)gcc
./power/acpi/Makefile:STRIP = $(CROSS)strip
./power/cpupower/Makefile:CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc-
./power/cpupower/Makefile:CC = $(CROSS)gcc
./power/cpupower/Makefile:LD = $(CROSS)gcc
./power/cpupower/Makefile:AR = $(CROSS)ar
./power/cpupower/Makefile:STRIP = $(CROSS)strip
./power/cpupower/Makefile:RANLIB = $(CROSS)ranlib
./power/cpupower/Makefile:export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
./power/x86/turbostat/Makefile:CC = $(CROSS_COMPILE)gcc
I agree it's desirable not to hardcode gcc, but we seem to be doing it all over
the place already.
-- Tim
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It allows optionally setting a custom CC, as well as optionally CROSS_COMPILE.
I'm not sure I follow this.
If CC is unset, you get only the CROSS_COMPILE prefix.
If CC is set to e.g. 'gcc', then you get a nicely formatted toolchain string.
But if CC already has the prefix applied, then this will result in
having it duplicated, which surely won't work correctly.
In the long run, I would hope that a higher level Makefile or environment setting
will be setting the toolchain string appropriately (as well as handling build flags)
which is why I wanted to use an ifndef (which Thomas correctly pointed out is just
wrong).
Actually, after getting this tiny program accepted, my next task was working on a
proper fix for handling cross compilation in a more generic (not case-by-case) way.
CROSS_COMPILE prefix usage looks a bit uncoordinated in the tools directory, but most
tests seem to be favoring $(CROSS_COMPILE)gcc.
$ cd tools ; mgrep CROSS
[...]
I agree it's desirable not to hardcode gcc, but we seem to be doing it all over
the place already.
Seems like it's time to start integrating the tests with the regular Kbuild
system, which handles cross-compilation fine...
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It allows optionally setting a custom CC, as well as optionally CROSS_COMPILE.
I'm not sure I follow this.
If CC is unset, you get only the CROSS_COMPILE prefix.
If CC is set to e.g. 'gcc', then you get a nicely formatted toolchain string.
But if CC already has the prefix applied, then this will result in
having it duplicated, which surely won't work correctly.
In the long run, I would hope that a higher level Makefile or environment setting
will be setting the toolchain string appropriately (as well as handling build flags)
which is why I wanted to use an ifndef (which Thomas correctly pointed out is just
wrong).
Actually, after getting this tiny program accepted, my next task was working on a
proper fix for handling cross compilation in a more generic (not case-by-case) way.
CROSS_COMPILE prefix usage looks a bit uncoordinated in the tools directory, but most
tests seem to be favoring $(CROSS_COMPILE)gcc.
$ cd tools ; mgrep CROSS
[...]
quoted
I agree it's desirable not to hardcode gcc, but we seem to be doing it all over
the place already.
Seems like it's time to start integrating the tests with the regular Kbuild
system, which handles cross-compilation fine...
Where possible, yes. It would be nice to leverage CROSS_COMPILE and CFLAGS, or
a portion thereof, from the Kbuild system (as well a KBUILD_OUTPUT and friends).
It's on my to-do list, after getting my little C program accepted...
-- Tim
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2014-12-04 00:08:31
On Wed, 2014-12-03 at 08:29 -0800, Tim Bird wrote:
On 12/02/2014 07:43 PM, Michael Ellerman wrote:
quoted
On Tue, 2014-12-02 at 19:36 -0800, Tim Bird wrote:
quoted
This test shows the amount of memory used by the system.
Note that this is dependent on the user-space that is loaded
when this program runs. Optimally, this program would be
run as the init program itself.
On Wed, 2014-12-03 at 08:29 -0800, Tim Bird wrote:
quoted
On 12/02/2014 07:43 PM, Michael Ellerman wrote:
quoted
On Tue, 2014-12-02 at 19:36 -0800, Tim Bird wrote:
quoted
This test shows the amount of memory used by the system.
Note that this is dependent on the user-space that is loaded
when this program runs. Optimally, this program would be
run as the init program itself.
I think the following is preferable:
CC := $(CROSS_COMPILE)$(CC)
It allows optionally setting a custom CC, as well as optionally CROSS_COMPILE.
I'm not sure I follow this.
If CC is unset, you get only the CROSS_COMPILE prefix.
CC is never unset. The default value is 'cc'.
Yeah - I found that out by experimentation yesterday. So my whole
idea for configuring it based on an unset CC was misguided.
quoted
If CC is set to e.g. 'gcc', then you get a nicely formatted toolchain string.
Right.
quoted
But if CC already has the prefix applied, then this will result in
having it duplicated, which surely won't work correctly.
That's just PEBKAC. Don't specify CROSS_COMPILE and also a fully specified CC.
Try it with the kernel Makefile and see how well it works.
quoted
CROSS_COMPILE prefix usage looks a bit uncoordinated in the tools directory, but most
tests seem to be favoring $(CROSS_COMPILE)gcc.
That doesn't make it right :)
Agreed. I'd like to separate this issue from the rest of the patch.
Shuah has accepted the patch as it currently is, but I'd like
to start working on the best way to support cross compilation
throughout the kselftest suite.
Ideally we can have CC set properly in a higher-level Makefile,
and not reference CROSS_COMPILE at all in the sub-directory Makefiles.
This may involve copying how CROSS_COMPILE and CFLAGS work in
the rest of the kernel tree, or making some kselftest-specific
modifications.
-- Tim