I am writing code for a real-time program running in an embedded Linux system. As it is critical that we don’t stall unpredictably on page faults, I would like to prefault in the stack so that the region that we use is guaranteed to be covered by a mlockall() call.
For the main thread this is simple enough; simply do a few big alloca()s and make sure to do a write every few pages. This works because at program startup, the stack limit is much larger than the amount we need; we end up allocating exactly how much we prefault in.
However, for pthread stacks, will they be allocated using MAP_GROWSDOWN as well? If so, what’s the best way to prefault them in, considering that:
- We don’t know how much of the (known) stack size is consumed by libc startup
- We don’t want to allocate more memory to the stack than is necessary
I’m aware that I can use pthread_attr_setstack to pass in a manually-allocated stack, but this complicates cleaning up after the thread, and so I’d prefer to avoid this if possible.
As such, what’s the best way to perform this prefaulting? It would be sufficient if there was an easy way to find out the lower bound of the stack (just above the guard page); at this point I could simply write to every page from there to the current stack pointer.
Note that portability is not a concern; we’d be happy to have a solution that works only under x86-32 and Linux.
If you use
pthread_attr_setstacksizeyou can still have automatic allocation with a known size.glibc nptl leaves guard pages between the stacks, so you could also set a
SEGVhandler and simply scribble until you fault and thenlongjmpout of the loop. That’d be ugly!Edit: A really nonportable way would be to open
/proc/self/mapsto find your stacks!