xref: /openbmc/qemu/tests/tcg/multiarch/munmap-pthread.c (revision aaa90fede5d10e2a3c3fc7f2df608128d2cba761)
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