#include #include #include #include #include #include struct thr_msg { struct uc_threadmsg msg; int a,b; char data[32]; }; START_TEST (test_thread_queue_length) struct uc_threadqueue queue; int i; fail_if(uc_thread_queue_init(&queue, 100) != 0); for (i = 0; i < 51; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->msg.msgtype = 1; fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); } fail_if(uc_thread_queue_length(&queue) != 51); END_TEST START_TEST (test_thread_queue_one_thread) struct uc_threadqueue queue; int i; fail_if(uc_thread_queue_init(&queue, 100) != 0); for (i = 0; i < 51; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->msg.msgtype = 0; msg->a = i; fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); } for (i = 0; i < 51; i++) { struct uc_threadmsg *msg; struct thr_msg *my_msg; fail_if(uc_thread_queue_get(&queue, &msg) != 0); my_msg = (struct thr_msg *)msg; fail_if(my_msg->a != i); free(my_msg); } fail_if(uc_thread_queue_destroy(&queue, NULL) != 0); END_TEST //pretty ugly.. static int test_thread_queue_walk_global; static void test_thread_queue_walk_func(struct uc_threadmsg *msg) { struct thr_msg *my_msg = (struct thr_msg *)msg; fail_if(my_msg->a != test_thread_queue_walk_global); test_thread_queue_walk_global++; } START_TEST (test_thread_queue_walk) struct uc_threadqueue queue; int i; fail_if(uc_thread_queue_init(&queue, 100) != 0); for (i = 0; i < 51; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->a = i; msg->msg.msgtype = 0; fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); } test_thread_queue_walk_global = 0; uc_thread_queue_walk(&queue, test_thread_queue_walk_func); END_TEST #define READER_WRITER_NUM_MSG 20000 static void *test_thread_queue_reader_writer_func(void *arg) { struct uc_threadqueue *queue = arg; int i; for (i = 0; i < READER_WRITER_NUM_MSG; i++) { struct uc_threadmsg *msg; struct thr_msg *my_msg; fail_if(uc_thread_queue_get(queue, &msg) != 0); my_msg = (struct thr_msg *)msg; fail_if(my_msg->a != i); free(my_msg); } return NULL; } START_TEST (test_thread_queue_reader_writer) struct uc_threadqueue queue; int i; pthread_t tid; fail_if(uc_thread_queue_init(&queue, 1000) != 0); fail_if(pthread_create(&tid, NULL, test_thread_queue_reader_writer_func, &queue) != 0); sched_yield(); for (i = 0; i < READER_WRITER_NUM_MSG; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->a = i; msg->msg.msgtype = 0; fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); } pthread_join(tid, NULL); fail_if(uc_thread_queue_destroy(&queue, NULL) != 0); END_TEST START_TEST (test_thread_queue_reader_writer_len_1) struct uc_threadqueue queue; int i; pthread_t tid; fail_if(uc_thread_queue_init(&queue, 1) != 0); fail_if(pthread_create(&tid, NULL, test_thread_queue_reader_writer_func, &queue) != 0); sched_yield(); for (i = 0; i < READER_WRITER_NUM_MSG; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->a = i; msg->msg.msgtype = 0; fail_if(uc_thread_queue_add(&queue, &msg->msg) != 0); } pthread_join(tid, NULL); END_TEST START_TEST (test_thread_queue_zero_len) struct uc_threadqueue queue; fail_if(uc_thread_queue_init(&queue, 0) == 0); //thread_queue_init should fail END_TEST void *test_thread_queue_multiple_writers_func(void *arg) { struct uc_threadqueue *queue = arg; int i; for (i = 0; i < READER_WRITER_NUM_MSG; i++) { struct thr_msg *msg = malloc(sizeof *msg); fail_if(msg == NULL); msg->a = i; msg->msg.msgtype = 0; fail_if(uc_thread_queue_add(queue, &msg->msg) != 0); } return NULL; } START_TEST (test_thread_queue_multiple_writers) struct uc_threadqueue queue; int i; int count_max = 0; pthread_t tid1,tid2,tid3; fail_if(uc_thread_queue_init(&queue, 10) != 0); fail_if(pthread_create(&tid1, NULL, test_thread_queue_multiple_writers_func, &queue) != 0); fail_if(pthread_create(&tid2, NULL, test_thread_queue_multiple_writers_func, &queue) != 0); fail_if(pthread_create(&tid3, NULL, test_thread_queue_multiple_writers_func, &queue) != 0); for (i = 0; i < READER_WRITER_NUM_MSG * 3; i++) { struct uc_threadmsg *msg; struct thr_msg *my_msg; fail_if(uc_thread_queue_get(&queue, &msg) != 0); my_msg = (struct thr_msg *)msg; if (my_msg->a == READER_WRITER_NUM_MSG - 1) count_max++; free(my_msg); } pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_join(tid3, NULL); fail_if(count_max != 3); END_TEST START_TEST (test_thread_queue_timeout1) struct uc_threadqueue queue; struct timespec timeout = {0, 1000}; struct uc_threadmsg *msg; fail_if(uc_thread_queue_init(&queue, 100) != 0); fail_if(uc_thread_queue_tryget(&queue, &timeout, &msg) != ETIMEDOUT); uc_thread_queue_destroy(&queue, NULL); END_TEST void *thread_test_thread_queue_timeout2(void *arg) { struct uc_threadqueue *queue = arg; struct uc_threadmsg *msg; struct thr_msg *my_msg; struct timespec timeout = {0, 2000}; fail_if(uc_thread_queue_tryget(queue, &timeout, &msg) != 0); fail_if(uc_thread_queue_tryget(queue, &timeout, &msg) != ETIMEDOUT); my_msg = (struct thr_msg *)msg; fail_if(my_msg->b != 12345); return NULL; } START_TEST (test_thread_queue_timeout2) struct uc_threadqueue queue; pthread_t tid1; struct thr_msg my_msg; fail_if(uc_thread_queue_init(&queue, 10) != 0); fail_if(pthread_create(&tid1, NULL, thread_test_thread_queue_timeout2, &queue) != 0); my_msg.b = 12345; my_msg.msg.msgtype = 0; fail_if(uc_thread_queue_add(&queue, &my_msg.msg) != 0); pthread_join(tid1, NULL); uc_thread_queue_destroy(&queue, NULL); END_TEST Suite *threadqueue_suite(void) { Suite *s = suite_create("treadqueue"); TCase *tc1 = tcase_create("thread queue"); tcase_add_test(tc1, test_thread_queue_length); tcase_add_test(tc1, test_thread_queue_one_thread); tcase_add_test(tc1, test_thread_queue_walk); tcase_add_test(tc1, test_thread_queue_reader_writer); tcase_add_test(tc1, test_thread_queue_reader_writer_len_1); tcase_add_test(tc1, test_thread_queue_zero_len); tcase_add_test(tc1, test_thread_queue_multiple_writers); tcase_add_test(tc1, test_thread_queue_timeout1); tcase_add_test(tc1, test_thread_queue_timeout2); //lets start with this: tcase_set_timeout(tc1, 15); suite_add_tcase(s, tc1); return s; }