19 void *race_thread(void *arg)
21 struct thread_data *th = arg;
22 long loops = th->loops;
23 struct xq_lock *lock = th->lock;
24 long *counter = th->counter;
25 unsigned long serial = 0, oldserial = 0, total = 0, maxdiff = 0, diff = 0;
26 double totaldiff = 0.0;
27 unsigned long *diffstat;
30 diffstat = calloc((int)log2(loops), sizeof(unsigned long));
36 oldserial = xq_acquire(lock, 1);
39 printf("%d: starting at %lu\n", th->id, oldserial);
40 for (i = 0; i < loops; i++) {
42 //printf("%d: %lu\n", th->id, i);
43 asm volatile ("#boo");
44 serial = xq_acquire(lock, 1);
45 asm volatile ("#bee");
46 //serial = oldserial +1;
48 diff = serial - oldserial;
52 diffstat[(int)log2(diff)] ++;
61 printf("%d: serial %lu, avediff: %.0lf/%lu = %lf maxdiff: %lu\n",
62 th->id, serial, totaldiff, total, totaldiff/total, maxdiff);
64 for (i = 0; i < (int)log2(loops); i++)
65 printf(" %012lu: %lu\n", (unsigned long)powl(2, i), diffstat[i]);
70 int error(const char *msg) {
75 long lock_race(long nr_threads, long loops, struct xq_lock *lock, long *counter)
77 struct thread_data *th = malloc(nr_threads * sizeof(struct thread_data));
80 return error("malloc");
82 pthread_t *threads = malloc(nr_threads * sizeof(pthread_t));
84 return error("malloc");
86 for (t = 0; t < nr_threads; t++) {
89 th[t].counter = counter;
93 for (t = 0; t < nr_threads; t++) {
94 r = pthread_create(&threads[t], NULL, race_thread, &th[t]);
96 return error("pthread_create");
99 for (t = 0; t < nr_threads; t++) {
100 pthread_join(threads[t], NULL);
103 return nr_threads * loops - *counter;
109 int main(int argc, char **argv)
111 long loops, nr_threads, r;
114 printf("Usage: xq_lock_test <nr_threads> <nr_loops>\n");
118 nr_threads = atoi(argv[1]);
119 if (nr_threads < 0) nr_threads = 2;
120 loops = atol(argv[2]);
121 if (loops < 0) loops = 1000;
123 struct timeval tv0, tv1;
124 gettimeofday(&tv0, NULL);
125 r = lock_race(nr_threads, loops, &lock, &counter);
126 gettimeofday(&tv1, NULL);
127 double seconds = tv1.tv_sec + tv1.tv_usec/1000000.0 - tv0.tv_sec - tv0.tv_usec / 1000000.0;
128 printf("lock race complete with %ld errors in %lf seconds\n", r, seconds);