Skip to content

Commit 36e5861

Browse files
committed
Reduce stack virtual memory consumption on Linux
1 parent cc8a9eb commit 36e5861

31 files changed

+582
-165
lines changed

examples/greenbean.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ int main(int argc, char *argv[]) {
337337
sigaddset(&block, SIGQUIT);
338338
pthread_attr_t attr;
339339
unassert(!pthread_attr_init(&attr));
340-
unassert(!pthread_attr_setstacksize(&attr, 65536));
340+
unassert(!pthread_attr_setstacksize(&attr, 65536 - getpagesize()));
341341
unassert(!pthread_attr_setguardsize(&attr, getpagesize()));
342342
unassert(!pthread_attr_setsigmask_np(&attr, &block));
343343
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0));

examples/stackexplorer.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
88
╚─────────────────────────────────────────────────────────────────*/
99
#endif
10+
#include "libc/dce.h"
11+
#include "libc/intrin/maps.h"
1012
#include "libc/mem/alg.h"
1113
#include "libc/mem/mem.h"
1214
#include "libc/runtime/runtime.h"
15+
#include "libc/runtime/stack.h"
16+
#include "libc/runtime/winargs.internal.h"
1317
#include "libc/stdio/stdio.h"
1418
#include "libc/x/xasprintf.h"
1519

@@ -67,8 +71,18 @@ int main(int argc, char *argv[]) {
6771
Append((uintptr_t)&__auxv[i + 1],
6872
xasprintf("&auxv[%d] = %#lx", i + 1, __auxv[i + 1]));
6973
}
74+
if (!IsWindows()) {
75+
struct AddrSize stak = __get_main_stack();
76+
Append((intptr_t)stak.addr + stak.size, "top of stack");
77+
Append((intptr_t)stak.addr, "bottom of stack");
78+
} else {
79+
#ifdef __x86_64__
80+
Append(GetStaticStackAddr(0) + GetStaticStackSize(), "top of stack");
81+
Append(GetStaticStackAddr(0) + GetGuardSize(), "bottom of stack");
82+
Append(GetStaticStackAddr(0), "bottom of guard region");
83+
#endif
84+
}
7085
qsort(things.p, things.n, sizeof(*things.p), Compare);
71-
for (int i = 0; i < things.n; ++i) {
86+
for (int i = 0; i < things.n; ++i)
7287
printf("%012lx %s\n", things.p[i].i, things.p[i].s);
73-
}
7488
}

examples/thread.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <pthread.h>
2+
#include <stdio.h>
3+
4+
// how to spawn a thread
5+
6+
void *my_thread(void *arg) {
7+
printf("my_thread(%p) is running\n", arg);
8+
return (void *)0x456L;
9+
}
10+
11+
int main(int argc, char *argv[]) {
12+
void *res;
13+
pthread_t th;
14+
pthread_create(&th, 0, my_thread, (void *)0x123L);
15+
pthread_join(th, &res);
16+
printf("my_thread() returned %p\n", res);
17+
}

libc/calls/getrlimit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "libc/calls/syscall-sysv.internal.h"
2222
#include "libc/dce.h"
2323
#include "libc/intrin/describeflags.h"
24+
#include "libc/intrin/rlimit.h"
2425
#include "libc/intrin/strace.h"
2526
#include "libc/runtime/runtime.h"
2627
#include "libc/runtime/stack.h"
@@ -47,8 +48,7 @@ int getrlimit(int resource, struct rlimit *rlim) {
4748
} else if (!IsWindows()) {
4849
rc = sys_getrlimit(resource, rlim);
4950
} else if (resource == RLIMIT_STACK) {
50-
rlim->rlim_cur = GetStaticStackSize();
51-
rlim->rlim_max = GetStaticStackSize();
51+
*rlim = __rlimit_stack_get();
5252
rc = 0;
5353
} else if (resource == RLIMIT_AS) {
5454
rlim->rlim_cur = __virtualmax;

libc/calls/setrlimit.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "libc/dce.h"
2424
#include "libc/errno.h"
2525
#include "libc/intrin/describeflags.h"
26+
#include "libc/intrin/rlimit.h"
2627
#include "libc/intrin/strace.h"
2728
#include "libc/macros.h"
2829
#include "libc/runtime/runtime.h"
@@ -88,10 +89,12 @@ int setrlimit(int resource, const struct rlimit *rlim) {
8889
} else if (!IsWindows() && !(IsNetbsd() && resource == RLIMIT_AS)) {
8990
rc = sys_setrlimit(resource, rlim);
9091
} else if (resource == RLIMIT_STACK) {
91-
rc = enotsup();
92+
rc = 0;
9293
} else {
9394
rc = einval();
9495
}
96+
if (!rc && resource == RLIMIT_STACK)
97+
__rlimit_stack_set(*rlim); // so __rlimit_stack_get() works on all OSes
9598
if (resource == RLIMIT_AS) {
9699
__virtualmax = rlim->rlim_cur;
97100
errno = olde;

libc/cosmo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ int cosmo_futex_wake(_COSMO_ATOMIC(int) *, int, char);
2525
int cosmo_futex_wait(_COSMO_ATOMIC(int) *, int, char, int,
2626
const struct timespec *);
2727

28-
errno_t cosmo_stack_alloc(unsigned *, unsigned *, void **) libcesque;
29-
errno_t cosmo_stack_free(void *, unsigned, unsigned) libcesque;
28+
errno_t cosmo_stack_alloc(size_t *, size_t *, void **) libcesque;
29+
errno_t cosmo_stack_free(void *, size_t, size_t) libcesque;
3030
void cosmo_stack_clear(void) libcesque;
3131
void cosmo_stack_setmaxstacks(int) libcesque;
3232
int cosmo_stack_getmaxstacks(void) libcesque;

libc/intrin/describemapflags.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,29 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/dce.h"
1920
#include "libc/intrin/describeflags.h"
2021
#include "libc/macros.h"
2122
#include "libc/nt/enum/consolemodeflags.h"
2223
#include "libc/sysv/consts/map.h"
2324
#include "libc/sysv/consts/prot.h"
2425

26+
#define MAP_GROWSDOWN_LINUX 0x00000100
27+
2528
const char *_DescribeMapFlags(char buf[64], int x) {
2629
const struct DescribeFlags kMapFlags[] = {
27-
{MAP_PRIVATE, "PRIVATE"}, //
28-
{MAP_ANONYMOUS, "ANONYMOUS"}, //
29-
{MAP_SHARED, "SHARED"}, //
30-
{MAP_FIXED, "FIXED"}, //
31-
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
32-
{MAP_HUGETLB, "HUGETLB"}, //
33-
{MAP_CONCEAL, "CONCEAL"}, //
34-
{MAP_LOCKED, "LOCKED"}, //
35-
{MAP_NORESERVE, "NORESERVE"}, //
36-
{MAP_NONBLOCK, "NONBLOCK"}, //
37-
{MAP_POPULATE, "POPULATE"}, //
30+
{MAP_PRIVATE, "PRIVATE"}, //
31+
{MAP_ANONYMOUS, "ANONYMOUS"}, //
32+
{MAP_SHARED, "SHARED"}, //
33+
{MAP_FIXED, "FIXED"}, //
34+
{MAP_FIXED_NOREPLACE, "FIXED_NOREPLACE"}, //
35+
{MAP_HUGETLB, "HUGETLB"}, //
36+
{MAP_CONCEAL, "CONCEAL"}, //
37+
{MAP_LOCKED, "LOCKED"}, //
38+
{MAP_NORESERVE, "NORESERVE"}, //
39+
{MAP_NONBLOCK, "NONBLOCK"}, //
40+
{MAP_POPULATE, "POPULATE"}, //
41+
{IsLinux() ? MAP_GROWSDOWN_LINUX : 0, "GROWSDOWN"}, //
3842
};
3943
return _DescribeFlags(buf, 64, kMapFlags, ARRAYLEN(kMapFlags), "MAP_", x);
4044
}

libc/intrin/describeprotflags.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
#include "libc/sysv/consts/prot.h"
2222

2323
const char *_DescribeProtFlags(char buf[48], int x) {
24+
if (!x)
25+
return "PROT_NONE";
2426
const struct DescribeFlags kProtFlags[] = {
2527
{PROT_READ, "READ"}, //
2628
{PROT_WRITE, "WRITE"}, //

libc/intrin/getmainstack.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/struct/rlimit.h"
20-
#include "libc/calls/struct/rlimit.internal.h"
21-
#include "libc/dce.h"
2220
#include "libc/intrin/getauxval.h"
23-
#include "libc/intrin/kprintf.h"
2421
#include "libc/intrin/maps.h"
22+
#include "libc/intrin/rlimit.h"
2523
#include "libc/macros.h"
2624
#include "libc/runtime/runtime.h"
25+
#include "libc/stdio/sysparam.h"
2726
#include "libc/sysv/consts/auxv.h"
28-
#include "libc/sysv/consts/rlim.h"
29-
#include "libc/sysv/consts/rlimit.h"
3027

3128
// Hack for guessing boundaries of _start()'s stack
3229
//
@@ -91,12 +88,9 @@ static uintptr_t __get_main_top(int pagesz) {
9188
}
9289

9390
static size_t __get_stack_size(int pagesz, uintptr_t start, uintptr_t top) {
94-
size_t size, max = 8 * 1024 * 1024;
95-
struct rlimit rlim = {RLIM_INFINITY};
96-
sys_getrlimit(RLIMIT_STACK, &rlim);
97-
if ((size = rlim.rlim_cur) > max)
98-
size = max;
99-
return MAX(ROUNDUP(size, pagesz), ROUNDUP(top - start, pagesz));
91+
size_t stacksz = __rlimit_stack_get().rlim_cur;
92+
stacksz = MIN(stacksz, 1024ul * 1024 * 1024 * 1024);
93+
return MAX(ROUNDDOWN(stacksz, pagesz), ROUNDUP(top - start, pagesz));
10094
}
10195

10296
/**
File renamed without changes.

0 commit comments

Comments
 (0)