From 915b04a76e8a5027835bae387337123df31c310e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Sun, 11 Aug 2019 00:00:03 +0000 Subject: [PATCH] mmap anonymous: configurable size --- README.adoc | 26 ++++++++++++++++---- path_properties.py | 2 +- userland/c/malloc.c | 15 ++++++++--- userland/c/{out_of_memory.c => malloc_max.c} | 2 +- userland/linux/mmap_anonymous.c | 13 ++++++++-- 5 files changed, 46 insertions(+), 12 deletions(-) rename userland/c/{out_of_memory.c => malloc_max.c} (78%) diff --git a/README.adoc b/README.adoc index 7e131f3..d4f8a34 100644 --- a/README.adoc +++ b/README.adoc @@ -12539,20 +12539,36 @@ link:userland/c/malloc.c[]: `malloc` hello world: allocate two ints and use them LInux 5.1 / glibc 2.29 implements it with the <>. -===== malloc out o fmemory +===== malloc maximum size -Test how much memory Linux lets us allocate: +Test how much memory Linux lets us allocate by doubling a buffer with `realloc` until it fails: .... -./run --userland userland/c/out_of_memory.c +./run --userland userland/c/malloc_max.c .... -Source: link:userland/c/out_of_memory.c[] +Source: link:userland/c/malloc_max.c[] -Outcome at c03d5d18ea971ae85d008101528d84c2ff25eb27 on Ubuntu 19.04 <> host: prints up to `0x1000000000` (64GiB). +Outcome at c03d5d18ea971ae85d008101528d84c2ff25eb27 on Ubuntu 19.04 <> host (16GiB RAM): prints up to `0x1000000000` (64GiB). TODO dive into source code. +TODO: if we do direct <> allocations with link:userland/c/malloc.c[] or <> with link:userland/linux/mmap_anonymous.c[], then the limit was smaller than 64GiB! + +These work: + +.... +./userland/c/malloc.out 0x100000000 +./userland/linux/mmap_anonymous.out 0x100000000 +.... + +which is `4Gib * sizeof(int) == 16GiB`, but these fail at 32GiB: + +.... +./userland/c/malloc.out 0x200000000 +./userland/linux/mmap_anonymous.out 0x200000000 +.... + Bibliography: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate ==== GCC C extensions diff --git a/path_properties.py b/path_properties.py index ffe50dd..29357e0 100644 --- a/path_properties.py +++ b/path_properties.py @@ -473,7 +473,7 @@ path_properties_tuples = ( 'file_write_read.c': {'baremetal': False}, 'getchar.c': {'interactive': True}, 'infinite_loop.c': {'more_than_1s': True}, - 'out_of_memory.c': {'disrupts_system': True}, + 'malloc_max.c': {'disrupts_system': True}, 'return1.c': {'exit_status': 1}, 'return2.c': {'exit_status': 2}, } diff --git a/userland/c/malloc.c b/userland/c/malloc.c index 7759c66..f522933 100644 --- a/userland/c/malloc.c +++ b/userland/c/malloc.c @@ -4,11 +4,20 @@ #include #include -int main(void) { +int main(int argc, char **argv) { int *is; - size_t nbytes = 2 * sizeof(*is); + size_t nbytes, nints; - /* Allocate 2 ints. Note that unlike traditional stack arrays (non-VLA) + /* Decide how many ints to allocate. */ + if (argc < 2) { + nints = 2; + } else { + nints = strtoull(argv[1], NULL, 0); + } + nbytes = nints * sizeof(*is); + + /* Allocate the ints. + * Note that unlike traditional stack arrays (non-VLA) * this value does not have to be determined at compile time! */ is = malloc(nbytes); diff --git a/userland/c/out_of_memory.c b/userland/c/malloc_max.c similarity index 78% rename from userland/c/out_of_memory.c rename to userland/c/malloc_max.c index 4135598..8eafb4c 100644 --- a/userland/c/out_of_memory.c +++ b/userland/c/malloc_max.c @@ -1,4 +1,4 @@ -/* https://cirosantilli.com/linux-kernel-module-cheat#malloc */ +/* https://cirosantilli.com/linux-kernel-module-cheat#malloc-maximum-size */ #include #include diff --git a/userland/linux/mmap_anonymous.c b/userland/linux/mmap_anonymous.c index 5ca8a29..1b8f1da 100644 --- a/userland/linux/mmap_anonymous.c +++ b/userland/linux/mmap_anonymous.c @@ -5,11 +5,20 @@ #include #include #include +#include #include -int main(void) { +int main(int argc, char **argv) { int *is; - size_t nbytes = 2 * sizeof(*is); + size_t nbytes, nints; + + /* Decide how many ints to allocate. */ + if (argc < 2) { + nints = 2; + } else { + nints = strtoull(argv[1], NULL, 0); + } + nbytes = nints * sizeof(*is); /* Allocate 2 ints. */ is = mmap(