diff --git a/test/test_runner.c b/test/test_runner.c index fab9686..da30362 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -30,6 +30,7 @@ extern Suite *htable_suite(void); extern Suite *heapsort_suite(void); extern Suite *dstr_suite(void); extern Suite *val_str_suite(void); +extern Suite *ticket_lock_suite(void); static suite_func suites[] = { bitvec_suite, @@ -54,7 +55,8 @@ static suite_func suites[] = { threadqueue_suite, heapsort_suite, dstr_suite, - val_str_suite + val_str_suite, + ticket_lock_suite }; int diff --git a/test/test_ticket_lock.c b/test/test_ticket_lock.c new file mode 100644 index 0000000..9e53f82 --- /dev/null +++ b/test/test_ticket_lock.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include + +//this is intended more as an example +//verifying multithreaded locks requires a more formal approach + +static int g_counter; +static struct UCTicketLock lock; +struct ThreadArg { + int rounds; + pthread_t tid; +}; +static void *update_thread(void *arg) +{ + int i; + struct ThreadArg *targ = arg; + for (i = 0; i < targ->rounds; i++) { + uc_ticket_lock(&lock); + g_counter++; + uc_ticket_unlock(&lock); + } + + return NULL; +} + +#define NR_THREADS 5 + +START_TEST(test_ticket_lock1) + struct ThreadArg threads[NR_THREADS]; + int i; + printf("TICKET SUITE\n"); + + for (i = 0; i < NR_THREADS; i++) { + int rc; + threads[i].rounds = NR_THREADS - i; + rc = pthread_create(&threads[i].tid, NULL, update_thread, &threads[i]); + ck_assert_int_eq(0, rc); + } + + for (i = 0; i < NR_THREADS; i++) { + int rc; + + rc = pthread_join(threads[i].tid, NULL); + ck_assert_int_eq(0, rc); + } + + //should be sum of integers from 1 .. NR_THREADS + ck_assert_int_eq((NR_THREADS * (NR_THREADS + 1)) / 2, g_counter); + + +END_TEST + +Suite *ticket_lock_suite(void) +{ + Suite *s = suite_create("ticket_lock"); + TCase *tc = tcase_create("ticket_lock tests"); + tcase_add_test(tc, test_ticket_lock1); + suite_add_tcase(s, tc); + + return s; +}