d9517ad868
and implement a _clear() function to clear out the queue
343 lines
8.7 KiB
C
343 lines
8.7 KiB
C
#include <check.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <sched.h>
|
|
#include <stdlib.h>
|
|
#include <ucore/threadqueue.h>
|
|
|
|
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, NULL) != 0);
|
|
|
|
END_TEST
|
|
|
|
|
|
|
|
|
|
//pretty ugly..
|
|
static int test_thread_queue_walk_global;
|
|
static void test_thread_queue_walk_func(struct uc_threadmsg *msg, void *cookie)
|
|
{
|
|
(void)cookie;
|
|
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, NULL);
|
|
|
|
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, 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, 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);
|
|
my_msg.b = 12345;
|
|
my_msg.msg.msgtype = 0;
|
|
fail_if(uc_thread_queue_add(&queue, &my_msg.msg) != 0);
|
|
fail_if(pthread_create(&tid1, NULL, thread_test_thread_queue_timeout2, &queue) != 0);
|
|
|
|
|
|
pthread_join(tid1, NULL);
|
|
|
|
uc_thread_queue_destroy(&queue, NULL, NULL);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_thread_queue_tryadd_timeout_0_0)
|
|
|
|
struct uc_threadqueue queue;
|
|
int i;
|
|
struct thr_msg msg[3];
|
|
memset(msg, 0, sizeof msg);
|
|
struct timespec timeout = {0,0};
|
|
|
|
fail_if(uc_thread_queue_init(&queue, 2) != 0);
|
|
for (i = 0; i < 2; i++) {
|
|
fail_if(uc_thread_queue_add(&queue, &msg[i].msg) != 0);
|
|
}
|
|
|
|
fail_if(uc_thread_queue_tryadd(&queue, &timeout, &msg[2].msg) != ETIMEDOUT);
|
|
|
|
fail_if(uc_thread_queue_destroy(&queue, NULL, NULL) != 0);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_thread_queue_tryadd_timeout_0_100)
|
|
|
|
struct uc_threadqueue queue;
|
|
int i;
|
|
struct thr_msg msg[3];
|
|
memset(msg, 0, sizeof msg);
|
|
struct timespec timeout = {0,100};
|
|
|
|
fail_if(uc_thread_queue_init(&queue, 2) != 0);
|
|
for (i = 0; i < 2; i++) {
|
|
fail_if(uc_thread_queue_add(&queue, &msg[i].msg) != 0);
|
|
}
|
|
|
|
fail_if(uc_thread_queue_tryadd(&queue, &timeout, &msg[2].msg) != ETIMEDOUT);
|
|
|
|
fail_if(uc_thread_queue_destroy(&queue, NULL, NULL) != 0);
|
|
|
|
END_TEST
|
|
|
|
START_TEST (test_thread_queue_tryadd_no_timeout_0_100)
|
|
|
|
struct uc_threadqueue queue;
|
|
int i;
|
|
struct thr_msg msg[3];
|
|
memset(msg, 0, sizeof msg);
|
|
struct timespec timeout = {0,100};
|
|
|
|
fail_if(uc_thread_queue_init(&queue, 3) != 0);
|
|
for (i = 0; i < 2; i++) {
|
|
fail_if(uc_thread_queue_add(&queue, &msg[i].msg) != 0);
|
|
}
|
|
|
|
fail_if(uc_thread_queue_tryadd(&queue, &timeout, &msg[2].msg) != 0);
|
|
|
|
fail_if(uc_thread_queue_destroy(&queue, NULL, NULL) != 0);
|
|
|
|
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);
|
|
tcase_add_test(tc1, test_thread_queue_tryadd_timeout_0_0);
|
|
tcase_add_test(tc1, test_thread_queue_tryadd_timeout_0_100);
|
|
tcase_add_test(tc1, test_thread_queue_tryadd_no_timeout_0_100);
|
|
|
|
//lets start with this:
|
|
tcase_set_timeout(tc1, 15);
|
|
|
|
suite_add_tcase(s, tc1);
|
|
|
|
return s;
|
|
}
|
|
|