2 * Written by Josh Dybnis and released to the public domain, as explained at
3 * http://creativecommons.org/licenses/publicdomain
19 #define NUM_ITERATIONS 10000000
29 static volatile int wait_;
32 void *worker (void *arg) {
33 int id = (int)(size_t)arg;
34 unsigned int r = (unsigned int)(id + 1) * 0x5bd1e995; // seed psuedo-random number generator
35 haz_t *hp0 = haz_get_static(0);
37 // Wait for all the worker threads to be ready.
38 (void)SYNC_ADD(&wait_, -1);
42 for (i = 0; i < NUM_ITERATIONS; ++ i) {
43 r ^= r << 6; r ^= r >> 21; r ^= r << 7; // generate next psuedo-random number
46 node_t *new_head = (node_t *)nbd_malloc(sizeof(node_t));
47 node_t *old_head = stk_->head;
51 new_head->next = temp;
52 } while ((old_head = SYNC_CAS(&stk_->head, temp, new_head)) != temp);
56 node_t *head = stk_->head;
62 head = VOLATILE_DEREF(stk_).head;
65 } while ((head = SYNC_CAS(&stk_->head, temp, temp->next)) != temp);
68 haz_defer_free(temp, nbd_free);
76 int main (int argc, char **argv) {
77 //lwt_set_trace_level("m0r0");
79 int num_threads = MAX_NUM_THREADS;
83 num_threads = strtol(argv[1], NULL, 10);
85 fprintf(stderr, "%s: Invalid argument for number of threads\n", argv[0]);
88 if (num_threads <= 0) {
89 fprintf(stderr, "%s: Number of threads must be at least 1\n", argv[0]);
94 stk_ = (lifo_t *)nbd_malloc(sizeof(lifo_t));
95 memset(stk_, 0, sizeof(lifo_t));
97 struct timeval tv1, tv2;
98 gettimeofday(&tv1, NULL);
101 pthread_t thread[num_threads];
102 for (int i = 0; i < num_threads; ++i) {
103 int rc = nbd_thread_create(thread + i, i, worker, (void *)(size_t)i);
104 if (rc != 0) { perror("pthread_create"); return rc; }
106 for (int i = 0; i < num_threads; ++i) {
107 pthread_join(thread[i], NULL);
110 gettimeofday(&tv2, NULL);
111 int ms = (int)(1000000*(tv2.tv_sec - tv1.tv_sec) + tv2.tv_usec - tv1.tv_usec) / 1000;
112 printf("Th:%d Time:%dms\n\n", num_threads, ms);