clist: add better debugging facilities
This commit is contained in:
parent
2b3eaf4ff7
commit
c66b05216d
5 changed files with 80 additions and 15 deletions
|
@ -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,12 +49,40 @@ 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* This file is part of GayBSD.
|
||||
* Copyright (c) 2021 fef <owo@fef.moe>.
|
||||
|
|
Loading…
Reference in a new issue