clist: add circular list api
This commit is contained in:
parent
a34fd6caaa
commit
89e7a4eb47
5 changed files with 212 additions and 4 deletions
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||||
|
@ -23,7 +25,7 @@
|
||||||
* @returns Pointer to the containing structure
|
* @returns Pointer to the containing structure
|
||||||
*/
|
*/
|
||||||
#define container_of(ptr, type, member) \
|
#define container_of(ptr, type, member) \
|
||||||
((type)( (void *)(ptr) - offsetof(type, member) ))
|
((type *)( (void *)(ptr) - offsetof(type, member) ))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Do an evil raw cast.
|
* @brief Do an evil raw cast.
|
158
include/gay/clist.h
Normal file
158
include/gay/clist.h
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
/* See the end of this file for copyright and license terms. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file gay/clist.h
|
||||||
|
* @brief Plain and simple circular list implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gay/cdefs.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simple circular list header.
|
||||||
|
* Embed this into other structures to make them part of a list.
|
||||||
|
*/
|
||||||
|
struct clist {
|
||||||
|
struct clist *next;
|
||||||
|
struct clist *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declare and define a clist.
|
||||||
|
*
|
||||||
|
* @param name Name of the list
|
||||||
|
*/
|
||||||
|
#define CLIST(name) \
|
||||||
|
struct clist name = { \
|
||||||
|
.next = &name, \
|
||||||
|
.prev = &name, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a new clist.
|
||||||
|
* Use this only for dynamically allocated lists,
|
||||||
|
* there is the `CLIST()` macro for globals.
|
||||||
|
*
|
||||||
|
* @param list List to initialize
|
||||||
|
*/
|
||||||
|
void clist_init(struct clist *list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a new node at the end of a clist.
|
||||||
|
*
|
||||||
|
* @param head Head of the list
|
||||||
|
* @param new New node to insert at the end
|
||||||
|
*/
|
||||||
|
void clist_add(struct clist *head, struct clist *new);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a new node at the beginning of a clist.
|
||||||
|
*
|
||||||
|
* @param head Head of the list
|
||||||
|
* @param new New node to insert at the beginning
|
||||||
|
*/
|
||||||
|
void clist_add_first(struct clist *head, struct clist *new);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove a node from a clist.
|
||||||
|
*
|
||||||
|
* @param node Node to remove
|
||||||
|
*/
|
||||||
|
void clist_del(struct clist *node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterate over every node in a clist.
|
||||||
|
*
|
||||||
|
* @param head The `struct clist *` acting as the head of the clist
|
||||||
|
* @param cursor A `struct clist *` to use as a cursor for iteration
|
||||||
|
*/
|
||||||
|
#define clist_foreach(head, cursor) \
|
||||||
|
for ((cursor) = (head)->next; \
|
||||||
|
(cursor) != (head); \
|
||||||
|
(cursor) = (cursor)->next)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterate over every node in a clist in reverse order.
|
||||||
|
*
|
||||||
|
* @param head The `struct clist *` acting as the head of the clist
|
||||||
|
* @param cursor A `struct clist *` to use as a cursor for iteration
|
||||||
|
*/
|
||||||
|
#define clist_foreach_rev(head, cursor, member) \
|
||||||
|
for ((cursor) = (head)->prev; \
|
||||||
|
(cursor) != (head); \
|
||||||
|
(cursor) = (cursor)->prev)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the structure embedding a clist.
|
||||||
|
*
|
||||||
|
* @param node The `struct clist *` to cast out of
|
||||||
|
* @param type Type of the containing structure
|
||||||
|
* @param member Name of the `struct clist` within the containing structure
|
||||||
|
* @returns The `struct *` the list node is embedded in
|
||||||
|
*/
|
||||||
|
#define clist_entry(node, type, member) \
|
||||||
|
container_of(node, type, member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the first entry in a list.
|
||||||
|
*
|
||||||
|
* @param head The `struct clist *` that is the head node
|
||||||
|
* @param type Type of the structure embedding the list nodes
|
||||||
|
* @param member Name of the `struct clist` within the embedding structure
|
||||||
|
* @returns The `struct *` the list is embedded in
|
||||||
|
*/
|
||||||
|
#define clist_first_entry(head, type, member) \
|
||||||
|
clist_entry((head)->next, type, member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the next entry in a clist.
|
||||||
|
*
|
||||||
|
* @param entry The `struct *` embedding a clist to get the sccessor of
|
||||||
|
* @param member Name of the `struct clist` embedded within the entry
|
||||||
|
* @returns The next `struct *` in the list
|
||||||
|
*/
|
||||||
|
#define clist_next_entry(entry, member) \
|
||||||
|
clist_entry((entry)->member.next, typeof(*(entry)), member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterate over each entry within a list.
|
||||||
|
*
|
||||||
|
* @param head The `struct clist *` that is the head node in the list
|
||||||
|
* @param cursor A `struct *` the list nodes are embedded in to use as the cursor
|
||||||
|
* @param member Name of the `struct clist` within the embedding structure
|
||||||
|
*/
|
||||||
|
#define clist_foreach_entry(head, cursor, member) \
|
||||||
|
for ((cursor) = clist_first_entry(head, typeof((*cursor)), member); \
|
||||||
|
&(cursor)->member != (head); \
|
||||||
|
(cursor) = clist_next_entry(cursor, member))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Iterate over each entry within a list, this is safe from element removal.
|
||||||
|
*
|
||||||
|
* @param head The `struct clist *` that is the head node in the list
|
||||||
|
* @param cursor A `struct *` the list nodes are embedded in to use as the cursor.
|
||||||
|
* This is the element that may be removed from the list.
|
||||||
|
* @param tmp An addional `struct *` of the same type as `cursor` (don't touch)
|
||||||
|
* @param member Name of the `struct clist` within the embedding structure
|
||||||
|
*/
|
||||||
|
#define clist_foreach_entry_safe(head, cursor, tmp, member) \
|
||||||
|
for ((cursor) = clist_first_entry(head, typeof(*(cursor)), member), \
|
||||||
|
(tmp) = clist_next_entry(cursor, member); \
|
||||||
|
(tmp)->member.prev != (head); \
|
||||||
|
(cursor) = (tmp), \
|
||||||
|
(tmp) = clist_next_entry(tmp, member))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of GayBSD.
|
||||||
|
* Copyright (c) 2021 fef <owo@fef.moe>.
|
||||||
|
*
|
||||||
|
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||||
|
* modify it under the terms of the Cooperative Nonviolent Public License
|
||||||
|
* (CNPL) as found in the LICENSE file in the source code root directory
|
||||||
|
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||||
|
* of the license, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||||
|
* permitted by applicable law. See the CNPL for details.
|
||||||
|
*/
|
|
@ -2,11 +2,12 @@
|
||||||
|
|
||||||
add_library(gay_kernel STATIC)
|
add_library(gay_kernel STATIC)
|
||||||
target_include_directories(gay_kernel PRIVATE ${GAY_INCLUDE_DIRS})
|
target_include_directories(gay_kernel PRIVATE ${GAY_INCLUDE_DIRS})
|
||||||
target_compile_definitions(gay_kernel INTERFACE ${GAY_KERNEL_DIFINITIONS})
|
target_compile_definitions(gay_kernel INTERFACE ${GAY_KERNEL_DEFINITIONS})
|
||||||
|
|
||||||
target_link_libraries(gay_kernel PRIVATE c)
|
target_link_libraries(gay_kernel PRIVATE c)
|
||||||
|
|
||||||
target_sources(gay_kernel PRIVATE
|
target_sources(gay_kernel PRIVATE
|
||||||
|
clist.c
|
||||||
kprintf.c
|
kprintf.c
|
||||||
main.c
|
main.c
|
||||||
)
|
)
|
||||||
|
|
47
kernel/clist.c
Normal file
47
kernel/clist.c
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* See the end of this file for copyright and license terms. */
|
||||||
|
|
||||||
|
#include <gay/clist.h>
|
||||||
|
|
||||||
|
void clist_init(struct clist *head)
|
||||||
|
{
|
||||||
|
head->next = head;
|
||||||
|
head->prev = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clist_add(struct clist *head, struct clist *new)
|
||||||
|
{
|
||||||
|
head->next->prev = new;
|
||||||
|
new->next = head->next;
|
||||||
|
|
||||||
|
new->prev = head;
|
||||||
|
head->next = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clist_add_end(struct clist *head, struct clist *new)
|
||||||
|
{
|
||||||
|
head->prev->next = new;
|
||||||
|
new->next = head;
|
||||||
|
|
||||||
|
new->prev = head->prev;
|
||||||
|
head->prev = new;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clist_del(struct clist *node)
|
||||||
|
{
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
node->prev->next = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of GayBSD.
|
||||||
|
* Copyright (c) 2021 fef <owo@fef.moe>.
|
||||||
|
*
|
||||||
|
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||||
|
* modify it under the terms of the Cooperative Nonviolent Public License
|
||||||
|
* (CNPL) as found in the LICENSE file in the source code root directory
|
||||||
|
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||||
|
* of the license, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||||
|
* permitted by applicable law. See the CNPL for details.
|
||||||
|
*/
|
|
@ -3,11 +3,11 @@
|
||||||
#include <stdarg.h> /* from clang */
|
#include <stdarg.h> /* from clang */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gay/cdefs.h>
|
||||||
#include <gay/config.h>
|
#include <gay/config.h>
|
||||||
#include <gay/errno.h>
|
#include <gay/errno.h>
|
||||||
#include <gay/kprintf.h>
|
#include <gay/kprintf.h>
|
||||||
#include <gay/types.h>
|
#include <gay/types.h>
|
||||||
#include <gay/util.h>
|
|
||||||
|
|
||||||
#if __SIZEOF_INT__ == 2
|
#if __SIZEOF_INT__ == 2
|
||||||
/* 5 decimal digits of 65535 (2 ** 16 - 1) */
|
/* 5 decimal digits of 65535 (2 ** 16 - 1) */
|
||||||
|
|
Loading…
Reference in a new issue