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
16
// Counting semaphore.
20
pthread_mutex_t m_mutex;
21
pthread_cond_t m_cond;
25
void csema_ctr(struct csema* p)
27
memset(p, 0, sizeof(*p));
28
pthread_mutex_init(&p->m_mutex, 0);
29
pthread_cond_init(&p->m_cond, 0);
32
void csema_dtr(struct csema* p)
34
pthread_cond_destroy(&p->m_cond);
35
pthread_mutex_destroy(&p->m_mutex);
38
void csema_p(struct csema* p, const int n)
40
pthread_mutex_lock(&p->m_mutex);
41
while (p->m_count < n)
42
pthread_cond_wait(&p->m_cond, &p->m_mutex);
44
pthread_cond_signal(&p->m_cond);
45
pthread_mutex_unlock(&p->m_mutex);
48
void csema_v(struct csema* p)
50
pthread_mutex_lock(&p->m_mutex);
52
pthread_cond_signal(&p->m_cond);
53
pthread_mutex_unlock(&p->m_mutex);
64
void cthread_ctr(struct cthread* p)
70
void cthread_dtr(struct cthread* p)
76
static int s_debug = 0;
77
static int s_trace = 0;
78
static int s_signal_count;
79
static pthread_mutex_t s_mutex;
80
static pthread_cond_t s_cond;
83
// Function definitions.
85
static void thread_func(struct cthread* thread_info)
89
pthread_mutex_lock(&s_mutex);
91
for (i = 0; i < s_signal_count; i++)
95
printf("thread %d [%d] (1)\n", thread_info->m_threadnum, i);
97
csema_v(thread_info->m_sema);
99
// Wait until the main thread signals us via pthread_cond_broadcast().
100
pthread_cond_wait(&s_cond, &s_mutex);
103
printf("thread %d [%d] (2)\n", thread_info->m_threadnum, i);
107
pthread_mutex_unlock(&s_mutex);
110
int main(int argc, char** argv)
115
while ((optchar = getopt(argc, argv, "d")) != EOF)
127
s_signal_count = argc > optind ? atoi(argv[optind]) : 10;
128
thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10;
131
printf("&s_cond = %p\n", &s_cond);
133
pthread_mutex_init(&s_mutex, 0);
134
pthread_cond_init(&s_cond, 0);
139
struct cthread* thread_vec;
142
thread_vec = malloc(sizeof(struct cthread) * thread_count);
143
for (p = thread_vec; p != thread_vec + thread_count; p++)
146
p->m_threadnum = p - thread_vec;
148
pthread_create(&p->m_thread, 0,
149
(void*(*)(void*))thread_func, &*p);
151
for (i = 0; i < s_signal_count; i++)
154
printf("main [%d] (1)\n", i);
155
csema_p(&sema, thread_count);
157
printf("main [%d] (2)\n", i);
158
pthread_mutex_lock(&s_mutex);
159
pthread_cond_broadcast(&s_cond);
160
pthread_mutex_unlock(&s_mutex);
162
printf("main [%d] (3)\n", i);
164
for (i = 0; i < thread_count; i++)
166
pthread_join(thread_vec[i].m_thread, 0);
167
cthread_dtr(&thread_vec[i]);
172
pthread_cond_destroy(&s_cond);
173
pthread_mutex_destroy(&s_mutex);