4 * @brief Multithreaded test program that triggers various access patterns
5 * without triggering any race conditions using a binary semaphore
6 * implemented via busy-waiting. Annotations are used to tell DRD
7 * which higher-level semaphore operations are being performed.
13 #include "../../config.h"
14 #include "../../drd/drd.h"
17 #define ITERATIONS 1000
20 volatile unsigned value
;
24 static unsigned int s_counter
;
26 static void sem_init(sem_t
*p
, unsigned value
)
30 ANNOTATE_SEM_INIT_PRE(p
, value
);
33 static void sem_destroy(sem_t
*p
)
35 ANNOTATE_SEM_DESTROY_POST(p
);
38 static void sem_wait(sem_t
*p
)
41 struct timespec ts
= { 0, 0 };
43 ANNOTATE_SEM_WAIT_PRE(p
);
49 } while (!old
|| !__sync_bool_compare_and_swap(&p
->value
, old
, new));
50 ANNOTATE_SEM_WAIT_POST(p
);
53 static void sem_post(sem_t
*p
)
55 ANNOTATE_SEM_POST_PRE(p
);
56 __sync_fetch_and_add(&p
->value
, 1);
59 static void *thread_func(void *arg
)
64 for (i
= 0; i
< ITERATIONS
; i
++) {
77 int main(int argc
, const char *argv
[])
79 pthread_t tid
[THREADS
];
83 for (i
= 0; i
< THREADS
; i
++)
84 pthread_create(&tid
[i
], 0, thread_func
, 0);
86 for (i
= 0; i
< THREADS
; i
++)
87 pthread_join(tid
[i
], 0);
89 assert(s_counter
== THREADS
* ITERATIONS
);
90 assert(s_sem
.value
== 1);
93 fprintf(stderr
, "Finished.\n");