183d92559SIlya Leoshkevich /* Test that munmap() and thread creation do not race. */
283d92559SIlya Leoshkevich #include <assert.h>
383d92559SIlya Leoshkevich #include <pthread.h>
483d92559SIlya Leoshkevich #include <stdbool.h>
583d92559SIlya Leoshkevich #include <stdlib.h>
683d92559SIlya Leoshkevich #include <string.h>
783d92559SIlya Leoshkevich #include <sys/mman.h>
883d92559SIlya Leoshkevich #include <unistd.h>
983d92559SIlya Leoshkevich
10*d4846c33SIlya Leoshkevich #include "nop_func.h"
1183d92559SIlya Leoshkevich
thread_mmap_munmap(void * arg)1283d92559SIlya Leoshkevich static void *thread_mmap_munmap(void *arg)
1383d92559SIlya Leoshkevich {
1483d92559SIlya Leoshkevich volatile bool *run = arg;
1583d92559SIlya Leoshkevich char *p;
1683d92559SIlya Leoshkevich int ret;
1783d92559SIlya Leoshkevich
1883d92559SIlya Leoshkevich while (*run) {
1983d92559SIlya Leoshkevich p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC,
2083d92559SIlya Leoshkevich MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
2183d92559SIlya Leoshkevich assert(p != MAP_FAILED);
2283d92559SIlya Leoshkevich
2383d92559SIlya Leoshkevich /* Create a small translation block. */
2483d92559SIlya Leoshkevich memcpy(p, nop_func, sizeof(nop_func));
2583d92559SIlya Leoshkevich ((void(*)(void))p)();
2683d92559SIlya Leoshkevich
2783d92559SIlya Leoshkevich ret = munmap(p, getpagesize());
2883d92559SIlya Leoshkevich assert(ret == 0);
2983d92559SIlya Leoshkevich }
3083d92559SIlya Leoshkevich
3183d92559SIlya Leoshkevich return NULL;
3283d92559SIlya Leoshkevich }
3383d92559SIlya Leoshkevich
thread_dummy(void * arg)3483d92559SIlya Leoshkevich static void *thread_dummy(void *arg)
3583d92559SIlya Leoshkevich {
3683d92559SIlya Leoshkevich return NULL;
3783d92559SIlya Leoshkevich }
3883d92559SIlya Leoshkevich
main(void)3983d92559SIlya Leoshkevich int main(void)
4083d92559SIlya Leoshkevich {
4183d92559SIlya Leoshkevich pthread_t mmap_munmap, dummy;
4283d92559SIlya Leoshkevich volatile bool run = true;
4383d92559SIlya Leoshkevich int i, ret;
4483d92559SIlya Leoshkevich
4583d92559SIlya Leoshkevich /* Without a template, nothing to test. */
4683d92559SIlya Leoshkevich if (sizeof(nop_func) == 0) {
4783d92559SIlya Leoshkevich return EXIT_SUCCESS;
4883d92559SIlya Leoshkevich }
4983d92559SIlya Leoshkevich
5083d92559SIlya Leoshkevich ret = pthread_create(&mmap_munmap, NULL, thread_mmap_munmap, (void *)&run);
5183d92559SIlya Leoshkevich assert(ret == 0);
5283d92559SIlya Leoshkevich
5383d92559SIlya Leoshkevich for (i = 0; i < 1000; i++) {
5483d92559SIlya Leoshkevich ret = pthread_create(&dummy, NULL, thread_dummy, NULL);
5583d92559SIlya Leoshkevich assert(ret == 0);
5683d92559SIlya Leoshkevich ret = pthread_join(dummy, NULL);
5783d92559SIlya Leoshkevich assert(ret == 0);
5883d92559SIlya Leoshkevich }
5983d92559SIlya Leoshkevich
6083d92559SIlya Leoshkevich run = false;
6183d92559SIlya Leoshkevich ret = pthread_join(mmap_munmap, NULL);
6283d92559SIlya Leoshkevich assert(ret == 0);
6383d92559SIlya Leoshkevich
6483d92559SIlya Leoshkevich return EXIT_SUCCESS;
6583d92559SIlya Leoshkevich }
66