memcheck/tests/sh-mem-random.c: Set huge_addr to 240GB
[valgrind.git] / drd / tests / swapcontext.c
blobec191968cab17c407c058b4399fbdb4da700ce6d
1 /* See also https://bugs.kde.org/show_bug.cgi?id=432381. */
3 #define _GNU_SOURCE
5 #include "../../config.h"
6 #if defined(VGO_darwin)
7 #define _XOPEN_SOURCE
8 #endif
10 #include <assert.h>
11 #include <limits.h>
12 #include <pthread.h>
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/time.h>
17 #include <ucontext.h>
18 #include <unistd.h>
19 #include "valgrind.h"
21 #define STACKSIZE (PTHREAD_STACK_MIN + 4096)
23 typedef struct threadlocal {
24 ucontext_t uc[3];
25 size_t nrsw;
26 } thread_local_t;
28 static void sig_alrm_handler(int signo) {
29 _exit(1);
32 static void f(void *data, int n)
34 enum { NR_SWITCHES = 200000 };
35 thread_local_t *tlocal = data;
37 while (1) {
38 struct timespec delay = { .tv_nsec = 1000 };
39 nanosleep(&delay, NULL);
40 if (++tlocal->nrsw == NR_SWITCHES)
41 return;
42 swapcontext(&tlocal->uc[n], &tlocal->uc[3 - n]);
46 void *worker(void *data)
48 thread_local_t *tlocal = data;
50 if (getcontext(&(tlocal->uc[1])) < 0)
51 abort();
52 if (getcontext(&(tlocal->uc[2])) < 0)
53 abort();
55 tlocal->uc[1].uc_link = &tlocal->uc[0];
56 tlocal->uc[1].uc_stack.ss_sp = malloc(STACKSIZE);
57 tlocal->uc[1].uc_stack.ss_size = STACKSIZE;
58 makecontext(&tlocal->uc[1], (void (*)(void))f, 2, tlocal, 1);
59 (void)VALGRIND_STACK_REGISTER(tlocal->uc[1].uc_stack.ss_sp,
60 tlocal->uc[1].uc_stack.ss_sp +
61 tlocal->uc[1].uc_stack.ss_size);
63 tlocal->uc[2].uc_link = &tlocal->uc[0];
64 tlocal->uc[2].uc_stack.ss_sp = malloc(STACKSIZE);
65 tlocal->uc[2].uc_stack.ss_size = STACKSIZE;
66 makecontext(&tlocal->uc[2], (void (*)(void))f, 2, tlocal, 2);
67 (void)VALGRIND_STACK_REGISTER(tlocal->uc[2].uc_stack.ss_sp,
68 tlocal->uc[2].uc_stack.ss_sp +
69 tlocal->uc[2].uc_stack.ss_size);
71 swapcontext(&tlocal->uc[0], &tlocal->uc[1]);
72 return NULL;
75 int main(int argc, char *argv[])
77 enum { NR = 32 };
78 thread_local_t tlocal[NR];
79 pthread_t thread[NR];
80 pthread_attr_t attr;
81 int i, res;
83 signal(SIGALRM, sig_alrm_handler);
84 memset(tlocal, 0, sizeof(tlocal));
86 pthread_attr_init(&attr);
87 res = pthread_attr_setstacksize(&attr, STACKSIZE);
88 assert(res == 0);
90 for (i = 0; i < NR; i++)
91 pthread_create(&thread[i], &attr, worker, &tlocal[i]);
93 pthread_attr_destroy(&attr);
95 // Wait until the threads have been created.
96 sleep(1);
97 for (i = 0; i < NR; i++)
98 pthread_kill(thread[i], SIGALRM);
100 for (i = 0; i < NR; i++)
101 pthread_join(thread[i], NULL);
103 return 0;