8 # if !defined(NO_CONFIG_H)
11 # include <semaphore.h>
13 # define inline _inline
14 # include "../../src/windows/platform.h"
15 # include "posix_semaphore.h"
17 #include "../../src/private.h"
22 # define err(rc,msg,...) do { perror(msg); exit(rc); } while (0)
23 # define errx(rc,msg,...) do { puts(msg); exit(rc); } while (0)
26 #include <pthread_workqueue.h>
30 /* If non-zero, extra debugging statements will be printed */
33 static sem_t test_complete;
34 static int test_rounds;
36 #define dbg_puts(s) if (dbg) puts(s)
38 #define dbg_printf(fmt,...) if (dbg) fprintf(stderr, fmt, __VA_ARGS__)
40 void additem(pthread_workqueue_t wq, void (*func)(void *),
46 rv = pthread_workqueue_additem_np(wq, *func, arg, NULL, NULL);
48 errx(1, "unable to add item: %s", strerror(rv));
49 dbg_puts("added item\n");
55 static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
57 pthread_mutex_lock(&mtx);
59 pthread_mutex_unlock(&mtx);
61 dbg_printf("rounds = %d\n", test_rounds);
62 if (test_rounds == 0) {
63 sem_post(&test_complete);
70 dbg_puts("semaphore UP\n");
71 sem_post((sem_t *) arg);
78 dbg_puts("semaphore DOWN\n");
79 sem_wait((sem_t *) arg);
80 dbg_puts("semaphore UP\n");
81 sem_post((sem_t *) arg);
88 int *count = (int *) arg;
93 /* Do some useless computation */
94 for (i = 0; i < nval; i++) {
97 for (j = 0; j < nval; j++) {
98 for (i = 0; i < nval; i++) {
114 printf("%s\n", (char *) msg);
115 if (strcmp(msg, "done") == 0)
124 dbg_printf("item %lu complete\n", (unsigned long) arg);
129 run_blocking_test(pthread_workqueue_t wq, int rounds)
133 for (i = 0; i < rounds; i++) {
134 additem(wq, lazy, (void *) i);
141 run_cond_wait_test(pthread_workqueue_t wq)
143 const int rounds = 10;
146 sleep(3); /* Allow time for the workers to enter pthread_cond_wait() */
148 for (i = 0; i < rounds; i++) {
149 additem(wq, lazy, (void *) i);
157 run_load_test(pthread_workqueue_t wq)
161 for (i = 0; i < 1024; i++) {
162 sprintf(buf, "%d", i);
163 additem(wq, sleepy, strdup(buf));
164 additem(wq, compute, NULL);
166 additem(wq, sleepy, "done");
169 /* Try to overwhelm the CPU with computation requests */
171 run_stress_test(pthread_workqueue_t wq, int rounds)
175 for (i = 0; i < rounds; i++) {
176 additem(wq, compute, &work_cnt);
183 * Ensure that the library is reinitialized after fork(2) is called.
186 run_fork_test(pthread_workqueue_t wq)
190 int rv, status, timeout;
192 puts("fork test... ");
200 rv = pthread_workqueue_create_np(&wq, NULL);
202 errx(1, "pthread_workqueue_create_np");
205 additem(wq, compute, &work_cnt);
206 while (work_cnt > 0) {
209 errx(1, "work was not completed");
214 if (wait(&status) != pid)
216 if (WEXITSTATUS(status) != 0)
217 errx(1, "fork test failed");
221 puts("fork test... N/A\n");
226 run_overcommit_test(pthread_workqueue_t wq)
229 pthread_workqueue_t ocwq;
230 pthread_workqueue_attr_t attr;
234 sem_init(&sem, 0, 0);
236 printf("pthread_workqueue_create_np() - overcommit enabled ");
237 pthread_workqueue_attr_init_np(&attr);
238 pthread_workqueue_attr_setovercommit_np(&attr, 1);
239 rv = pthread_workqueue_create_np(&ocwq, &attr);
245 printf("stress test - overcommit enabled ");
246 run_stress_test(ocwq, 25);
249 /* FIXME: should use a multiple of the number of CPUs instead of magic number */
250 printf("deadlock test - overcommit enabled ");
252 for (i = 0; i < 40; i++) {
253 additem(ocwq, sem_down, &sem);
255 additem(ocwq, sem_up, &sem);
256 sem_wait(&test_complete);
261 pthread_workqueue_t wq;
265 pthread_workqueue_init_np();
268 sem_init(&test_complete, 0, 0);
270 run_overcommit_test(NULL);
272 printf("pthread_workqueue_create_np().. ");
273 rv = pthread_workqueue_create_np(&wq, NULL);
278 printf("stress test.. ");
279 run_stress_test(wq, 25);
284 //run_deadlock_test();
285 // run_cond_wait_test();
286 // run_blocking_test();
290 puts("All tests completed.\n");