From 1d82010e42b40e196cc6d879a835e028ae2faf89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=81ojek?= Date: Sat, 13 Dec 2025 10:38:51 +0100 Subject: [PATCH 1/2] Fix fcontext stack size on 64KiB pages --- src/nle.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/nle.c b/src/nle.c index 67276dc84..b393c179f 100644 --- a/src/nle.c +++ b/src/nle.c @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -22,6 +23,23 @@ #define STACK_SIZE (1 << 16) /* 64KiB */ +static size_t +effective_stack_size(void) +{ + /* create_fcontext_stack() uses the first page as a guard page. + * + * On systems with 64KiB pages (e.g. some aarch64 kernels), STACK_SIZE=64KiB + * results in a single page mapping, leaving no usable stack space after + * the guard page. Ensure at least 2 pages (guard + usable). + */ + size_t stack_size = STACK_SIZE; + long page_size = sysconf(_SC_PAGESIZE); + if (page_size > 0 && stack_size < 2u * (size_t) page_size) { + stack_size = 2u * (size_t) page_size; + } + return stack_size; +} + #ifndef __has_feature #define __has_feature(x) 0 /* Compatibility with non-clang compilers. */ #endif @@ -402,7 +420,7 @@ nle_start(nle_obs *obs, FILE *ttyrec, nle_settings *settings_p) /* Initialise the level generation RNG */ nle_init_lgen_rng(); - nle->stack = create_fcontext_stack(STACK_SIZE); + nle->stack = create_fcontext_stack(effective_stack_size()); nle->generatorcontext = make_fcontext(nle->stack.sptr, nle->stack.ssize, mainloop); From 1ff5cda2ff3f2b72306d5f819970e68d5df381f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C5=81ojek?= Date: Sun, 14 Dec 2025 22:07:25 +0100 Subject: [PATCH 2/2] Format src/nle.c for clang-format --- src/nle.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nle.c b/src/nle.c index b393c179f..07f315083 100644 --- a/src/nle.c +++ b/src/nle.c @@ -1,8 +1,8 @@ #include #include -#include #include +#include #include @@ -28,9 +28,10 @@ effective_stack_size(void) { /* create_fcontext_stack() uses the first page as a guard page. * - * On systems with 64KiB pages (e.g. some aarch64 kernels), STACK_SIZE=64KiB - * results in a single page mapping, leaving no usable stack space after - * the guard page. Ensure at least 2 pages (guard + usable). + * On systems with 64KiB pages (e.g. some aarch64 kernels), + * STACK_SIZE=64KiB results in a single page mapping, leaving no usable + * stack space after the guard page. Ensure at least 2 pages (guard + + * usable). */ size_t stack_size = STACK_SIZE; long page_size = sysconf(_SC_PAGESIZE);