• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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