Skip to content

Commit 764a245

Browse files
jhawthornjeremyevans
authored andcommitted
Fix M:N threads under OpenBSD
OpenBSD requires MAP_STACK for memory regions used as thread stacks. However it seems to error with "Invalid argument" unless the permissions include both PROT_READ | PROT_WRITE. We should be able to satisft this by re-mmapping over our reserved stack region to get the MAP_STACK flag. As a (very minor) bonus, this applies MAP_STACK only to the machine stack region, not the VM region. Co-authored-by: Jeremy Evans <code@jeremyevans.net>
1 parent 21f2bbf commit 764a245

1 file changed

Lines changed: 8 additions & 7 deletions

File tree

thread_pthread_mn.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,7 @@ nt_thread_stack_size(void)
189189
static struct nt_stack_chunk_header *
190190
nt_alloc_thread_stack_chunk(void)
191191
{
192-
int mmap_flags = MAP_ANONYMOUS | MAP_PRIVATE;
193-
#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
194-
mmap_flags |= MAP_STACK;
195-
#endif
196-
197-
const char *m = (void *)mmap(NULL, MSTACK_CHUNK_SIZE, PROT_NONE, mmap_flags, -1, 0);
192+
const char *m = (void *)mmap(NULL, MSTACK_CHUNK_SIZE, PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
198193
if (m == MAP_FAILED) {
199194
return NULL;
200195
}
@@ -318,9 +313,15 @@ nt_alloc_stack(rb_vm_t *vm, void **vm_stack, void **machine_stack)
318313
char *stack_start = nt_stack_chunk_get_stack_start(ch, idx);
319314
size_t vm_stack_size = vm->default_params.thread_vm_stack_size;
320315
size_t mstack_size = nt_thread_stack_size() - vm_stack_size - MSTACK_PAGE_SIZE;
316+
char *mstack_start = stack_start + vm_stack_size + MSTACK_PAGE_SIZE;
317+
318+
int mstack_flags = MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE;
319+
#if defined(MAP_STACK) && !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
320+
mstack_flags |= MAP_STACK;
321+
#endif
321322

322323
if (mprotect(stack_start, vm_stack_size, PROT_READ | PROT_WRITE) != 0 ||
323-
mprotect(stack_start + vm_stack_size + MSTACK_PAGE_SIZE, mstack_size, PROT_READ | PROT_WRITE) != 0) {
324+
mmap(mstack_start, mstack_size, PROT_READ | PROT_WRITE, mstack_flags, -1, 0) == MAP_FAILED) {
324325
err = errno;
325326
}
326327
else {

0 commit comments

Comments
 (0)