mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
core: clist: make singly linked
This commit is contained in:
parent
f626ee5969
commit
f9f6adb48d
79
core/clist.c
79
core/clist.c
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup core_util
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Circular linked list implementation
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "clist.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* inserts new_node after node */
|
||||
void clist_add(clist_node_t **node, clist_node_t *new_node)
|
||||
{
|
||||
if (*node != NULL) {
|
||||
new_node->next = (*node);
|
||||
new_node->prev = (*node)->prev;
|
||||
(*node)->prev->next = new_node;
|
||||
(*node)->prev = new_node;
|
||||
|
||||
if ((*node)->prev == *node) {
|
||||
(*node)->prev = new_node;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*node = new_node;
|
||||
new_node->next = new_node;
|
||||
new_node->prev = new_node;
|
||||
}
|
||||
}
|
||||
|
||||
/* removes node. */
|
||||
void clist_remove(clist_node_t **list, clist_node_t *node)
|
||||
{
|
||||
if (node->next != node) {
|
||||
node->prev->next = node->next;
|
||||
node->next->prev = node->prev;
|
||||
|
||||
if (node == *list) {
|
||||
*list = node->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
void clist_print(clist_node_t *clist)
|
||||
{
|
||||
clist_node_t *start = clist, *node = start;
|
||||
if (!start) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
printf("list entry: %p: prev=%p next=%p\n",
|
||||
(void *)clist, (void *)clist->prev, (void *)clist->next);
|
||||
clist = clist->next;
|
||||
|
||||
if (clist == start) {
|
||||
break;
|
||||
}
|
||||
} while (node != start);
|
||||
}
|
||||
#endif
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Freie Universität Berlin
|
||||
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* 2013 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -13,6 +14,14 @@
|
||||
* @file
|
||||
* @brief Circular linked list
|
||||
*
|
||||
* This file contains a circularly linked list implementation.
|
||||
*
|
||||
* clist_insert(), clist_remove_head() and clist_advance() take constant time.
|
||||
*
|
||||
* Each list is represented as a "clist_node_t". It's only member, the "next"
|
||||
* pointer, points to the last entry in the list, whose "next" pointer points to
|
||||
* the first entry.
|
||||
*
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
@ -20,51 +29,67 @@
|
||||
#define CLIST_H
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @def clist_get_container(NODE, TYPE, MEMBER)
|
||||
* @brief Returns the container of the circular list
|
||||
* @details For a struct `TYPE` with a member `MEMBER`, which is a `clist_node_t`,
|
||||
* given a pointer `NODE` to `TYPE::MEMBER` this function returns a pointer
|
||||
* to the instance of `TYPE`.
|
||||
* @details E.g. for `struct my_struct_t { ...; clist_node_t n; ... } my_struct;`,
|
||||
* `&my_struct == clist_get_container(&my_struct.n, struct my_struct_t, n)`.
|
||||
* @param[in] NODE pointer to a member
|
||||
* @param[in] TYPE a type name (a struct or union), container of NODE
|
||||
* @param[in] MEMBER name of the member of TYPE which NODE points to
|
||||
* @return Pointer to the container of NODE.
|
||||
*/
|
||||
#define clist_get_container(NODE, TYPE, MEMBER) container_of(NODE, TYPE, MEMBER)
|
||||
|
||||
/**
|
||||
* @brief Structure representing a node in the clist.
|
||||
*/
|
||||
typedef struct clist_node_t {
|
||||
struct clist_node_t *next; /**< pointer to next node */
|
||||
struct clist_node_t *prev; /**< pointer to the previous node */
|
||||
} clist_node_t;
|
||||
|
||||
/**
|
||||
* @brief Inserts *new_node* after *node* into list
|
||||
* @brief List node structure
|
||||
*
|
||||
* @param[in,out] node Node after which *new_node* gets inserted
|
||||
* @param[in,out] new_node Node which gets inserted after *node*.
|
||||
* Used as is as reference to a list.
|
||||
*
|
||||
* clist stores a pointer to the last element of a list. That way, both
|
||||
* appending to end of list and removing head can be done in constant time.
|
||||
*
|
||||
* Actual list objects should have a @c clist_node_t as member and then use
|
||||
* the container_of() macro in list operations.
|
||||
* See @ref thread_add_to_list() as example.
|
||||
*/
|
||||
typedef list_node_t clist_node_t;
|
||||
|
||||
/**
|
||||
* @brief inserts *new_node* into *list*
|
||||
*
|
||||
* @param[in,out] list Ptr to clist
|
||||
* @param[in,out] new_node Node which gets inserted.
|
||||
* Must not be NULL.
|
||||
*/
|
||||
void clist_add(clist_node_t **node, clist_node_t *new_node);
|
||||
static inline void clist_insert(clist_node_t *list, clist_node_t *new_node)
|
||||
{
|
||||
if (list->next) {
|
||||
new_node->next = list->next->next;
|
||||
list->next->next = new_node;
|
||||
}
|
||||
else {
|
||||
new_node->next = new_node;
|
||||
}
|
||||
list->next = new_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes *node* from list
|
||||
* @brief Removes and returns first element from list
|
||||
*
|
||||
* @param[in,out] list Pointer to the *list* to remove *node* from.
|
||||
* @param[in] node Node to remove from *list*
|
||||
* Must not be NULL.
|
||||
* @param[in,out] list Pointer to the *list* to remove first element
|
||||
* from.
|
||||
*/
|
||||
void clist_remove(clist_node_t **list, clist_node_t *node);
|
||||
static inline clist_node_t *clist_remove_head(clist_node_t *list)
|
||||
{
|
||||
if (list->next) {
|
||||
clist_node_t *first = list->next->next;
|
||||
if (list->next == first) {
|
||||
list->next = NULL;
|
||||
}
|
||||
else {
|
||||
list->next->next = first->next;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Advances the circle list.
|
||||
@ -75,9 +100,11 @@ void clist_remove(clist_node_t **list, clist_node_t *node);
|
||||
*
|
||||
* @param[in,out] list The list to work upon.
|
||||
*/
|
||||
static inline void clist_advance(clist_node_t **list)
|
||||
static inline void clist_advance(clist_node_t *list)
|
||||
{
|
||||
*list = (*list)->next;
|
||||
if (list->next) {
|
||||
list->next = list->next->next;
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
|
@ -167,7 +167,7 @@ extern volatile kernel_pid_t sched_active_pid;
|
||||
/**
|
||||
* List of runqueues per priority level
|
||||
*/
|
||||
extern clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS];
|
||||
extern clist_node_t sched_runqueues[SCHED_PRIO_LEVELS];
|
||||
|
||||
/**
|
||||
* @brief Removes thread from scheduler and set status to #STATUS_STOPPED
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "cpu_conf.h"
|
||||
#include "sched.h"
|
||||
#include "list.h"
|
||||
#include "clist.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -68,8 +69,8 @@
|
||||
*/
|
||||
struct _thread {
|
||||
char *sp; /**< thread's stack pointer */
|
||||
uint8_t status; /**< thread's status */
|
||||
uint8_t priority; /**< thread's priority */
|
||||
uint8_t status; /**< thread's status */
|
||||
uint8_t priority; /**< thread's priority */
|
||||
|
||||
kernel_pid_t pid; /**< thread's process id */
|
||||
|
||||
|
@ -89,7 +89,7 @@ void mutex_unlock(mutex_t *mutex)
|
||||
return;
|
||||
}
|
||||
|
||||
list_node_t *next = (list_node_t*) list_remove_head(&mutex->queue);
|
||||
list_node_t *next = list_remove_head(&mutex->queue);
|
||||
|
||||
thread_t *process = container_of((clist_node_t*)next, thread_t, rq_entry);
|
||||
|
||||
|
10
core/sched.c
10
core/sched.c
@ -50,7 +50,7 @@ volatile thread_t *sched_active_thread;
|
||||
|
||||
volatile kernel_pid_t sched_active_pid = KERNEL_PID_UNDEF;
|
||||
|
||||
clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS];
|
||||
clist_node_t sched_runqueues[SCHED_PRIO_LEVELS];
|
||||
static uint32_t runqueue_bitcache = 0;
|
||||
|
||||
#ifdef MODULE_SCHEDSTATISTICS
|
||||
@ -68,7 +68,7 @@ int sched_run(void)
|
||||
* since the threading should not be started before at least the idle thread was started.
|
||||
*/
|
||||
int nextrq = bitarithm_lsb(runqueue_bitcache);
|
||||
thread_t *next_thread = clist_get_container(sched_runqueues[nextrq], thread_t, rq_entry);
|
||||
thread_t *next_thread = container_of(sched_runqueues[nextrq].next->next, thread_t, rq_entry);
|
||||
|
||||
DEBUG("sched_run: active thread: %" PRIkernel_pid ", next thread: %" PRIkernel_pid "\n",
|
||||
(active_thread == NULL) ? KERNEL_PID_UNDEF : active_thread->pid,
|
||||
@ -133,7 +133,7 @@ void sched_set_status(thread_t *process, unsigned int status)
|
||||
if (!(process->status >= STATUS_ON_RUNQUEUE)) {
|
||||
DEBUG("sched_set_status: adding thread %" PRIkernel_pid " to runqueue %" PRIu16 ".\n",
|
||||
process->pid, process->priority);
|
||||
clist_add(&sched_runqueues[process->priority], &(process->rq_entry));
|
||||
clist_insert(&sched_runqueues[process->priority], &(process->rq_entry));
|
||||
runqueue_bitcache |= 1 << process->priority;
|
||||
}
|
||||
}
|
||||
@ -141,9 +141,9 @@ void sched_set_status(thread_t *process, unsigned int status)
|
||||
if (process->status >= STATUS_ON_RUNQUEUE) {
|
||||
DEBUG("sched_set_status: removing thread %" PRIkernel_pid " to runqueue %" PRIu16 ".\n",
|
||||
process->pid, process->priority);
|
||||
clist_remove(&sched_runqueues[process->priority], &(process->rq_entry));
|
||||
clist_remove_head(&sched_runqueues[process->priority]);
|
||||
|
||||
if (!sched_runqueues[process->priority]) {
|
||||
if (!sched_runqueues[process->priority].next) {
|
||||
runqueue_bitcache &= ~(1 << process->priority);
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +224,6 @@ kernel_pid_t thread_create(char *stack, int stacksize, char priority, int flags,
|
||||
cb->status = 0;
|
||||
|
||||
cb->rq_entry.next = NULL;
|
||||
cb->rq_entry.prev = NULL;
|
||||
|
||||
cb->wait_data = NULL;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user