1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

queue: add queue_t root type

This commit is contained in:
René Kijewski 2014-05-07 00:41:21 +02:00
parent 4c6a6ee4b3
commit 4032a22719
14 changed files with 100 additions and 211 deletions

View File

@ -39,14 +39,14 @@ typedef struct mutex_t {
* by the user.**
* @internal
*/
queue_node_t queue;
queue_t queue;
} mutex_t;
/**
* @brief Static initializer for mutex_t.
* @details This initializer is preferrable to mutex_init().
*/
#define MUTEX_INIT { 0, QUEUE_NODE_INIT }
#define MUTEX_INIT { 0, QUEUE_INIT }
/**
* @brief Initializes a mutex object.

View File

@ -23,7 +23,7 @@
#include <stdint.h>
/**
* data type for queue nodes
* data type for priority queue nodes
*/
typedef struct queue_node_t {
struct queue_node_t *next; /**< next queue node */
@ -31,11 +31,23 @@ typedef struct queue_node_t {
uint32_t priority; /**< queue node priority */
} queue_node_t;
/**
* data type for priority queues
*/
typedef struct queue {
queue_node_t *first; /**< first queue node */
} queue_t;
/**
* @brief Static initializer for queue_node_t.
*/
#define QUEUE_NODE_INIT { NULL, 0, 0 }
/**
* @brief Static initializer for queue_t.
*/
#define QUEUE_INIT { NULL }
/**
* @brief remove the queue's head
*
@ -43,7 +55,7 @@ typedef struct queue_node_t {
*
* @return the old head
*/
queue_node_t *queue_remove_head(queue_node_t *root);
queue_node_t *queue_remove_head(queue_t *root);
/**
* @brief insert `new_obj` into `root` based on its priority
@ -54,7 +66,7 @@ queue_node_t *queue_remove_head(queue_node_t *root);
* @param[in,out] root the queue's root
* @param[in] new_obj the object to prepend
*/
void queue_priority_add(queue_node_t *root, queue_node_t *new_obj);
void queue_priority_add(queue_t *root, queue_node_t *new_obj);
/**
* @brief remove `node` from `root`
@ -62,11 +74,11 @@ void queue_priority_add(queue_node_t *root, queue_node_t *new_obj);
* @param[in,out] root the queue's root
* @param[in] node the node to remove
*/
void queue_remove(queue_node_t *root, queue_node_t *node);
void queue_remove(queue_t *root, queue_node_t *node);
#if ENABLE_DEBUG
void queue_print(queue_node_t *node);
void queue_print_node(queue_node_t *node);
void queue_print(queue_t *root);
void queue_print_node(queue_t *root);
#endif
/** @} */

View File

@ -65,7 +65,7 @@ typedef struct tcb_t {
clist_node_t rq_entry; /**< run queue entry */
void *wait_data; /**< holding messages */
queue_node_t msg_waiters; /**< threads waiting on message */
queue_t msg_waiters; /**< threads waiting on message */
cib_t msg_queue; /**< message queue */
msg_t *msg_array; /**< memory holding messages */

View File

@ -88,8 +88,8 @@ void mutex_unlock(struct mutex_t *mutex)
int irqstate = disableIRQ();
if (mutex->val != 0) {
if (mutex->queue.next) {
queue_node_t *next = queue_remove_head(&(mutex->queue));
queue_node_t *next = queue_remove_head(&(mutex->queue));
if (next) {
tcb_t *process = (tcb_t *) next->data;
DEBUG("%s: waking up waiter.\n", process->name);
sched_set_status(process, STATUS_PENDING);
@ -110,8 +110,8 @@ void mutex_unlock_and_sleep(struct mutex_t *mutex)
int irqstate = disableIRQ();
if (mutex->val != 0) {
if (mutex->queue.next) {
queue_node_t *next = queue_remove_head(&(mutex->queue));
queue_node_t *next = queue_remove_head(&(mutex->queue));
if (next) {
tcb_t *process = (tcb_t *) next->data;
DEBUG("%s: waking up waiter.\n", process->name);
sched_set_status(process, STATUS_PENDING);

View File

@ -22,8 +22,11 @@
#include "queue.h"
void queue_remove(queue_node_t *root, queue_node_t *node)
void queue_remove(queue_t *root_, queue_node_t *node)
{
/* The strict aliasing rules allow this assignment. */
queue_node_t *root = (queue_node_t *) root_;
while (root->next != NULL) {
if (root->next == node) {
root->next = node->next;
@ -35,20 +38,19 @@ void queue_remove(queue_node_t *root, queue_node_t *node)
}
}
queue_node_t *queue_remove_head(queue_node_t *root)
queue_node_t *queue_remove_head(queue_t *root)
{
queue_node_t *head = root->next;
if (head != NULL) {
root->next = head->next;
queue_node_t *head = root->first;
if (head) {
root->first = head->next;
}
return head;
}
void queue_priority_add(queue_node_t *root, queue_node_t *new_obj)
void queue_priority_add(queue_t *root, queue_node_t *new_obj)
{
queue_node_t *node = root;
/* The strict aliasing rules allow this assignment. */
queue_node_t *node = (queue_node_t *) root;
while (node->next != NULL) {
if (node->next->priority > new_obj->priority) {
@ -65,12 +67,11 @@ void queue_priority_add(queue_node_t *root, queue_node_t *new_obj)
}
#if ENABLE_DEBUG
void queue_print(queue_node_t *node)
void queue_print(queue_t *node)
{
printf("queue:\n");
while (node->next != NULL) {
node = node->next;
for (queue_node_t *node = node->first; node; node = node->next) {
printf("Data: %u Priority: %lu\n", node->data, (unsigned long) node->priority);
}
}

View File

@ -187,9 +187,7 @@ int thread_create(char *stack, int stacksize, char priority, int flags, void *(*
cb->wait_data = NULL;
cb->msg_waiters.data = 0;
cb->msg_waiters.priority = 0;
cb->msg_waiters.next = NULL;
cb->msg_waiters.first = NULL;
cib_init(&(cb->msg_queue), 0);
cb->msg_array = NULL;

View File

@ -10,7 +10,7 @@
typedef struct sem {
volatile unsigned int value;
queue_node_t queue;
queue_t queue;
} sem_t;
/**

View File

@ -33,7 +33,7 @@ typedef struct pthread_condattr_t {
typedef struct pthread_cond_t {
/* fields are managed by cv functions, don't touch */
queue_node_t queue; /**< Threads currently waiting to be signaled. */
queue_t queue; /**< Threads currently waiting to be signaled. */
} pthread_cond_t;
/**

View File

@ -36,7 +36,7 @@ typedef struct pthread_rwlock
/**
* @brief Queue of waiting threads.
*/
queue_node_t queue;
queue_t queue;
/**
* @brief Provides mutual exclusion on reading and writing on the structure.

View File

@ -84,9 +84,7 @@ int pthread_cond_init(struct pthread_cond_t *cond, struct pthread_condattr_t *at
DEBUG("pthread_cond_init: currently attributes are not supported.\n");
}
cond->queue.priority = 0;
cond->queue.data = 0;
cond->queue.next = NULL;
cond->queue.first = NULL;
return 0;
}

View File

@ -75,12 +75,12 @@ bool __pthread_rwlock_blocked_readingly(const pthread_rwlock_t *rwlock)
/* Determine if there is a writer waiting to get this lock who has a higher or the same priority: */
if (rwlock->queue.next == NULL) {
if (rwlock->queue.first == NULL) {
/* no waiting thread */
return false;
}
queue_node_t *qnode = rwlock->queue.next;
queue_node_t *qnode = rwlock->queue.first;
if (qnode->priority > sched_active_thread->priority) {
/* the waiting thread has a lower priority */
return false;
@ -264,7 +264,7 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
rwlock->readers = 0;
}
if (rwlock->readers != 0 || rwlock->queue.next == NULL) {
if (rwlock->readers != 0 || rwlock->queue.first == NULL) {
/* this thread was not the last reader, or no one is waiting to aquire the lock */
DEBUG("Thread %u: pthread_rwlock_%s(): no one is waiting\n", thread_pid, "unlock");
mutex_unlock(&rwlock->mutex);
@ -289,8 +289,8 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
++rwlock->readers;
/* wake up further readers */
while (rwlock->queue.next) {
waiting_node = (__pthread_rwlock_waiter_node_t *) rwlock->queue.next->data;
while (rwlock->queue.first) {
waiting_node = (__pthread_rwlock_waiter_node_t *) rwlock->queue.first->data;
if (waiting_node->is_writer) {
/* Not to be unfair to writers, we don't try to wake up readers that came after the first writer. */
DEBUG("Thread %u: pthread_rwlock_%s(): continuing readers blocked by writer %u\n",

View File

@ -39,16 +39,14 @@ int sem_init(sem_t *sem, int pshared, unsigned int value)
sem->value = value;
/* waiters for the mutex */
sem->queue.priority = 0;
sem->queue.data = 0;
sem->queue.next = NULL;
sem->queue.first = NULL;
return 0;
}
int sem_destroy(sem_t *sem)
{
if (sem->queue.next) {
if (sem->queue.first) {
DEBUG("%s: tried to destroy active semaphore.\n", sched_active_thread->name);
return -1;
}

View File

@ -50,8 +50,8 @@ static int vtimer_set(vtimer_t *timer);
static int set_longterm(vtimer_t *timer);
static int set_shortterm(vtimer_t *timer);
static queue_node_t longterm_queue_root;
static queue_node_t shortterm_queue_root;
static queue_t longterm_queue_root;
static queue_t shortterm_queue_root;
static vtimer_t longterm_tick_timer;
static uint32_t longterm_tick_start;
@ -71,14 +71,14 @@ static int set_longterm(vtimer_t *timer)
static int update_shortterm(void)
{
if (shortterm_queue_root.next == NULL) {
if (shortterm_queue_root.first == NULL) {
/* there is no vtimer to schedule, queue is empty */
DEBUG("update_shortterm: shortterm_queue_root.next == NULL - dont know what to do here\n");
return 0;
}
if (hwtimer_id != -1) {
/* there is a running hwtimer for us */
if (hwtimer_next_absolute != shortterm_queue_root.next->priority) {
if (hwtimer_next_absolute != shortterm_queue_root.first->priority) {
/* the next timer in the vtimer queue is not the next hwtimer */
/* we have to remove the running hwtimer (and schedule a new one) */
hwtimer_remove(hwtimer_id);
@ -90,7 +90,7 @@ static int update_shortterm(void)
}
/* short term part of the next vtimer */
hwtimer_next_absolute = shortterm_queue_root.next->priority;
hwtimer_next_absolute = shortterm_queue_root.first->priority;
uint32_t next = hwtimer_next_absolute;
@ -98,7 +98,7 @@ static int update_shortterm(void)
uint32_t now = HWTIMER_TICKS_TO_US(hwtimer_now());
/* make sure the longterm_tick_timer does not get truncated */
if (((vtimer_t *) shortterm_queue_root.next)->action != vtimer_callback_tick) {
if (((vtimer_t *) shortterm_queue_root.first)->action != vtimer_callback_tick) {
/* the next vtimer to schedule is the long term tick */
/* it has a shortterm offset of longterm_tick_start */
next += longterm_tick_start;
@ -126,11 +126,11 @@ void vtimer_callback_tick(vtimer_t *timer)
longterm_tick_timer.absolute.microseconds += MICROSECONDS_PER_TICK;
set_shortterm(&longterm_tick_timer);
while (longterm_queue_root.next) {
vtimer_t *timer = (vtimer_t *) longterm_queue_root.next;
while (longterm_queue_root.first) {
vtimer_t *timer = (vtimer_t *) longterm_queue_root.first;
if (timer->absolute.seconds == seconds) {
timer = (vtimer_t *) queue_remove_head(&longterm_queue_root);
queue_remove_head(&longterm_queue_root);
set_shortterm(timer);
}
else {

View File

@ -15,16 +15,19 @@
#define Q_LEN (4)
static queue_node_t q[Q_LEN];
static queue_t q;
static queue_node_t qe[Q_LEN];
static void set_up(void)
{
memset(q, 0, sizeof(q));
q.first = NULL;
memset(qe, 0, sizeof(qe));
}
static void test_queue_remove_head_empty(void)
{
queue_node_t *root = &(q[0]), *res;
queue_t *root = &q;
queue_node_t *res;
res = queue_remove_head(root);
@ -33,11 +36,12 @@ static void test_queue_remove_head_empty(void)
static void test_queue_remove_head_one(void)
{
queue_node_t *root = &(q[0]), *elem = &(q[1]), *res;
queue_t *root = &q;
queue_node_t *elem = &(qe[1]), *res;
elem->data = 62801;
queue_add_head(root, elem);
queue_priority_add(root, elem);
res = queue_remove_head(root);
@ -49,91 +53,27 @@ static void test_queue_remove_head_one(void)
TEST_ASSERT_NULL(res);
}
static void test_queue_add_head_one(void)
{
queue_node_t *root = &(q[0]), *elem = &(q[1]);
elem->data = 44011;
queue_add_head(root, elem);
TEST_ASSERT(root->next == elem);
TEST_ASSERT_EQUAL_INT(44011, root->next->data);
TEST_ASSERT_NULL(root->next->next);
}
static void test_queue_add_head_two(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
elem1->data = 25303;
elem2->data = 64960;
queue_add_head(root, elem1);
queue_add_head(root, elem2);
TEST_ASSERT(root->next == elem2);
TEST_ASSERT_EQUAL_INT(64960, root->next->data);
TEST_ASSERT(root->next->next == elem1);
TEST_ASSERT_EQUAL_INT(25303, root->next->next->data);
TEST_ASSERT_NULL(root->next->next->next);
}
static void test_queue_add_tail_one(void)
{
queue_node_t *root = &(q[0]), *elem = &(q[1]);
elem->data = 33893;
queue_add_tail(root, elem);
TEST_ASSERT(root->next == elem);
TEST_ASSERT_EQUAL_INT(33893, root->next->data);
TEST_ASSERT_NULL(root->next->next);
}
static void test_queue_add_tail_two(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
elem1->data = 9084;
elem2->data = 57068;
queue_add_tail(root, elem1);
queue_add_tail(root, elem2);
TEST_ASSERT(root->next == elem1);
TEST_ASSERT_EQUAL_INT(9084, root->next->data);
TEST_ASSERT(root->next->next == elem2);
TEST_ASSERT_EQUAL_INT(57068, root->next->next->data);
TEST_ASSERT_NULL(root->next->next->next);
}
static void test_queue_priority_add_one(void)
{
queue_node_t *root = &(q[0]), *elem = &(q[1]);
queue_t *root = &q;
queue_node_t *elem = &(qe[1]);
elem->data = 7317;
elem->priority = 713643658;
queue_priority_add(root, elem);
TEST_ASSERT(root->next == elem);
TEST_ASSERT_EQUAL_INT(7317, root->next->data);
TEST_ASSERT_EQUAL_INT(713643658, root->next->priority);
TEST_ASSERT(root->first == elem);
TEST_ASSERT_EQUAL_INT(7317, root->first->data);
TEST_ASSERT_EQUAL_INT(713643658, root->first->priority);
TEST_ASSERT_NULL(root->next->next);
TEST_ASSERT_NULL(root->first->next);
}
static void test_queue_priority_add_two_equal(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
queue_t *root = &q;
queue_node_t *elem1 = &(qe[1]), *elem2 = &(qe[2]);
elem1->data = 27088;
elem1->priority = 14202;
@ -144,20 +84,21 @@ static void test_queue_priority_add_two_equal(void)
queue_priority_add(root, elem1);
queue_priority_add(root, elem2);
TEST_ASSERT(root->next == elem1);
TEST_ASSERT_EQUAL_INT(27088, root->next->data);
TEST_ASSERT_EQUAL_INT(14202, root->next->priority);
TEST_ASSERT(root->first == elem1);
TEST_ASSERT_EQUAL_INT(27088, root->first->data);
TEST_ASSERT_EQUAL_INT(14202, root->first->priority);
TEST_ASSERT(root->next->next == elem2);
TEST_ASSERT_EQUAL_INT(4356, root->next->next->data);
TEST_ASSERT_EQUAL_INT(14202, root->next->next->priority);
TEST_ASSERT(root->first->next == elem2);
TEST_ASSERT_EQUAL_INT(4356, root->first->next->data);
TEST_ASSERT_EQUAL_INT(14202, root->first->next->priority);
TEST_ASSERT_NULL(root->next->next->next);
TEST_ASSERT_NULL(root->first->next->next);
}
static void test_queue_priority_add_two_distinct(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
queue_t *root = &q;
queue_node_t *elem1 = &(qe[1]), *elem2 = &(qe[2]);
elem1->data = 46421;
elem1->priority = 4567;
@ -168,83 +109,30 @@ static void test_queue_priority_add_two_distinct(void)
queue_priority_add(root, elem1);
queue_priority_add(root, elem2);
TEST_ASSERT(root->next == elem2);
TEST_ASSERT_EQUAL_INT(43088, root->next->data);
TEST_ASSERT_EQUAL_INT(1234, root->next->priority);
TEST_ASSERT(root->first == elem2);
TEST_ASSERT_EQUAL_INT(43088, root->first->data);
TEST_ASSERT_EQUAL_INT(1234, root->first->priority);
TEST_ASSERT(root->next->next == elem1);
TEST_ASSERT_EQUAL_INT(46421, root->next->next->data);
TEST_ASSERT_EQUAL_INT(4567, root->next->next->priority);
TEST_ASSERT(root->first->next == elem1);
TEST_ASSERT_EQUAL_INT(46421, root->first->next->data);
TEST_ASSERT_EQUAL_INT(4567, root->first->next->priority);
TEST_ASSERT_NULL(root->next->next->next);
}
static int generic_compare(queue_node_t *a, queue_node_t *b)
{
return (b->priority) - (a->priority);
}
static void test_queue_priority_add_generic_two_equal(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
elem1->data = 43804;
elem1->priority = 34572;
elem2->data = 64016;
elem2->priority = 34572;
queue_priority_add_generic(root, elem1, generic_compare);
queue_priority_add_generic(root, elem2, generic_compare);
TEST_ASSERT(root->next == elem1);
TEST_ASSERT_EQUAL_INT(43804, root->next->data);
TEST_ASSERT_EQUAL_INT(34572, root->next->priority);
TEST_ASSERT(root->next->next == elem2);
TEST_ASSERT_EQUAL_INT(64016, root->next->next->data);
TEST_ASSERT_EQUAL_INT(34572, root->next->next->priority);
TEST_ASSERT_NULL(root->next->next->next);
}
static void test_queue_priority_add_generic_two_distinct(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
elem1->data = 39152;
elem1->priority = 45394;
elem2->data = 54496;
elem2->priority = 56834;
queue_priority_add_generic(root, elem1, generic_compare);
queue_priority_add_generic(root, elem2, generic_compare);
TEST_ASSERT(root->next == elem1);
TEST_ASSERT_EQUAL_INT(39152, root->next->data);
TEST_ASSERT_EQUAL_INT(45394, root->next->priority);
TEST_ASSERT(root->next->next == elem2);
TEST_ASSERT_EQUAL_INT(54496, root->next->next->data);
TEST_ASSERT_EQUAL_INT(56834, root->next->next->priority);
TEST_ASSERT_NULL(root->next->next->next);
TEST_ASSERT_NULL(root->first->next->next);
}
static void test_queue_remove_one(void)
{
queue_node_t *root = &(q[0]), *elem1 = &(q[1]), *elem2 = &(q[2]);
queue_node_t *elem3 = &(q[3]);
queue_t *root = &q;
queue_node_t *elem1 = &(qe[1]), *elem2 = &(qe[2]), *elem3 = &(qe[3]);
queue_add_head(root, elem1);
queue_add_head(root, elem2);
queue_add_head(root, elem3);
queue_priority_add(root, elem1);
queue_priority_add(root, elem2);
queue_priority_add(root, elem3);
queue_remove(root, elem2);
TEST_ASSERT(root->next == elem3);
TEST_ASSERT(root->next->next == elem1);
TEST_ASSERT_NULL(root->next->next->next);
TEST_ASSERT(root->first == elem1);
TEST_ASSERT(root->first->next == elem3);
TEST_ASSERT_NULL(root->first->next->next);
}
Test *tests_core_queue_tests(void)
@ -252,15 +140,9 @@ Test *tests_core_queue_tests(void)
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_queue_remove_head_empty),
new_TestFixture(test_queue_remove_head_one),
new_TestFixture(test_queue_add_head_one),
new_TestFixture(test_queue_add_head_two),
new_TestFixture(test_queue_add_tail_one),
new_TestFixture(test_queue_add_tail_two),
new_TestFixture(test_queue_priority_add_one),
new_TestFixture(test_queue_priority_add_two_equal),
new_TestFixture(test_queue_priority_add_two_distinct),
new_TestFixture(test_queue_priority_add_generic_two_equal),
new_TestFixture(test_queue_priority_add_generic_two_distinct),
new_TestFixture(test_queue_remove_one),
};