■ ■ ■ ■ ■ ■
test/zdtm/transition/rseq01.c
| skipped 85 lines |
86 | 86 | | #endif |
87 | 87 | | /* EOF */ |
88 | 88 | | |
89 | | - | static volatile struct rseq *rseq_ptr; |
| 89 | + | static __thread volatile struct rseq *rseq_ptr; |
90 | 90 | | static __thread volatile struct rseq __rseq_abi; |
91 | 91 | | |
92 | 92 | | static int sys_rseq(volatile struct rseq *rseq_abi, uint32_t rseq_len, int flags, uint32_t sig) |
| skipped 26 lines |
119 | 119 | | |
120 | 120 | | #define rseq_after_asm_goto() asm volatile("" : : : "memory") |
121 | 121 | | |
122 | | - | static int rseq_addv(intptr_t *v, intptr_t count, int cpu, bool ignore_abort) |
| 122 | + | static int rseq_addv(intptr_t *v, intptr_t count, int cpu, bool ignore_abort, const char *id) |
123 | 123 | | { |
124 | 124 | | double a = 10000000000000000.0; |
125 | 125 | | double b = -1; |
| skipped 51 lines |
177 | 177 | | ); |
178 | 178 | | /* clang-format on */ |
179 | 179 | | rseq_after_asm_goto(); |
180 | | - | test_msg("exit %lx %lx %f %f\n", rseq_cs1, rseq_cs2, a, b); |
| 180 | + | test_msg("exit %s, %lx %lx %f %f\n", id, rseq_cs1, rseq_cs2, a, b); |
181 | 181 | | if (rseq_cs1 != rseq_cs2) { |
182 | 182 | | /* |
183 | 183 | | * It means that we finished critical section |
| skipped 8 lines |
192 | 192 | | return 0; |
193 | 193 | | abort: |
194 | 194 | | rseq_after_asm_goto(); |
195 | | - | test_msg("abort %lx %lx %f %f\n", rseq_cs1, rseq_cs2, a, b); |
| 195 | + | test_msg("abort %s, %lx %lx %f %f\n", id, rseq_cs1, rseq_cs2, a, b); |
196 | 196 | | if (ignore_abort) |
197 | 197 | | return 0; |
198 | 198 | | return -1; |
199 | 199 | | } |
200 | 200 | | |
| 201 | + | static task_waiter_t waiter; |
| 202 | + | static intptr_t *cpu_data; |
| 203 | + | bool ignore_abort = true; |
| 204 | + | int thread_ret; |
| 205 | + | |
| 206 | + | void *thread_routine(void *args) |
| 207 | + | { |
| 208 | + | int cpu; |
| 209 | + | |
| 210 | + | rseq_ptr = &__rseq_abi; |
| 211 | + | memset((void *)rseq_ptr, 0, sizeof(struct rseq)); |
| 212 | + | register_thread(); |
| 213 | + | task_waiter_complete(&waiter, 1); |
| 214 | + | task_waiter_wait4(&waiter, 2); |
| 215 | + | |
| 216 | + | while (test_go()) { |
| 217 | + | cpu = RSEQ_ACCESS_ONCE(rseq_ptr->cpu_id_start); |
| 218 | + | thread_ret = rseq_addv(&cpu_data[cpu], 2, cpu, ignore_abort, "thread"); |
| 219 | + | |
| 220 | + | if (thread_ret) |
| 221 | + | break; |
| 222 | + | } |
| 223 | + | |
| 224 | + | check_thread(); |
| 225 | + | return NULL; |
| 226 | + | } |
| 227 | + | |
201 | 228 | | int main(int argc, char *argv[]) |
202 | 229 | | { |
203 | 230 | | int cpu = 0; |
204 | 231 | | int ret; |
205 | | - | intptr_t *cpu_data; |
206 | 232 | | long nr_cpus; |
207 | | - | bool ignore_abort = true; |
| 233 | + | pthread_t thread; |
208 | 234 | | |
209 | 235 | | rseq_ptr = &__rseq_abi; |
210 | 236 | | memset((void *)rseq_ptr, 0, sizeof(struct rseq)); |
| skipped 22 lines |
233 | 259 | | RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE; |
234 | 260 | | #endif |
235 | 261 | | |
| 262 | + | task_waiter_init(&waiter); |
| 263 | + | if (pthread_create(&thread, NULL, thread_routine, NULL)) { |
| 264 | + | fail("pthread_create"); |
| 265 | + | exit(EXIT_FAILURE); |
| 266 | + | } |
| 267 | + | task_waiter_wait4(&waiter, 1); |
| 268 | + | |
236 | 269 | | test_daemon(); |
| 270 | + | task_waiter_complete(&waiter, 2); |
237 | 271 | | |
238 | 272 | | while (test_go()) { |
239 | 273 | | cpu = RSEQ_ACCESS_ONCE(rseq_ptr->cpu_id_start); |
240 | | - | ret = rseq_addv(&cpu_data[cpu], 2, cpu, ignore_abort); |
| 274 | + | ret = rseq_addv(&cpu_data[cpu], 2, cpu, ignore_abort, "task"); |
241 | 275 | | |
242 | 276 | | if (ret) |
243 | 277 | | break; |
244 | 278 | | } |
245 | | - | |
246 | | - | test_waitsig(); |
247 | 279 | | |
248 | 280 | | check_thread(); |
249 | 281 | | |
250 | | - | if (ret) |
| 282 | + | if (pthread_join(thread, NULL)) { |
| 283 | + | fail("pthread_join"); |
| 284 | + | exit(EXIT_FAILURE); |
| 285 | + | } |
| 286 | + | |
| 287 | + | if (ret || thread_ret) |
251 | 288 | | fail(); |
252 | 289 | | else |
253 | 290 | | pass(); |
| skipped 18 lines |