Helgrind: add suppression for libnss from getaddrinfo
[valgrind.git] / drd / tests / pth_broadcast.c
blob21ff4ca1cd654170b61173460042fb14ccdffd11
1 /** Broadcast a (POSIX threads) signal to all running threads, where the
2 * number of threads can be specified on the command line. This test program
3 * is intended not only to test the correctness of drd but also to test
4 * whether performance does not degrade too much when the number of threads
5 * increases.
6 */
9 #include <assert.h>
10 #include <pthread.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
17 // Counting semaphore.
19 struct csema
21 pthread_mutex_t m_mutex;
22 pthread_cond_t m_cond;
23 int m_count;
26 void csema_ctr(struct csema* p)
28 memset(p, 0, sizeof(*p));
29 pthread_mutex_init(&p->m_mutex, 0);
30 pthread_cond_init(&p->m_cond, 0);
33 void csema_dtr(struct csema* p)
35 pthread_cond_destroy(&p->m_cond);
36 pthread_mutex_destroy(&p->m_mutex);
39 void csema_p(struct csema* p, const int n)
41 pthread_mutex_lock(&p->m_mutex);
42 while (p->m_count < n)
43 pthread_cond_wait(&p->m_cond, &p->m_mutex);
44 p->m_count -= n;
45 pthread_cond_signal(&p->m_cond);
46 pthread_mutex_unlock(&p->m_mutex);
49 void csema_v(struct csema* p)
51 pthread_mutex_lock(&p->m_mutex);
52 p->m_count++;
53 pthread_cond_signal(&p->m_cond);
54 pthread_mutex_unlock(&p->m_mutex);
58 struct cthread
60 pthread_t m_thread;
61 int m_threadnum;
62 struct csema* m_sema;
65 void cthread_ctr(struct cthread* p)
67 p->m_thread = 0;
68 p->m_sema = 0;
71 void cthread_dtr(struct cthread* p)
72 { }
75 // Local variables.
77 static int s_debug = 0;
78 static int s_trace = 0;
79 static int s_signal_count;
80 static pthread_mutex_t s_mutex;
81 static pthread_cond_t s_cond;
84 // Function definitions.
86 static void *thread_func(void *arg)
88 struct cthread* thread_info = arg;
89 int i;
91 pthread_mutex_lock(&s_mutex);
93 for (i = 0; i < s_signal_count; i++)
95 if (s_trace)
97 printf("thread %d [%d] (1)\n", thread_info->m_threadnum, i);
99 csema_v(thread_info->m_sema);
101 // Wait until the main thread signals us via pthread_cond_broadcast().
102 pthread_cond_wait(&s_cond, &s_mutex);
103 if (s_trace)
105 printf("thread %d [%d] (2)\n", thread_info->m_threadnum, i);
109 pthread_mutex_unlock(&s_mutex);
111 return NULL;
114 int main(int argc, char** argv)
116 int optchar;
117 int thread_count;
119 while ((optchar = getopt(argc, argv, "d")) != EOF)
121 switch (optchar)
123 case 'd':
124 s_debug = 1;
125 break;
126 default:
127 assert(0);
128 break;
132 /* This test should complete in 15s or less. If the test does not complete */
133 /* within that time, abort the test via the signal SIGALRM. */
134 alarm(100);
136 s_signal_count = argc > optind ? atoi(argv[optind]) : 10;
137 thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10;
139 if (s_debug)
140 printf("&s_cond = %p\n", &s_cond);
142 pthread_mutex_init(&s_mutex, 0);
143 pthread_cond_init(&s_cond, 0);
145 int i;
146 struct csema sema;
147 struct cthread* p;
148 struct cthread* thread_vec;
150 csema_ctr(&sema);
151 thread_vec = malloc(sizeof(struct cthread) * thread_count);
152 for (p = thread_vec; p != thread_vec + thread_count; p++)
154 cthread_ctr(p);
155 p->m_threadnum = p - thread_vec;
156 p->m_sema = &sema;
157 pthread_create(&p->m_thread, 0, thread_func, &*p);
159 for (i = 0; i < s_signal_count; i++)
161 if (s_trace)
162 printf("main [%d] (1)\n", i);
163 csema_p(&sema, thread_count);
164 if (s_trace)
165 printf("main [%d] (2)\n", i);
166 pthread_mutex_lock(&s_mutex);
167 pthread_cond_broadcast(&s_cond);
168 pthread_mutex_unlock(&s_mutex);
169 if (s_trace)
170 printf("main [%d] (3)\n", i);
172 for (i = 0; i < thread_count; i++)
174 pthread_join(thread_vec[i].m_thread, 0);
175 cthread_dtr(&thread_vec[i]);
177 free(thread_vec);
178 csema_dtr(&sema);
180 pthread_cond_destroy(&s_cond);
181 pthread_mutex_destroy(&s_mutex);
183 fprintf(stderr, "Done.\n");
185 return 0;