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 */ 7 8 9 #include <assert.h> 10 #include <pthread.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 #include <unistd.h> 15 16 17 // Counting semaphore. 18 19 struct csema 20 { 21 pthread_mutex_t m_mutex; 22 pthread_cond_t m_cond; 23 int m_count; 24 }; 25 26 void csema_ctr(struct csema* p) 27 { 28 memset(p, 0, sizeof(*p)); 29 pthread_mutex_init(&p->m_mutex, 0); 30 pthread_cond_init(&p->m_cond, 0); 31 } 32 33 void csema_dtr(struct csema* p) 34 { 35 pthread_cond_destroy(&p->m_cond); 36 pthread_mutex_destroy(&p->m_mutex); 37 } 38 39 void csema_p(struct csema* p, const int n) 40 { 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); 47 } 48 49 void csema_v(struct csema* p) 50 { 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); 55 } 56 57 58 struct cthread 59 { 60 pthread_t m_thread; 61 int m_threadnum; 62 struct csema* m_sema; 63 }; 64 65 void cthread_ctr(struct cthread* p) 66 { 67 p->m_thread = 0; 68 p->m_sema = 0; 69 } 70 71 void cthread_dtr(struct cthread* p) 72 { } 73 74 75 // Local variables. 76 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; 82 83 84 // Function definitions. 85 86 static void thread_func(struct cthread* thread_info) 87 { 88 int i; 89 90 pthread_mutex_lock(&s_mutex); 91 92 for (i = 0; i < s_signal_count; i++) 93 { 94 if (s_trace) 95 { 96 printf("thread %d [%d] (1)\n", thread_info->m_threadnum, i); 97 } 98 csema_v(thread_info->m_sema); 99 100 // Wait until the main thread signals us via pthread_cond_broadcast(). 101 pthread_cond_wait(&s_cond, &s_mutex); 102 if (s_trace) 103 { 104 printf("thread %d [%d] (2)\n", thread_info->m_threadnum, i); 105 } 106 } 107 108 pthread_mutex_unlock(&s_mutex); 109 } 110 111 int main(int argc, char** argv) 112 { 113 int optchar; 114 int thread_count; 115 116 while ((optchar = getopt(argc, argv, "d")) != EOF) 117 { 118 switch (optchar) 119 { 120 case 'd': 121 s_debug = 1; 122 break; 123 default: 124 assert(0); 125 break; 126 } 127 } 128 129 /* This test should complete in 15s or less. If the test does not complete */ 130 /* within that time, abort the test via the signal SIGALRM. */ 131 alarm(100); 132 133 s_signal_count = argc > optind ? atoi(argv[optind]) : 10; 134 thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10; 135 136 if (s_debug) 137 printf("&s_cond = %p\n", &s_cond); 138 139 pthread_mutex_init(&s_mutex, 0); 140 pthread_cond_init(&s_cond, 0); 141 { 142 int i; 143 struct csema sema; 144 struct cthread* p; 145 struct cthread* thread_vec; 146 147 csema_ctr(&sema); 148 thread_vec = malloc(sizeof(struct cthread) * thread_count); 149 for (p = thread_vec; p != thread_vec + thread_count; p++) 150 { 151 cthread_ctr(p); 152 p->m_threadnum = p - thread_vec; 153 p->m_sema = &sema; 154 pthread_create(&p->m_thread, 0, 155 (void*(*)(void*))thread_func, &*p); 156 } 157 for (i = 0; i < s_signal_count; i++) 158 { 159 if (s_trace) 160 printf("main [%d] (1)\n", i); 161 csema_p(&sema, thread_count); 162 if (s_trace) 163 printf("main [%d] (2)\n", i); 164 pthread_mutex_lock(&s_mutex); 165 pthread_cond_broadcast(&s_cond); 166 pthread_mutex_unlock(&s_mutex); 167 if (s_trace) 168 printf("main [%d] (3)\n", i); 169 } 170 for (i = 0; i < thread_count; i++) 171 { 172 pthread_join(thread_vec[i].m_thread, 0); 173 cthread_dtr(&thread_vec[i]); 174 } 175 free(thread_vec); 176 csema_dtr(&sema); 177 } 178 pthread_cond_destroy(&s_cond); 179 pthread_mutex_destroy(&s_mutex); 180 181 fprintf(stderr, "Done.\n"); 182 183 return 0; 184 } 185