1 /* See also https://bugs.kde.org/show_bug.cgi?id=432381. */
5 #include "../../config.h"
6 #if defined(VGO_darwin)
21 #define STACKSIZE (PTHREAD_STACK_MIN + 4096)
23 typedef struct threadlocal
{
28 static void sig_alrm_handler(int signo
) {
32 static void f(void *data
, int n
)
34 enum { NR_SWITCHES
= 200000 };
35 thread_local_t
*tlocal
= data
;
38 struct timespec delay
= { .tv_nsec
= 1000 };
39 nanosleep(&delay
, NULL
);
40 if (++tlocal
->nrsw
== NR_SWITCHES
)
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)
52 if (getcontext(&(tlocal
->uc
[2])) < 0)
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]);
75 int main(int argc
, char *argv
[])
78 thread_local_t tlocal
[NR
];
83 signal(SIGALRM
, sig_alrm_handler
);
84 memset(tlocal
, 0, sizeof(tlocal
));
86 pthread_attr_init(&attr
);
87 res
= pthread_attr_setstacksize(&attr
, STACKSIZE
);
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.
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
);