1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Cyril Hrubis <chrubis@suse.cz> 4 */ 5 6 /* 7 * Test for callback thread safety. 8 */ 9 #include <pthread.h> 10 #include "tst_test.h" 11 12 #define THREADS 10 13 14 static pthread_barrier_t barrier; 15 setup(void)16 static void setup(void) 17 { 18 pthread_barrier_init(&barrier, NULL, THREADS); 19 20 tst_res(TINFO, "setup() executed"); 21 } 22 cleanup(void)23 static void cleanup(void) 24 { 25 static int flag; 26 27 /* Avoid subsequent threads to enter the cleanup */ 28 if (tst_atomic_inc(&flag) != 1) 29 pthread_exit(NULL); 30 31 tst_res(TINFO, "cleanup() started"); 32 usleep(10000); 33 tst_res(TINFO, "cleanup() finished"); 34 } 35 worker(void * id)36 static void *worker(void *id) 37 { 38 tst_res(TINFO, "Thread %ld waiting...", (long)id); 39 pthread_barrier_wait(&barrier); 40 tst_brk(TBROK, "Failure %ld", (long)id); 41 42 return NULL; 43 } 44 do_test(void)45 static void do_test(void) 46 { 47 long i; 48 pthread_t threads[THREADS]; 49 50 for (i = 0; i < THREADS; i++) 51 pthread_create(threads+i, NULL, worker, (void*)i); 52 53 for (i = 0; i < THREADS; i++) { 54 tst_res(TINFO, "Joining thread %li", i); 55 pthread_join(threads[i], NULL); 56 } 57 } 58 59 static struct tst_test test = { 60 .test_all = do_test, 61 .setup = setup, 62 .cleanup = cleanup, 63 }; 64