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
);