clist: add circular list api

main
anna 3 years ago
parent a34fd6caaa
commit 89e7a4eb47
Signed by: fef
GPG Key ID: EC22E476DC2D3D84

@ -2,7 +2,9 @@
#pragma once
#include <stddef.h>
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef offsetof
#define offsetof(type, member) __builtin_offsetof(type, member)
@ -23,7 +25,7 @@
* @returns Pointer to the containing structure
*/
#define container_of(ptr, type, member) \
((type)( (void *)(ptr) - offsetof(type, member) ))
((type *)( (void *)(ptr) - offsetof(type, member) ))
/**
* @brief Do an evil raw cast.

@ -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)
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_sources(gay_kernel PRIVATE
clist.c
kprintf.c
main.c
)

@ -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 <string.h>
#include <gay/cdefs.h>
#include <gay/config.h>
#include <gay/errno.h>
#include <gay/kprintf.h>
#include <gay/types.h>
#include <gay/util.h>
#if __SIZEOF_INT__ == 2
/* 5 decimal digits of 65535 (2 ** 16 - 1) */

Loading…
Cancel
Save