2 /* { dg-require-effective-target split_stack } */
3 /* { dg-require-effective-target pthread_h } */
4 /* { dg-require-effective-target ucontext_h } */
5 /* { dg-options "-pthread -fsplit-stack" } */
11 extern void __splitstack_getcontext (void *context[10]);
13 extern void __splitstack_setcontext (void *context[10]);
15 extern void *__splitstack_makecontext (size_t, void *context[10], size_t *);
17 extern void __splitstack_block_signals (int *, int *);
19 extern void __splitstack_block_signals_context (void *context[10], int *,
22 extern void *__splitstack_find (void *, void *, size_t *, void **, void **,
25 extern void *__splitstack_find_context (void *context[10], size_t *, void **,
34 static void swap (ucontext_t *, void *fs[10], ucontext_t *, void *ts[10])
35 __attribute__ ((no_split_stack));
38 swap (ucontext_t *fu, void *fs[10], ucontext_t *tu, void *ts[10])
40 __splitstack_getcontext (fs);
41 __splitstack_setcontext (ts);
43 __splitstack_setcontext (fs);
46 /* Use a noinline function to ensure that the buffer is not removed
48 static void use_buffer (char *buf) __attribute__ ((noinline));
50 use_buffer (char *buf)
56 down (int i, const char *msg, ucontext_t *me, void *mes[10],
57 ucontext_t *other, void *others[10])
64 swap (me, mes, other, others);
65 down (i - 1, msg, me, mes, other, others);
72 void *next_segment = NULL;
74 void *initial_sp = NULL;
76 stack = __splitstack_find_context (mes, &stack_size, &next_segment,
77 &next_sp, &initial_sp);
81 while (__splitstack_find (next_segment, next_sp, &stack_size,
82 &next_segment, &next_sp, &initial_sp)
92 down (1000, "go1", &c1, s1, &c2, s2);
99 down (1000, "go2", &c2, s2, &c1, s1);
103 struct thread_context
109 static void *start_thread (void *) __attribute__ ((no_split_stack));
112 start_thread (void *context)
114 struct thread_context *tc = (struct thread_context *) context;
118 __splitstack_block_signals (&block, NULL);
119 __splitstack_setcontext (tc->s);
125 main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
130 struct thread_context tc;
133 if (getcontext (&c1) < 0)
138 c1.uc_stack.ss_sp = __splitstack_makecontext (8192, &s1[0], &size);
139 if (c1.uc_stack.ss_sp == NULL)
141 c1.uc_stack.ss_flags = 0;
142 c1.uc_stack.ss_size = size;
145 __splitstack_block_signals_context (&s1[0], &block, NULL);
146 makecontext (&c1, go1, 0);
148 c2.uc_stack.ss_sp = __splitstack_makecontext (8192, &s2[0], &size);
149 if (c2.uc_stack.ss_sp == NULL)
151 c2.uc_stack.ss_flags = 0;
152 c2.uc_stack.ss_size = size;
154 __splitstack_block_signals_context (&s2[0], &block, NULL);
155 makecontext (&c2, go2, 0);
158 __splitstack_block_signals (&block, NULL);
162 err = pthread_create (&tid, NULL, start_thread, &tc);
166 err = pthread_join (tid, NULL);