/* * start the push here */ static void stress_stackmmap_push_start(void) { /* stack for SEGV handler must not be on the stack */ static uint8_t stack_sig[SIGSTKSZ + STACK_ALIGNMENT]; struct sigaction new_action; /* * We need to handle SEGV signals when we * hit the end of the mmap'd stack; however * an alternative signal handling stack * is required because we ran out of stack */ (void)memset(&new_action, 0, sizeof new_action); new_action.sa_handler = stress_segvhandler; (void)sigemptyset(&new_action.sa_mask); new_action.sa_flags = SA_ONSTACK; if (sigaction(SIGSEGV, &new_action, NULL) < 0) return; /* * We need an alternative signal stack * to handle segfaults on an overrun * mmap'd stack */ (void)memset(stack_sig, 0, sizeof(stack_sig)); if (stress_sigaltstack(stack_sig, SIGSTKSZ) < 0) return; stress_stackmmap_push_msync(); }
/* * push values onto file backed mmap'd stack and * force msync on the map'd region if page boundary * has changed */ static void stress_stackmmap_push_msync(void) { void *addr = (void *)(((uintptr_t)&addr) & page_mask); static void *laddr; if (addr != laddr) { msync(addr, page_size, mwc8() >= 128 ? MS_SYNC : MS_ASYNC); laddr = addr; } if (opt_do_run) stress_stackmmap_push_msync(); }
/* * push values onto file backed mmap'd stack and * force msync on the map'd region if page boundary * has changed */ static void stress_stackmmap_push_msync(void) { void *addr = (void *)(((uintptr_t)&addr) & page_mask); static void *laddr; char waste[64]; waste[0] = 0; waste[sizeof(waste) - 1] = 0; if (addr != laddr) { (void)shim_msync(addr, page_size, (mwc8() & 1) ? MS_ASYNC : MS_SYNC); laddr = addr; } if (g_keep_stressing_flag) stress_stackmmap_push_msync(); }