clist: add better debugging facilities

main
anna 3 years ago
parent 2b3eaf4ff7
commit c66b05216d
Signed by: fef
GPG Key ID: EC22E476DC2D3D84

@ -14,7 +14,9 @@ option(CFG_POISON_PAGES "Poison pages after allocate and free" ON)
option(CFG_POISON_HEAP "Poison heap memory after kmalloc() and kfree()" ON)
option(CFG_DEBUG_IRQ "Debug IRQs" ON)
option(CFG_DEBUG_IRQ "Debug IRQs" ${DEBUG})
option(CFG_DEBUG_CLIST "Sanitize clist operations" ${DEBUG})
option(CFG_DEBUG_PAGE_ALLOCS "Debug page frame allocations" OFF)

@ -7,6 +7,7 @@
#pragma once
#include <gay/config.h>
#include <gay/util.h>
/**
@ -62,6 +63,26 @@ void clist_add_first(struct clist *head, struct clist *new);
*/
void clist_del(struct clist *node);
/**
* @brief Remove and return the first node in a clist.
* If the list is empty and `CFG_DEBUG_CLIST` is defined, this returns nil.
* If `CFG_DEBUG_CLIST` is not defined in this case, it will blow up.
*
* @param head Head of the list
* @return The deleted node
*/
struct clist *clist_del_first(struct clist *head);
/**
* @brief Remove and return the last node in a clist.
* If the list is empty and `CFG_DEBUG_CLIST` is defined, this returns nil.
* If `CFG_DEBUG_CLIST` is not defined in this case, it will blow up.
*
* @param head Head of the list
* @return The deleted node
*/
struct clist *clist_del_last(struct clist *head);
/**
* @brief Return whether a clist is empty.
*

@ -34,6 +34,9 @@
/** @brief Debug IRQs */
#cmakedefine01 CFG_DEBUG_IRQ
/** @brief Sanitize clist operations */
#cmakedefine01 CFG_DEBUG_CLIST
/** @brief Debug page frame allocations */
#cmakedefine01 CFG_DEBUG_PAGE_ALLOCS

@ -41,17 +41,11 @@
#define container_of(ptr, type, member) \
((type *)( (void *)(ptr) - offsetof(type, member) ))
/**
* @brief Do an evil raw cast.
*
* @param type Type to cast to
* @param expr Expression to cast
* @returns The raw value of `expr`, cast to `type`
*/
#define raw_cast(type, expr) ({ \
typeof(expr) __expr = (expr); \
*(type *)&__expr; \
})
/** @brief Determine whether `ptr` is kinda sus. */
static __always_inline bool sus_nil(const void *ptr)
{
return ptr < (void *)0x1000;
}
/**
* @brief Align `ptr` such that `ptr % n == 0`.

@ -2,15 +2,32 @@
#include <gay/clist.h>
#include <gay/config.h>
#include <gay/kprintf.h>
void clist_init(struct clist *head)
{
# if CFG_DEBUG_CLIST
if (head->next == head && head->prev == head)
kprintf("clist_init(%p) called multiple times\n", head);
# endif
head->next = head;
head->prev = head;
}
void clist_add(struct clist *head, struct clist *new)
{
# if CFG_DEBUG_CLIST
if (sus_nil(head->next) || sus_nil(head->prev)) {
kprintf("clist_add(%p, %p): head seems uninitialized\n", head, new);
return;
}
if (sus_nil(new)) {
kprintf("clist_add(%p, %p): new node is NULL!\n", head, new);
return;
}
# endif
head->prev->next = new;
new->next = head;
@ -32,10 +49,38 @@ void clist_del(struct clist *node)
node->next->prev = node->prev;
node->prev->next = node->next;
# ifdef DEBUG
node->next = NULL;
node->prev = NULL;
# if CFG_DEBUG_CLIST
node->next = nil;
node->prev = nil;
# endif
}
struct clist *clist_del_first(struct clist *head)
{
# if CFG_DEBUG_CLIST
if (clist_is_empty(head)) {
kprintf("clist_del_first(%p): empty list!\n", head);
return nil;
}
# endif
struct clist *first = head->next;
clist_del(first);
return first;
}
struct clist *clist_del_last(struct clist *head)
{
# ifdef CFG_DEBUG_CLIST
if (clist_is_empty(head)) {
kprintf("clist_del_last(%p): empty list!\n", head);
return nil;
}
# endif
struct clist *last = head->prev;
clist_del(last);
return last;
}
/*

Loading…
Cancel
Save