panic: move to separate file, add KASSERT macro
This commit is contained in:
parent
24c6e9504d
commit
b6385aea0a
10 changed files with 100 additions and 34 deletions
|
@ -28,6 +28,9 @@ configure_file(
|
|||
|
||||
include("arch/${ARCH}/config/toolchain.cmake")
|
||||
|
||||
# Used by the KASSERT macro for printing the filename relative to the source root
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pipe -nostdinc -ffreestanding -fno-stack-protector")
|
||||
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -pipe -D_ASM_SOURCE")
|
||||
if(DEBUG)
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
*/
|
||||
#define __packed __attribute__(( packed ))
|
||||
|
||||
#define __printflike(fmt_argn, firstva_argn) \
|
||||
__attribute__(( format(printf, fmt_argn, firstva_argn) ))
|
||||
|
||||
/**
|
||||
* @brief Function does not have any side effects or internal state.
|
||||
* Subsequent calls with the same parameters always return the same result.
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
* @returns The amount of bytes written,
|
||||
* or a negative number from `errno.h` on failure
|
||||
*/
|
||||
__attribute__(( format(printf, 1, 2) ))
|
||||
int kprintf(const char *__restrict fmt, ...);
|
||||
int kprintf(const char *__restrict fmt, ...) __printflike(1, 2);
|
||||
|
||||
/**
|
||||
* @brief Print to the kernel log.
|
||||
|
@ -29,7 +28,7 @@ int kprintf(const char *__restrict fmt, ...);
|
|||
* @returns The amount of bytes written,
|
||||
* or a negative number from `errno.h` on failure
|
||||
*/
|
||||
int kvprintf(const char *__restrict fmt, va_list args);
|
||||
int kvprintf(const char *__restrict fmt, va_list args) __printflike(1, 0);
|
||||
|
||||
/**
|
||||
* @brief Printing functions that `kprintf()` and friends call for writing.
|
||||
|
|
|
@ -25,6 +25,11 @@ struct task {
|
|||
tcb_t tcb;
|
||||
struct task *parent;
|
||||
pid_t pid;
|
||||
/**
|
||||
* @brief 0 = interruptable, > 0 = uninterruptible, < 0 = we messed up.
|
||||
* Increment/decrement using `critical_enter()`/`critical_leave()`.
|
||||
*/
|
||||
volatile int critnest;
|
||||
enum task_state state;
|
||||
};
|
||||
|
||||
|
|
64
include/gay/systm.h
Normal file
64
include/gay/systm.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* See the end of this file for copyright and license terms. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gay/cdefs.h>
|
||||
#include <gay/sched.h>
|
||||
#include <gay/types.h>
|
||||
|
||||
/**
|
||||
* @brief Print an error message and halt the system immediately.
|
||||
*
|
||||
* @param fmt printf style format string
|
||||
*/
|
||||
void panic(const char *fmt, ...) __noreturn __printflike(1, 2);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* @brief Assert that statement `x` is true.
|
||||
* If it is not and debugging is enabled, the kernel panics.
|
||||
*/
|
||||
#define KASSERT(x) do { \
|
||||
if ( __predict_false(!(x)) ) { \
|
||||
panic("Assertion \"%s\" failed!\n" \
|
||||
" in function %s()\n" \
|
||||
" in file %s, line %u\n", \
|
||||
#x, __func__, __FILENAME__, __LINE__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define KASSERT(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline void critical_enter(void)
|
||||
{
|
||||
struct task *tsk = current;
|
||||
tsk->critnest++;
|
||||
}
|
||||
|
||||
static inline void critical_leave(void)
|
||||
{
|
||||
struct task *tsk = current;
|
||||
tsk->critnest--;
|
||||
|
||||
KASSERT(tsk->critnest >= 0);
|
||||
}
|
||||
|
||||
static inline bool in_critical(void)
|
||||
{
|
||||
return current->critnest > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
|
@ -5,8 +5,6 @@
|
|||
#include <gay/cdefs.h>
|
||||
#include <gay/types.h>
|
||||
|
||||
void panic(const char *fmt, ...) __noreturn;
|
||||
|
||||
/**
|
||||
* @brief Get the number of elements in a statically allocated array.
|
||||
*
|
||||
|
@ -49,20 +47,20 @@ static __always_inline bool sus_nil(const void *ptr)
|
|||
return ptr < (void *)0x1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Align `ptr` such that `ptr % n == 0`.
|
||||
*
|
||||
* @param ptr Pointer to align
|
||||
* @param log The log2 of the alignment. If negative, the pointer will be
|
||||
* aligned to the next lower address, otherwise to the next higher one.
|
||||
* @returns The aligned pointer
|
||||
*/
|
||||
void *ptr_align(void *ptr, int log);
|
||||
|
||||
static __always_inline uintptr_t uintptr_align(uintptr_t ptr, int log)
|
||||
static __always_inline uintptr_t _align_floor(uintptr_t ptr, usize size)
|
||||
{
|
||||
return (uintptr_t)ptr_align((void *)ptr, log);
|
||||
return ptr - ptr % size;
|
||||
}
|
||||
#define align_floor(ptr, size) ( (typeof(ptr))_align_floor((uintptr_t)(ptr), size) )
|
||||
|
||||
static __always_inline uintptr_t _align_ceil(uintptr_t ptr, usize size)
|
||||
{
|
||||
uintptr_t aligned = ptr - ptr % size;
|
||||
if (aligned < ptr)
|
||||
aligned += size;
|
||||
return aligned;
|
||||
}
|
||||
#define align_ceil(ptr, size) ( (typeof(ptr))_align_ceil((uintptr_t)(ptr), size) )
|
||||
|
||||
/*
|
||||
* This file is part of GayBSD.
|
||||
|
|
|
@ -13,8 +13,8 @@ target_sources(gay_kernel PRIVATE
|
|||
kprintf.c
|
||||
main.c
|
||||
mutex.c
|
||||
panic.c
|
||||
sched.c
|
||||
util.c
|
||||
)
|
||||
|
||||
add_subdirectory(mm)
|
||||
|
|
|
@ -38,7 +38,7 @@ int kmalloc_init(uintptr_t _phys_start, uintptr_t _phys_end)
|
|||
phys_start = image_end_phys;
|
||||
}
|
||||
|
||||
phys_start = uintptr_align(phys_start, +HUGEPAGE_SHIFT);
|
||||
phys_start = align_ceil(phys_start, HUGEPAGE_SIZE);
|
||||
/*
|
||||
* This is intentionally not aligned to hugepages, because __early_get_page()
|
||||
* shrinks it in single PAGE_SIZE steps whenever it is called anyway.
|
||||
|
@ -48,7 +48,7 @@ int kmalloc_init(uintptr_t _phys_start, uintptr_t _phys_end)
|
|||
* be able to allocate pages before the page frame allocator is set up
|
||||
* in the first place).
|
||||
*/
|
||||
phys_end = uintptr_align(phys_end, -PAGE_SHIFT);
|
||||
phys_end = align_floor(phys_end, PAGE_SIZE);
|
||||
|
||||
int err = pages_init();
|
||||
if (err)
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
#include <arch/cpufunc.h>
|
||||
|
||||
#include <gay/cdefs.h>
|
||||
#include <gay/config.h>
|
||||
#include <gay/kprintf.h>
|
||||
#include <gay/types.h>
|
||||
#include <gay/util.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
__noreturn
|
||||
void panic(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -21,7 +22,7 @@ void panic(const char *fmt, ...)
|
|||
else
|
||||
kvprintf(fmt, args);
|
||||
|
||||
kprintf("\nSystem halted");
|
||||
kprintf("\nKernel version: %s\nSystem halted", GAY_VERSION_STR);
|
||||
|
||||
/* no need for va_end() here i guess */
|
||||
while (1) {
|
||||
|
@ -30,17 +31,6 @@ void panic(const char *fmt, ...)
|
|||
}
|
||||
}
|
||||
|
||||
void *ptr_align(void *ptr, int log)
|
||||
{
|
||||
uintptr_t shifted = 1 << abs(log);
|
||||
uintptr_t aligned = (uintptr_t)ptr & ~(shifted - 1);
|
||||
|
||||
if (log > 0 && aligned != (uintptr_t)ptr)
|
||||
aligned += shifted;
|
||||
|
||||
return (void *)aligned;
|
||||
}
|
||||
|
||||
/*
|
||||
* This file is part of GayBSD.
|
||||
* Copyright (c) 2021 fef <owo@fef.moe>.
|
|
@ -11,6 +11,7 @@ struct task kernel_task = {
|
|||
.parent = nil,
|
||||
.pid = 0,
|
||||
.state = TASK_READY,
|
||||
.critnest = 0,
|
||||
};
|
||||
|
||||
struct task *current_array[CFG_MAX_CPU] = {
|
||||
|
@ -40,6 +41,9 @@ void schedule(void)
|
|||
struct task *old = current;
|
||||
struct task *new = nil;
|
||||
|
||||
if (old->critnest)
|
||||
return;
|
||||
|
||||
clist_add(inactive_queue, &old->run_queue);
|
||||
|
||||
/* Dijkstra would be so mad if he saw this */
|
||||
|
|
Loading…
Reference in a new issue