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
17 // Counting semaphore.
21 pthread_mutex_t m_mutex
;
22 pthread_cond_t m_cond
;
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
);
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
);
53 pthread_cond_signal(&p
->m_cond
);
54 pthread_mutex_unlock(&p
->m_mutex
);
65 void cthread_ctr(struct cthread
* p
)
71 void cthread_dtr(struct cthread
* p
)
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
;
91 pthread_mutex_lock(&s_mutex
);
93 for (i
= 0; i
< s_signal_count
; i
++)
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
);
105 printf("thread %d [%d] (2)\n", thread_info
->m_threadnum
, i
);
109 pthread_mutex_unlock(&s_mutex
);
114 int main(int argc
, char** argv
)
119 while ((optchar
= getopt(argc
, argv
, "d")) != EOF
)
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. */
136 s_signal_count
= argc
> optind
? atoi(argv
[optind
]) : 10;
137 thread_count
= argc
> optind
+ 1 ? atoi(argv
[optind
+ 1]) : 10;
140 printf("&s_cond = %p\n", &s_cond
);
142 pthread_mutex_init(&s_mutex
, 0);
143 pthread_cond_init(&s_cond
, 0);
148 struct cthread
* thread_vec
;
151 thread_vec
= malloc(sizeof(struct cthread
) * thread_count
);
152 for (p
= thread_vec
; p
!= thread_vec
+ thread_count
; p
++)
155 p
->m_threadnum
= p
- thread_vec
;
157 pthread_create(&p
->m_thread
, 0, thread_func
, &*p
);
159 for (i
= 0; i
< s_signal_count
; i
++)
162 printf("main [%d] (1)\n", i
);
163 csema_p(&sema
, thread_count
);
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
);
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
]);
180 pthread_cond_destroy(&s_cond
);
181 pthread_mutex_destroy(&s_mutex
);
183 fprintf(stderr
, "Done.\n");