aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2026-08-29 10:53:39 +0200
committerFelix Morgner <felix.morgner@ost.ch>2026-08-29 10:53:39 +0200
commit0824a76b4f7294a74f4728084ca13070a4c8e7da (patch)
tree94804942a9119ad8666f7b3cdf6b2f80503a2a93
parent1e24d2b3cd4315fff4177c593bcfeef5b354f612 (diff)
downloadkernel-0824a76b4f7294a74f4728084ca13070a4c8e7da.tar.xz
kernel-0824a76b4f7294a74f4728084ca13070a4c8e7da.zip
chore: normalize panic messages
-rw-r--r--arch/x86_64/arch/bus/cpu.cpp2
-rw-r--r--arch/x86_64/arch/cpu/initialization.cpp4
-rw-r--r--arch/x86_64/arch/cpu/interrupts.cpp6
-rw-r--r--arch/x86_64/arch/devices/init.cpp4
-rw-r--r--arch/x86_64/arch/drivers/cpu/lapic.cpp6
-rw-r--r--arch/x86_64/arch/memory/higher_half_mapper.cpp4
-rw-r--r--arch/x86_64/arch/memory/kernel_mapper.cpp6
-rw-r--r--arch/x86_64/kapi/boot_modules.cpp2
-rw-r--r--arch/x86_64/kapi/cpu.cpp2
-rw-r--r--arch/x86_64/kapi/devices.cpp6
-rw-r--r--arch/x86_64/kapi/memory.cpp18
-rw-r--r--docs/code_style.md498
-rw-r--r--kernel/kapi/cpu.cpp2
-rw-r--r--kernel/kapi/devices/driver_registry.cpp4
-rw-r--r--kernel/kapi/devices/facet_registry.cpp4
-rw-r--r--kernel/kapi/memory.cpp10
-rw-r--r--kernel/kernel/filesystems/ext2/directory_iterator.cpp6
-rw-r--r--kernel/kernel/filesystems/ext2/filesystem.cpp2
-rw-r--r--kernel/kernel/filesystems/ext2/inode.cpp2
-rw-r--r--kernel/kernel/filesystems/ext2/write_batch.cpp6
-rw-r--r--kernel/kernel/main.cpp2
-rw-r--r--kernel/kernel/memory/block_list_allocator.cpp2
-rw-r--r--kernel/kernel/memory/operators.cpp2
-rw-r--r--kernel/kernel/vfs.cpp28
-rw-r--r--kernel/kernel/vfs/dentry.cpp4
-rw-r--r--kernel/kernel/vfs/device_inode.cpp4
-rw-r--r--kernel/kernel/vfs/driver_registry.cpp8
-rw-r--r--kernel/kernel/vfs/mount.cpp6
-rw-r--r--kernel/kernel/vfs/open_file_descriptor.cpp4
-rw-r--r--kernel/kernel/vfs/open_file_table.cpp4
-rw-r--r--libs/acpi/acpi/data/madt.hpp2
-rw-r--r--libs/kstd/kstd/bits/basic_string.hpp30
-rw-r--r--libs/kstd/kstd/bits/format/context.hpp2
-rw-r--r--libs/kstd/kstd/bits/format/error.hpp2
-rw-r--r--libs/kstd/kstd/bits/format/formatter/ordering.hpp6
-rw-r--r--libs/kstd/kstd/bits/mutex/mutex.cpp2
-rw-r--r--libs/kstd/kstd/bits/observer_ptr.hpp2
-rw-r--r--libs/kstd/kstd/flat_map.hpp8
-rw-r--r--libs/kstd/kstd/libc/stdlib.cpp2
-rw-r--r--libs/kstd/kstd/vector.hpp8
40 files changed, 610 insertions, 112 deletions
diff --git a/arch/x86_64/arch/bus/cpu.cpp b/arch/x86_64/arch/bus/cpu.cpp
index 4b9edffc..a21d910d 100644
--- a/arch/x86_64/arch/bus/cpu.cpp
+++ b/arch/x86_64/arch/bus/cpu.cpp
@@ -36,7 +36,7 @@ namespace arch::bus
auto madt = kapi::acpi::get_table<::acpi::table_signature_v<::acpi::madt>>();
if (!madt)
{
- kstd::println("[x86_64:BUS] Failed to find ACPI APIC table");
+ kstd::println("[ARCH:BUS] Failed to find ACPI APIC table");
return;
}
diff --git a/arch/x86_64/arch/cpu/initialization.cpp b/arch/x86_64/arch/cpu/initialization.cpp
index 49870eb7..83493fe3 100644
--- a/arch/x86_64/arch/cpu/initialization.cpp
+++ b/arch/x86_64/arch/cpu/initialization.cpp
@@ -123,10 +123,10 @@ namespace arch::cpu
gdt_user_code_descriptor, gdt_user_data_descriptor, tss_descriptor,
};
- kstd::println("[x86_64:SYS] Reloading Global Descriptor Table.");
+ kstd::println("[ARCH:SYS] Reloading Global Descriptor Table.");
gdt.load(1, 2);
- kstd::println("[x86_64:SYS] Initializing Interrupt Descriptor Table.");
+ kstd::println("[ARCH:SYS] Initializing Interrupt Descriptor Table.");
auto static idt = interrupt_descriptor_table{};
idt.load();
}
diff --git a/arch/x86_64/arch/cpu/interrupts.cpp b/arch/x86_64/arch/cpu/interrupts.cpp
index 99186e2d..c825e8ab 100644
--- a/arch/x86_64/arch/cpu/interrupts.cpp
+++ b/arch/x86_64/arch/cpu/interrupts.cpp
@@ -141,11 +141,11 @@ namespace arch::cpu
if (has_error_code(static_cast<exception>(number)))
{
kstd::println(kstd::print_sink::stderr,
- "[x86_64:CPU] Unhandled exception number {:#04x} received with code {:#04x}", number, code);
+ "[ARCH:CPU] Unhandled exception number {:#04x} received with code {:#04x}", number, code);
}
else
{
- kstd::println(kstd::print_sink::stderr, "[x86_64:CPU] Unhandled exception number {:#04x} received", number);
+ kstd::println(kstd::print_sink::stderr, "[ARCH:CPU] Unhandled exception number {:#04x} received", number);
}
}
}
@@ -155,7 +155,7 @@ namespace arch::cpu
if (kapi::interrupts::dispatch(irq_number) == kapi::interrupts::status::unhandled)
{
- kstd::println(kstd::print_sink::stderr, "[x86_64:CPU] Unhandled interrupt {:#04x} (IRQ{})", number,
+ kstd::println(kstd::print_sink::stderr, "[ARCH:CPU] Unhandled interrupt {:#04x} (IRQ{})", number,
irq_number);
}
diff --git a/arch/x86_64/arch/devices/init.cpp b/arch/x86_64/arch/devices/init.cpp
index 9c20d413..639e8870 100644
--- a/arch/x86_64/arch/devices/init.cpp
+++ b/arch/x86_64/arch/devices/init.cpp
@@ -46,7 +46,7 @@ namespace arch::devices
{
if (kapi::acpi::init(*acpi_root_pointer))
{
- kstd::println("[x86_64:DEV] ACPI subsystem initialized.");
+ kstd::println("[ARCH:DEV] ACPI subsystem initialized.");
}
}
@@ -55,7 +55,7 @@ namespace arch::devices
auto init_legacy_devices() -> void
{
- kstd::println("[x86_64:DEV] Initializing ISA bus...");
+ kstd::println("[ARCH:DEV] Initializing ISA bus...");
auto root_bus = kapi::devices::get_root_bus();
auto isa_bus = kstd::make_shared<arch::bus::isa>();
diff --git a/arch/x86_64/arch/drivers/cpu/lapic.cpp b/arch/x86_64/arch/drivers/cpu/lapic.cpp
index f8aa8e90..c02c3df6 100644
--- a/arch/x86_64/arch/drivers/cpu/lapic.cpp
+++ b/arch/x86_64/arch/drivers/cpu/lapic.cpp
@@ -126,7 +126,7 @@ namespace arch::drivers::cpu
if (!kapi::memory::map_mmio_region(m_mapped_region, kapi::memory::physical_address{mmio->start},
kapi::memory::page_mapper::flags::writable))
{
- kstd::println(kstd::print_sink::stderr, "[x86_64:DRV] LAPIC {} MMIO mapping failed!", signature->hardware_id());
+ kstd::println(kstd::print_sink::stderr, "[ARCH:DRV] LAPIC {} MMIO mapping failed!", signature->hardware_id());
return kstd::failure(make_error_code(kstd::errc::io_error));
}
@@ -142,12 +142,12 @@ namespace arch::drivers::cpu
write_register(registers::spurious_interrupt_vector, lapic_enable_bit | spurious_interrupt_vector);
- kstd::println("[x86_64:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}",
+ kstd::println("[ARCH:DRV] LAPIC initialized. version: {#x} | max_lvt_entry: {} | eoi_suppression: {:s}",
version, highest_lvt_entry_index, supports_eoi_broadcast_suppression);
}
else
{
- kstd::println("[x86_64:DRV] LAPIC {} is not on the BSP, deferring initialization.", signature->hardware_id());
+ kstd::println("[ARCH:DRV] LAPIC {} is not on the BSP, deferring initialization.", signature->hardware_id());
}
return kstd::success();
diff --git a/arch/x86_64/arch/memory/higher_half_mapper.cpp b/arch/x86_64/arch/memory/higher_half_mapper.cpp
index 75adb3c5..974b00a0 100644
--- a/arch/x86_64/arch/memory/higher_half_mapper.cpp
+++ b/arch/x86_64/arch/memory/higher_half_mapper.cpp
@@ -33,7 +33,7 @@ namespace arch::memory
if (entry.present())
{
- kapi::system::panic("[x86_64:MEM] Tried to map a page that is already mapped!");
+ kapi::system::panic("[ARCH:MEM] Tried to map a page that is already mapped!");
}
entry.frame(frame, to_table_flags(flags) | page_table::entry::flags::present);
@@ -45,7 +45,7 @@ namespace arch::memory
{
if (!try_unmap(page))
{
- kapi::system::panic("[x86_64:MEM] Tried to unmap a page that is not mapped!");
+ kapi::system::panic("[ARCH:MEM] Tried to unmap a page that is not mapped!");
}
}
diff --git a/arch/x86_64/arch/memory/kernel_mapper.cpp b/arch/x86_64/arch/memory/kernel_mapper.cpp
index a15a1d9e..070a7866 100644
--- a/arch/x86_64/arch/memory/kernel_mapper.cpp
+++ b/arch/x86_64/arch/memory/kernel_mapper.cpp
@@ -50,7 +50,7 @@ namespace arch::memory
auto elf_information = m_mbi->maybe_elf_symbols<elf::format::elf64>();
if (!elf_information)
{
- kapi::system::panic("[x86_64:MEM] ELF section information is not available.");
+ kapi::system::panic("[ARCH:MEM] ELF section information is not available.");
}
auto sections = *elf_information;
@@ -64,7 +64,7 @@ namespace arch::memory
if (allocated_sections.empty())
{
- kapi::system::panic("[x86_64:MEM] No allocated ELF sections were found.");
+ kapi::system::panic("[ARCH:MEM] No allocated ELF sections were found.");
}
std::ranges::for_each(allocated_sections,
@@ -78,7 +78,7 @@ namespace arch::memory
auto linear_start_address = kapi::memory::linear_address{section.virtual_load_address};
auto physical_start_address = kapi::memory::physical_address{section.virtual_load_address & ~m_kernel_load_base};
- kstd::println("[x86_64:MEM] mapping {}"
+ kstd::println("[ARCH:MEM] mapping {}"
"\n {} bytes -> page count: {}"
"\n {} @ {}",
name, section.size, number_of_pages, linear_start_address, physical_start_address);
diff --git a/arch/x86_64/kapi/boot_modules.cpp b/arch/x86_64/kapi/boot_modules.cpp
index 607aca4e..95ed0287 100644
--- a/arch/x86_64/kapi/boot_modules.cpp
+++ b/arch/x86_64/kapi/boot_modules.cpp
@@ -25,7 +25,7 @@ namespace kapi::boot_modules
auto init(kapi::devices::bus & bus) -> void
{
- kstd::println("[x86_64:BOOT_MODULES] Attaching boot modules.");
+ kstd::println("[ARCH:BOOT_MODULES] Attaching boot modules.");
auto modules = boot::bootstrap_information.mbi->modules();
diff --git a/arch/x86_64/kapi/cpu.cpp b/arch/x86_64/kapi/cpu.cpp
index 2bec841c..11a12656 100644
--- a/arch/x86_64/kapi/cpu.cpp
+++ b/arch/x86_64/kapi/cpu.cpp
@@ -15,7 +15,7 @@ namespace kapi::cpu
if (is_initialized.test_and_set())
{
- system::panic("[x86_64] CPU has already been initialized.");
+ system::panic("[ARCH:CPU] CPU has already been initialized.");
}
arch::cpu::initialize_descriptors();
diff --git a/arch/x86_64/kapi/devices.cpp b/arch/x86_64/kapi/devices.cpp
index 1e2fedd6..39dbc010 100644
--- a/arch/x86_64/kapi/devices.cpp
+++ b/arch/x86_64/kapi/devices.cpp
@@ -39,7 +39,7 @@ namespace kapi::devices
for (auto driver : descriptors)
{
auto instance = driver->make_instance();
- kstd::println("[x86_64:DRV] registering driver '{}' ({})", instance->name(), driver->name());
+ kstd::println("[ARCH:DRV] registering driver '{}' ({})", instance->name(), driver->name());
kapi::devices::driver_registry::get().add(std::move(instance));
}
}
@@ -54,7 +54,7 @@ namespace kapi::devices
{
if (!cpu_bus)
{
- system::panic("[x86_64:DEV] The CPU topology has not yet been initialized!");
+ system::panic("[ARCH:DEV] The CPU topology has not yet been initialized!");
}
return cpu_bus;
@@ -64,7 +64,7 @@ namespace kapi::devices
{
if (cpu_bus)
{
- system::panic("[x86_64:DEV] The CPU topology has already been initialized!");
+ system::panic("[ARCH:DEV] The CPU topology has already been initialized!");
}
cpu_bus = kstd::make_shared<arch::bus::cpu>();
diff --git a/arch/x86_64/kapi/memory.cpp b/arch/x86_64/kapi/memory.cpp
index 37b4c7f3..9cf955e5 100644
--- a/arch/x86_64/kapi/memory.cpp
+++ b/arch/x86_64/kapi/memory.cpp
@@ -45,7 +45,7 @@ namespace kapi::memory
auto memory_map = boot::bootstrap_information.mbi->maybe_memory_map();
if (!memory_map)
{
- system::panic("[x86_64] Failed to create early allocator, no memory map available.");
+ system::panic("[ARCH:MEM] Failed to create early allocator, no memory map available.");
}
auto const & mbi = boot::bootstrap_information.mbi;
@@ -157,7 +157,7 @@ namespace kapi::memory
auto next_free_frame = region_based_allocator->next_free_frame();
if (!next_free_frame)
{
- system::panic("[x86_64:MEM] No more free memory!");
+ system::panic("[ARCH:MEM] No more free memory!");
}
std::ranges::for_each(std::views::iota(kapi::memory::frame{}, *next_free_frame),
@@ -196,26 +196,26 @@ namespace kapi::memory
if (is_initialized.test_and_set())
{
- system::panic("[x86_64] Memory management has already been initialized.");
+ system::panic("[ARCH:MEM] Memory management has already been initialized.");
}
- kstd::println("[x86_64:MEM] Enabling additional CPU protection features.");
+ kstd::println("[ARCH:MEM] Enabling additional CPU protection features.");
enable_cpu_protections();
region_based_allocator.emplace(collect_memory_information());
set_frame_allocator(*region_based_allocator);
- kstd::println("[x86_64:MEM] Establishing higher-half direct mapping.");
+ kstd::println("[ARCH:MEM] Establishing higher-half direct mapping.");
establish_higher_half_direct_mapping();
- kstd::println("[x86_64:MEM] Preparing new paging hierarchy.");
+ kstd::println("[ARCH:MEM] Preparing new paging hierarchy.");
auto new_pml4_frame = kapi::memory::allocate_frame();
if (!new_pml4_frame)
{
- system::panic("[x86_64:MEM] Failed to allocate new PML4!");
+ system::panic("[ARCH:MEM] Failed to allocate new PML4!");
}
auto new_pml4 = arch::memory::to_higher_half_pointer<arch::memory::page_table>(new_pml4_frame->start_address());
std::construct_at(new_pml4);
@@ -232,7 +232,7 @@ namespace kapi::memory
auto old_pml4 = static_cast<arch::memory::page_table *>(current_cr3.address());
(*new_pml4)[256] = (*old_pml4)[256];
- kstd::println("[x86_64:MEM] Switching to new paging hierarchy.");
+ kstd::println("[ARCH:MEM] Switching to new paging hierarchy.");
auto cr3 = arch::cpu::cr3::read();
cr3.frame(*new_pml4_frame);
@@ -246,7 +246,7 @@ namespace kapi::memory
init_pmm(frame::containing(physical_address{highest_byte}).number() + 1, handoff_to_kernel_pmm);
- kstd::println("[x86_64:MEM] Releasing bootstrap memory allocators.");
+ kstd::println("[ARCH:MEM] Releasing bootstrap memory allocators.");
region_based_allocator.reset();
}
diff --git a/docs/code_style.md b/docs/code_style.md
new file mode 100644
index 00000000..f417a047
--- /dev/null
+++ b/docs/code_style.md
@@ -0,0 +1,498 @@
+# TeachOS C++ Code Style Guide
+
+This document codifies the C++ coding idioms used throughout the TeachOS kernel.
+It covers language usage, ownership and lifetime models, algorithm selection, error
+propagation, class design, and naming conventions. It does **not** cover token-level
+formatting, which is enforced automatically by the `.clang-format` configuration.
+
+---
+
+## 1. Language Standard and Vocabulary
+
+TeachOS targets **C++23** without compiler extensions (`CMAKE_CXX_EXTENSIONS NO`).
+Standard library features may be used freely where a hosted implementation is
+available (i.e., in `libs/`, `kapi/`, and `kernel/`), but the project ships its own
+standard library subset in `libs/kstd/`. **kstd types must be preferred over their
+`std::` equivalents** wherever a kstd equivalent exists.
+
+| Concept | Preferred | Avoid |
+|---|---|---|
+| Dynamic array | `kstd::vector<T>` | `std::vector<T>` |
+| String (owning) | `kstd::string` | `std::string` |
+| String view | `std::string_view` | (kstd has no alias; use `std::string_view` directly) |
+| Non-owning pointer | `kstd::observer_ptr<T>` | raw `T*` for ownership-neutral access |
+| Shared ownership | `kstd::shared_ptr<T>` | `std::shared_ptr<T>` |
+| Unique ownership | `kstd::unique_ptr<T>` | `std::unique_ptr<T>` |
+| Failable results | `kstd::result<T>` | exceptions, output parameters, `std::optional` for errors |
+| Printing | `kstd::println(...)` | `std::println(...)`, `printf` |
+
+`std::string_view`, `std::span`, `std::array`, `std::optional`, `std::byte`, and the
+`std::ranges` and `std::views` namespaces are used directly from the standard library
+because they have no kstd equivalents.
+
+---
+
+## 2. Function Declarations — Trailing Return Types
+
+**All** functions and member functions use trailing return type syntax, including those
+returning `void`.
+
+```cpp
+// Correct
+auto device_registry::get() -> device_registry &;
+auto bitmap_is_set(std::span<std::byte const> bitmap, std::size_t index) -> bool;
+auto init() -> void;
+
+// Wrong
+device_registry & device_registry::get();
+bool bitmap_is_set(std::span<std::byte const> bitmap, std::size_t index);
+void init();
+```
+
+This rule applies to: free functions, member functions, lambdas with explicit return
+types, and virtual functions. The only exception is constructors and destructors,
+which have no return type at all.
+
+---
+
+## 3. Parameter Passing Conventions
+
+The choice of passing convention encodes intent and must be consistent.
+
+### 3.1 View and cheaply copyable types — pass by value
+
+Types that are designed to be non-owning views or are trivially copyable must be
+passed and returned **by value**. Passing them by `const &` is redundant and adds
+a pointer indirection with no benefit.
+
+This applies to:
+- `std::string_view`
+- `std::span<T>`
+- `kstd::observer_ptr<T>`
+- `kstd::bytes`, `kstd::pages` and similar unit wrappers
+- `kapi::capabilities::facet_id`
+- `kapi::memory::page`, `kapi::memory::frame`, `kapi::memory::physical_address`, `kapi::memory::linear_address`
+
+```cpp
+// Correct
+auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+auto has(std::span<std::byte const> data) -> bool;
+
+// Wrong
+auto resolve(kapi::capabilities::facet_id const & id, std::string_view const & name) -> void *;
+```
+
+### 3.2 Large or non-trivial types — pass by `const &`
+
+For types that own heap memory or are non-trivially copyable, use `const &` when the
+callee does not take ownership.
+
+```cpp
+auto do_publish(kstd::string const & name) -> kstd::result<void>;
+auto add_child(kstd::string const & child_name) -> void;
+```
+
+### 3.3 Sink parameters — pass by value and move
+
+When a function is designed to take **ownership** of an argument, accept it by value
+and move it into its destination. This makes the transfer explicit at the call site.
+
+```cpp
+// In the header
+auto add_child(kstd::shared_ptr<device> child) -> void;
+auto do_publish(kstd::shared_ptr<device> device, kstd::string name, ...) -> kstd::result<void>;
+
+// In the implementation
+auto bus::add_child(kstd::shared_ptr<device> child) -> void
+{
+ m_devices.push_back(std::move(child)); // ownership transferred here
+}
+```
+
+### 3.4 Mutable subsystem references — pass by non-const reference
+
+Services and subsystems that are mutated in-place (e.g., `page_mapper &`,
+`driver_state &`, `kapi::devices::bus &`) are passed by non-const reference. This
+expresses that the function operates on a shared, mutable context.
+
+```cpp
+auto remap_kernel(kapi::memory::page_mapper & mapper) -> void;
+auto add_directory_entry(inode & directory, inode & child, driver_state & state, write_batch & batch) -> kstd::result<void>;
+```
+
+---
+
+## 4. Error Handling
+
+### 4.1 Recoverable errors — `kstd::result<T>`
+
+Functions that can fail in an expected, recoverable way must return `kstd::result<T>`
+(an alias for `std::expected<T, kstd::error_code>`). Use the `kstd::success()` and
+`kstd::failure()` helpers consistently.
+
+```cpp
+auto mount(kstd::shared_ptr<inode> parent)
+ -> kstd::result<std::pair<kstd::shared_ptr<inode>, state *>>;
+
+// In the implementation
+if (!device)
+{
+ return kstd::failure(make_error_code(kstd::errc::invalid_argument));
+}
+return kstd::success(result_value);
+```
+
+Callers must check the result before using its value. The idiomatic check is:
+
+```cpp
+auto result = some_function();
+if (!result)
+{
+ return kstd::failure(result.error()); // propagate
+}
+// use *result
+```
+
+Monadic composition (`transform`, `and_then`, `or_else`) is preferred over
+manual if-check-and-return chains when it produces clearer code.
+
+### 4.2 Unrecoverable errors — `kapi::system::panic`
+
+Violations of kernel invariants (e.g., a subsystem used before being initialized,
+OOM during boot) call `kapi::system::panic(...)`. `panic` is `[[noreturn]]`. It must
+not be used for recoverable errors.
+
+Log prefix convention: `[SUBSYSTEM:TAG] message`. Examples: `[OS:DEV]`,
+`[OS:VFS]`, `[ARCH:DRV]`.
+
+```cpp
+if (!instance)
+{
+ system::panic("[OS:DEV] Device registry has not been initialized.");
+}
+```
+
+### 4.3 No exceptions
+
+The kernel does not use C++ exceptions. Do not write `throw` or `try`/`catch` in
+kernel code.
+
+---
+
+## 5. Ownership and Lifetime
+
+### 5.1 Shared ownership — `kstd::shared_ptr`
+
+Use `kstd::shared_ptr<T>` when a resource is co-owned by multiple subsystems and
+its lifetime must be extended by any of them (e.g., `device`, `inode`, `dentry`).
+Weak back-references that must not extend lifetime use `kstd::weak_ptr<T>`.
+
+### 5.2 Non-owning references — `kstd::observer_ptr` and raw references
+
+Use `kstd::observer_ptr<T>` to express a non-owning pointer where null is a valid
+state and the holder has no say in the lifetime of the target. Use a raw reference
+(`T &` or `T const &`) when null is not valid and the reference is short-lived (i.e.,
+a function parameter or a local alias).
+
+Never use raw `T *` to mean "sometimes I own this, sometimes I don't". Ownership must
+be expressed unambiguously through the pointer type.
+
+### 5.3 Driver data — `kstd::shared_ptr<void>`
+
+Drivers attach their state to a `device` using an untyped `kstd::shared_ptr<void>`
+via `device::set_driver_data`. A driver retrieves its state via `device::driver_data`.
+This allows the device tree to destroy driver data automatically when the device is
+released, without the device knowing the concrete driver type.
+
+---
+
+## 6. Algorithm and Range Usage
+
+### 6.1 Prefer `std::ranges` algorithms over manual loops
+
+When processing a range to search, filter, transform, or reduce, use the appropriate
+`std::ranges` algorithm or view pipeline instead of writing a raw `for` loop.
+
+```cpp
+// Correct
+auto already_published = std::ranges::any_of(
+ m_entries, [&](auto const & entry) {
+ return entry.id() == id && entry.device().get() == device.get();
+ });
+
+std::ranges::for_each(observers, [&](auto observer) { /* ... */ });
+
+// Wrong — manual linear scan for a boolean result
+for (auto const & entry : m_entries)
+{
+ if (entry.id() == id && entry.device().get() == device.get())
+ {
+ return true;
+ }
+}
+return false;
+```
+
+Acceptable uses of explicit loops include:
+- Accumulation or mutation that modifies state in-place and cannot be cleanly
+ expressed with a ranges algorithm.
+- Low-level routines dealing with raw memory arithmetic (allocators, page mappers).
+- Iterator-pair loops in library internals (`kstd::vector`, `kstd::basic_string`).
+
+### 6.2 Prefer view composition over intermediate containers
+
+Build processing pipelines using `std::views::filter`, `std::views::transform`,
+`std::views::reverse`, `std::views::split`, and `std::ranges::subrange` rather than
+materialising intermediate vectors.
+
+```cpp
+// Correct
+auto descriptors = std::span{&__start_platform_drivers, &__stop_platform_drivers}
+ | std::views::filter([](auto p) { return p != nullptr; });
+
+auto modules_view = std::ranges::subrange(begin(), end())
+ | std::views::filter(filter_modules)
+ | std::views::transform(transform_module);
+```
+
+### 6.3 Do not call the same function twice to avoid storing the result
+
+If an intermediate value is needed more than once, store it in a local variable. This
+applies especially to factory calls and heap allocations.
+
+```cpp
+// Wrong — double invocation, two allocations, different objects
+for (auto driver : descriptors)
+{
+ kstd::println("registering driver '{}'", driver->make_instance()->name());
+ registry.add(driver->make_instance());
+}
+
+// Correct
+for (auto driver : descriptors)
+{
+ auto instance = driver->make_instance();
+ kstd::println("registering driver '{}'", instance->name());
+ registry.add(std::move(instance));
+}
+```
+
+---
+
+## 7. Class and Struct Design
+
+### 7.1 Prefer `struct` over `class`
+
+The entire codebase uses `struct` for all type definitions with explicit `private:`
+sections where necessary. Do not introduce `class`.
+
+### 7.2 Member ordering within a type
+
+Follow this ordering within a `struct`:
+
+1. Nested types and type aliases.
+2. Static data members and static constexpr constants (e.g., `static constexpr auto id = ...`).
+3. Constructors and destructor.
+4. Public member functions.
+5. `protected:` section with virtual hooks.
+6. `private:` section with helper functions, then data members.
+
+Data members are always in the `private` section and always prefixed with `m_`.
+
+```cpp
+struct facet_registry
+{
+ struct entry { /* ... */ }; // 1. nested type
+
+ facet_registry() = default; // 3. constructor
+
+ auto static init() -> void; // 4. public interface
+ auto static get() -> facet_registry &;
+ auto publish(...) -> kstd::result<void>;
+
+private:
+ auto do_publish(...) -> kstd::result<void>; // 6a. private helpers
+
+ mutable tracked_mutex m_lock{}; // 6b. data members, m_ prefix
+ kstd::vector<entry> m_entries;
+};
+```
+
+### 7.3 `explicit` on single-argument constructors
+
+Mark every single-argument constructor `explicit` unless an implicit conversion is
+intentional and documented. A deliberate implicit constructor must be accompanied by
+a comment explaining the decision.
+
+```cpp
+// Correct
+explicit device(kstd::string const & name);
+constexpr explicit facet_id(std::string_view name);
+
+// Intentional implicit — documented at the declaration
+//! This constructor allows implicit conversion from chunk<...> to page for
+//! convenience. It is deliberately not explicit.
+constexpr page(chunk other) : chunk{other} {}
+```
+
+### 7.4 Declare deleted special members explicitly
+
+If a type is not copyable or not movable, declare the deleted special members
+explicitly rather than relying on implicit suppression.
+
+```cpp
+device(device const &) = delete;
+auto operator=(device const &) -> device & = delete;
+```
+
+### 7.5 Virtual destructors
+
+Every base class with virtual member functions must have a `virtual` destructor,
+defaulted if not otherwise needed.
+
+```cpp
+virtual ~driver_descriptor() = default;
+virtual ~facet_registry_observer() = default;
+```
+
+---
+
+## 8. Static Singletons
+
+Several subsystems expose a single global instance via an `init()`/`get()` pair.
+Follow this pattern:
+
+- Store the instance in an anonymous namespace as a `constinit std::optional<T>`.
+- `init()` asserts the instance is not yet constructed, then `emplace()`s it.
+- `get()` asserts the instance exists and returns a reference to it.
+- Both functions panic on violation rather than returning an error code, because
+ incorrect call order is a programming error, not a recoverable runtime condition.
+
+```cpp
+namespace
+{
+ auto constinit instance = std::optional<device_registry>{};
+}
+
+auto device_registry::init() -> void
+{
+ if (instance)
+ {
+ system::panic("[OS:DEV] Device registry has already been initialized.");
+ }
+ instance.emplace();
+}
+
+auto device_registry::get() -> device_registry &
+{
+ if (!instance)
+ {
+ system::panic("[OS:DEV] Device registry has not been initialized.");
+ }
+ return *instance;
+}
+```
+
+---
+
+## 9. Enumerations
+
+All enumerations use `enum struct` (scoped enums), never plain `enum`. Specify the
+underlying type explicitly when the representation matters (e.g., for hardware
+register fields).
+
+```cpp
+// Correct
+enum struct state
+{
+ uninitialized,
+ present,
+ bound,
+};
+
+// Wrong
+enum state { uninitialized, present, bound };
+```
+
+---
+
+## 10. Naming
+
+| Symbol | Convention | Example |
+|---|---|---|
+| Types (struct, enum) | `lower_case` | `device_registry`, `facet_id` |
+| Functions and methods | `lower_case` | `add_child`, `make_instance` |
+| Local variables | `lower_case` | `entry`, `block_index` |
+| Private data members | `m_` prefix, `lower_case` | `m_entries`, `m_driver_data` |
+| Template type parameters | `CamelCase` | `ValueType`, `FacetType` |
+| Constants and constexpr variables | `lower_case` | `page_size`, `direct_block_count` |
+| Type aliases | `lower_case` | `value_type`, `size_type` |
+| Namespaces | `lower_case` | `kapi::devices`, `kernel::vfs` |
+
+Namespaces reflect directory structure: `kernel::vfs`, `kernel::filesystems::ext2`,
+`arch::devices`, etc.
+
+---
+
+## 11. `[[nodiscard]]`
+
+Mark any function `[[nodiscard]]` whose return value the caller should not silently
+discard. This includes in particular:
+
+- All functions returning `kstd::result<T>`.
+- All query functions (getters, lookups) that return computed data.
+- Factory functions and builder utilities.
+
+```cpp
+[[nodiscard]] auto resolve(kapi::capabilities::facet_id id, std::string_view name) -> void *;
+[[nodiscard]] auto children() const -> kstd::vector<kstd::shared_ptr<device>>;
+[[nodiscard]] auto request_resource(resource_type type, std::size_t index = 0) const -> kstd::result<resource>;
+```
+
+---
+
+## 12. `constexpr` and `constinit`
+
+Mark functions `constexpr` whenever they can be evaluated at compile time or in
+constant expressions, even if they are also called at runtime. Mark module-scope
+variables `constinit` to guarantee zero-initialization before any dynamic
+initialization runs — important in a kernel with no well-defined global
+initialization order.
+
+---
+
+## 13. Documentation
+
+Every non-trivial public type, function, and data member must be documented with a
+Doxygen comment using the `//!` line style.
+
+```cpp
+//! A brief one-line description.
+//!
+//! Optional longer description providing context.
+//!
+//! @param name Description of the parameter.
+//! @return Description of the return value.
+//! @warning Any important warnings or preconditions.
+auto add_child(kstd::shared_ptr<device> child) -> void;
+```
+
+Doxygen grouping (`@addtogroup`, `@{`, `@}`) is used to organise the API surface into
+logical sections visible in generated documentation.
+
+---
+
+## 14. Header Guards
+
+All headers use traditional include guards, not `#pragma once`. The guard name follows
+the pattern `TEACHOS_<SUBPACKAGE>_<PATH>_HPP`, where each path component is
+uppercased and separators are replaced by `_`.
+
+```cpp
+#ifndef TEACHOS_KAPI_DEVICES_BUS_HPP
+#define TEACHOS_KAPI_DEVICES_BUS_HPP
+// ...
+#endif
+```
+
+The closing `#endif` carries no comment with the guard name.
diff --git a/kernel/kapi/cpu.cpp b/kernel/kapi/cpu.cpp
index 44331908..61f13edc 100644
--- a/kernel/kapi/cpu.cpp
+++ b/kernel/kapi/cpu.cpp
@@ -16,7 +16,7 @@ namespace kapi::cpu
kstd::println(kstd::print_sink::stderr, "\tWrite: {}", context.is_write_access);
kstd::println(kstd::print_sink::stderr, "\tUser: {}", context.is_user_mode);
- kapi::system::panic("Halting the system due to an unrecoverable page fault.");
+ kapi::system::panic("[OS:CPU] Halting the system due to an unrecoverable page fault.");
}
} // namespace
diff --git a/kernel/kapi/devices/driver_registry.cpp b/kernel/kapi/devices/driver_registry.cpp
index 7abb121f..405596cd 100644
--- a/kernel/kapi/devices/driver_registry.cpp
+++ b/kernel/kapi/devices/driver_registry.cpp
@@ -38,7 +38,7 @@ namespace kapi::devices
{
if (registry.has_value())
{
- system::panic("[kernel] Device driver registry has already been initialized.");
+ system::panic("[OS:DRV] Device driver registry has already been initialized.");
}
registry.emplace();
@@ -48,7 +48,7 @@ namespace kapi::devices
{
if (!registry)
{
- system::panic("[kernel] Device driver registry has not been initialized.");
+ system::panic("[OS:DRV] Device driver registry has not been initialized.");
}
return *registry;
diff --git a/kernel/kapi/devices/facet_registry.cpp b/kernel/kapi/devices/facet_registry.cpp
index b2d12c86..2974c71e 100644
--- a/kernel/kapi/devices/facet_registry.cpp
+++ b/kernel/kapi/devices/facet_registry.cpp
@@ -29,7 +29,7 @@ namespace kapi::devices
{
if (registry.has_value())
{
- system::panic("[kernel] Device facet registry has already been initialized.");
+ system::panic("[OS:DEV] Device facet registry has already been initialized.");
}
registry.emplace();
@@ -39,7 +39,7 @@ namespace kapi::devices
{
if (!registry)
{
- system::panic("[kernel] Device facet registry has not been initialized.");
+ system::panic("[OS:DEV] Device facet registry has not been initialized.");
}
return *registry;
diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp
index a0445645..1c6fa2c8 100644
--- a/kernel/kapi/memory.cpp
+++ b/kernel/kapi/memory.cpp
@@ -27,17 +27,17 @@ namespace kapi::memory
auto allocate_many(std::size_t) noexcept -> std::optional<std::pair<frame, std::size_t>> override
{
- system::panic("Tried to allocate frames without an active allocator.");
+ system::panic("[OS:MEM] Tried to allocate frames without an active allocator.");
}
auto mark_used(frame) -> void override
{
- system::panic("Tried to mark frame as used without an active allocator.");
+ system::panic("[OS:MEM] Tried to mark frame as used without an active allocator.");
}
auto release_many(std::pair<frame, std::size_t>) -> void override
{
- system::panic("Tried to release frames without an active allocator.");
+ system::panic("[OS:MEM] Tried to release frames without an active allocator.");
}
};
@@ -47,12 +47,12 @@ namespace kapi::memory
auto map(page, frame, flags) -> std::byte * override
{
- system::panic("Tried to map a page without an active mapper.");
+ system::panic("[OS:MEM] Tried to map a page without an active mapper.");
}
auto unmap(page) -> void override
{
- system::panic("Tried to unmap a page without an active mapper.");
+ system::panic("[OS:MEM] Tried to unmap a page without an active mapper.");
}
auto try_unmap(page) noexcept -> bool override
diff --git a/kernel/kernel/filesystems/ext2/directory_iterator.cpp b/kernel/kernel/filesystems/ext2/directory_iterator.cpp
index 2d5a2fe4..b1bb8b4f 100644
--- a/kernel/kernel/filesystems/ext2/directory_iterator.cpp
+++ b/kernel/kernel/filesystems/ext2/directory_iterator.cpp
@@ -26,7 +26,7 @@ namespace kernel::filesystems::ext2
{
if (!inode.is_directory())
{
- kapi::system::panic("[FS:ext2] Tried perform directory iteration on non-directory inode {}", inode.number());
+ kapi::system::panic("[FS:EXT2] Tried perform directory iteration on non-directory inode {}", inode.number());
}
if (m_file_offset >= data_size(*m_inode, *m_state))
@@ -84,7 +84,7 @@ namespace kernel::filesystems::ext2
{
if (auto result = do_read(*m_inode, m_buffer, m_file_offset, *m_state); !result)
{
- kapi::system::panic("[FS:ext2] failed to read directory entry", result.error());
+ kapi::system::panic("[FS:EXT2] failed to read directory entry", result.error());
}
auto entry = reinterpret_cast<pointer>(m_buffer.data());
@@ -97,7 +97,7 @@ namespace kernel::filesystems::ext2
if (auto result = do_read(*m_inode, m_buffer, m_file_offset, *m_state); !result)
{
- kapi::system::panic("[FS:ext2] failed to read directory entry", result.error());
+ kapi::system::panic("[FS:EXT2] failed to read directory entry", result.error());
}
entry = reinterpret_cast<pointer>(m_buffer.data());
diff --git a/kernel/kernel/filesystems/ext2/filesystem.cpp b/kernel/kernel/filesystems/ext2/filesystem.cpp
index 1785c0d7..eefd658c 100644
--- a/kernel/kernel/filesystems/ext2/filesystem.cpp
+++ b/kernel/kernel/filesystems/ext2/filesystem.cpp
@@ -166,7 +166,7 @@ namespace kernel::filesystems::ext2
case kapi::filesystem::file_type::socket:
return constants::mode_socket;
default:
- kapi::system::panic("[EXT2] Not implemented.");
+ kapi::system::panic("[FS:EXT2] Not implemented.");
}
}();
}
diff --git a/kernel/kernel/filesystems/ext2/inode.cpp b/kernel/kernel/filesystems/ext2/inode.cpp
index 4abf8599..5bdd7871 100644
--- a/kernel/kernel/filesystems/ext2/inode.cpp
+++ b/kernel/kernel/filesystems/ext2/inode.cpp
@@ -93,7 +93,7 @@ namespace kernel::filesystems::ext2
{
if (!is_regular())
{
- kapi::system::panic("[EXT2] ext2::inode write called on inode that is not of type regular");
+ kapi::system::panic("[FS:EXT2] ext2::inode write called on inode that is not of type regular");
}
// TODO check maximum file size of filesystem
diff --git a/kernel/kernel/filesystems/ext2/write_batch.cpp b/kernel/kernel/filesystems/ext2/write_batch.cpp
index 0bec30f4..76865a47 100644
--- a/kernel/kernel/filesystems/ext2/write_batch.cpp
+++ b/kernel/kernel/filesystems/ext2/write_batch.cpp
@@ -25,7 +25,7 @@ namespace kernel::filesystems::ext2
if (!result)
{
- kapi::system::panic("[FS:ext2] failed to write block groups descriptor", result.error());
+ kapi::system::panic("[FS:EXT2] failed to write block groups descriptor", result.error());
}
});
@@ -34,7 +34,7 @@ namespace kernel::filesystems::ext2
auto result = ext2::write_superblock(m_state);
if (!result)
{
- kapi::system::panic("[FS:ext2] failed to write superblock", result.error());
+ kapi::system::panic("[FS:EXT2] failed to write superblock", result.error());
}
}
@@ -42,7 +42,7 @@ namespace kernel::filesystems::ext2
auto result = ext2::write_inode(inode->number(), inode->data(), m_state);
if (!result)
{
- kapi::system::panic("[FS:ext2] failed to write inode", result.error());
+ kapi::system::panic("[FS:EXT2] failed to write inode", result.error());
}
});
}
diff --git a/kernel/kernel/main.cpp b/kernel/kernel/main.cpp
index f59b4ad7..ac2e18b8 100644
--- a/kernel/kernel/main.cpp
+++ b/kernel/kernel/main.cpp
@@ -32,7 +32,7 @@ auto run_demo() -> void
auto fd_1 = kapi::filesystem::open("/entrance/tickets.txt");
if (!fd_1)
{
- kapi::system::panic("demo failed");
+ kapi::system::panic("[demo failed]");
}
else
{
diff --git a/kernel/kernel/memory/block_list_allocator.cpp b/kernel/kernel/memory/block_list_allocator.cpp
index 993dd470..b5afd1d8 100644
--- a/kernel/kernel/memory/block_list_allocator.cpp
+++ b/kernel/kernel/memory/block_list_allocator.cpp
@@ -130,7 +130,7 @@ namespace kernel::memory
auto frame = kapi::memory::allocate_frame();
if (!frame)
{
- kapi::system::panic("[OS:Heap] OOM when expanding heap.");
+ kapi::system::panic("[OS:MEM] OOM when expanding heap.");
return false;
}
diff --git a/kernel/kernel/memory/operators.cpp b/kernel/kernel/memory/operators.cpp
index 45ba5152..8c60bb63 100644
--- a/kernel/kernel/memory/operators.cpp
+++ b/kernel/kernel/memory/operators.cpp
@@ -20,7 +20,7 @@
if (pointer == nullptr)
{
- kapi::system::panic("[OS:Heap] Out of memory!");
+ kapi::system::panic("[OS:MEM] Out of memory!");
}
return pointer;
diff --git a/kernel/kernel/vfs.cpp b/kernel/kernel/vfs.cpp
index 42e98219..cbabda82 100644
--- a/kernel/kernel/vfs.cpp
+++ b/kernel/kernel/vfs.cpp
@@ -44,7 +44,7 @@ namespace kernel::vfs
{
if (active_vfs)
{
- kapi::system::panic("[FILESYSTEM] vfs has already been initialized.");
+ kapi::system::panic("[OS:VFS] vfs has already been initialized.");
}
active_vfs.emplace();
@@ -56,13 +56,13 @@ namespace kernel::vfs
auto rootfs = driver_registry::get().find("rootfs");
if (!rootfs)
{
- kapi::system::panic("[OS:FS] rootfs driver is missing!");
+ kapi::system::panic("[OS:VFS] rootfs driver is missing!");
}
auto root_mount_result = (*rootfs)->mount(nullptr);
if (!root_mount_result)
{
- kapi::system::panic("[FILESYSTEM] failed to mount root FS", root_mount_result.error());
+ kapi::system::panic("[OS:VFS] failed to mount root FS", root_mount_result.error());
}
auto [root_inode, root_state] = *root_mount_result;
@@ -74,13 +74,13 @@ namespace kernel::vfs
auto devfs = driver_registry::get().find("devfs");
if (!devfs)
{
- kapi::system::panic("[OS:FS] devfs driver is missing!");
+ kapi::system::panic("[OS:VFS] devfs driver is missing!");
}
auto device_fs_mount_result = (*devfs)->mount(nullptr);
if (!device_fs_mount_result)
{
- kapi::system::panic("[FILESYSTEM] failed to mount device FS", device_fs_mount_result.error());
+ kapi::system::panic("[OS:VFS] failed to mount device FS", device_fs_mount_result.error());
}
auto [device_fs_root, device_fs_data] = *device_fs_mount_result;
@@ -95,13 +95,13 @@ namespace kernel::vfs
if (!root_devfs_mount)
{
- kapi::system::panic("[OS:FS] failed to mount initial devfs!", root_devfs_mount.error());
+ kapi::system::panic("[OS:VFS] failed to mount initial devfs!", root_devfs_mount.error());
}
auto resolved = resolve_path_internal("/dev/ram0");
if (!resolved)
{
- kapi::system::panic("[OS:FS] Failed to resolve boot disk!", resolved.error());
+ kapi::system::panic("[OS:VFS] Failed to resolve boot disk!", resolved.error());
}
auto [boot_device_dentry, boot_device_mount_context] = *resolved;
@@ -109,14 +109,14 @@ namespace kernel::vfs
auto driver = driver_registry::get().match(boot_device_dentry->inode());
if (!driver)
{
- kstd::println(kstd::print_sink::stderr, "[OS:FS] Missing driver for root disk!");
+ kstd::println(kstd::print_sink::stderr, "[OS:VFS] Missing driver for root disk!");
return;
}
auto mount = mount::create(nullptr, *driver, nullptr, boot_device_mount_context, boot_device_dentry->inode());
if (!mount)
{
- kapi::system::panic("[OS:FS] failed to mount boot FS", mount.error());
+ kapi::system::panic("[OS:VFS] failed to mount boot FS", mount.error());
}
m_mount_table.add_mount(*mount);
@@ -125,7 +125,7 @@ namespace kernel::vfs
{
if (auto result = mkdir("/dev"); !result)
{
- kapi::system::panic("[OS:FS] Failed to create devfs mount point!", result.error());
+ kapi::system::panic("[OS:VFS] Failed to create devfs mount point!", result.error());
}
real_dev_dentry = resolve_path("/dev");
}
@@ -133,7 +133,7 @@ namespace kernel::vfs
m_mount_table.move_mount(*root_devfs_mount, *real_dev_dentry, *mount);
if (auto result = m_mount_table.remove_mount(root_mount); !result)
{
- kapi::system::panic("[OS:FS] Failed to unmount early rootfs!", result.error());
+ kapi::system::panic("[OS:VFS] Failed to unmount early rootfs!", result.error());
}
}
@@ -141,7 +141,7 @@ namespace kernel::vfs
{
if (!active_vfs)
{
- kapi::system::panic("[FILESYSTEM] vfs has not been initialized.");
+ kapi::system::panic("[OS:VFS] vfs has not been initialized.");
}
return *active_vfs;
@@ -343,7 +343,7 @@ namespace kernel::vfs
auto current_mount = m_mount_table.find_mount("/");
if (!current_mount)
{
- kapi::system::panic("[FILESYSTEM] no root mount found.");
+ kapi::system::panic("[OS:VFS] no root mount found.");
}
auto current_dentry = current_mount->root_dentry();
@@ -410,7 +410,7 @@ namespace kernel::vfs
current_mount = m_mount_table.find_mount(next_dentry->absolute_path());
if (!current_mount)
{
- kapi::system::panic("[FILESYSTEM] mount for dentry with mounted flag not found.");
+ kapi::system::panic("[OS:VFS] mount for dentry with mounted flag not found.");
}
next_dentry = current_mount->root_dentry();
diff --git a/kernel/kernel/vfs/dentry.cpp b/kernel/kernel/vfs/dentry.cpp
index d9cb835a..092cab7c 100644
--- a/kernel/kernel/vfs/dentry.cpp
+++ b/kernel/kernel/vfs/dentry.cpp
@@ -22,11 +22,11 @@ namespace kernel::vfs
{
if (!m_inode)
{
- kapi::system::panic("[FILESYSTEM] dentry constructed with null inode.");
+ kapi::system::panic("[OS:VFS] dentry constructed with null inode.");
}
if (m_name.empty())
{
- kapi::system::panic("[FILESYSTEM] dentry constructed with empty name.");
+ kapi::system::panic("[OS:VFS] dentry constructed with empty name.");
}
}
diff --git a/kernel/kernel/vfs/device_inode.cpp b/kernel/kernel/vfs/device_inode.cpp
index ebb39541..e9c70f15 100644
--- a/kernel/kernel/vfs/device_inode.cpp
+++ b/kernel/kernel/vfs/device_inode.cpp
@@ -25,7 +25,7 @@ namespace kernel::vfs
{
if (!device)
{
- kapi::system::panic("[FILESYSTEM] device_inode constructed with null device.");
+ kapi::system::panic("[OS:VFS] device_inode constructed with null device.");
}
}
@@ -36,7 +36,7 @@ namespace kernel::vfs
{
if (!device)
{
- kapi::system::panic("[FILESYSTEM] device_inode constructed with null device.");
+ kapi::system::panic("[OS:VFS] device_inode constructed with null device.");
}
}
diff --git a/kernel/kernel/vfs/driver_registry.cpp b/kernel/kernel/vfs/driver_registry.cpp
index 16d048bf..736cfcbc 100644
--- a/kernel/kernel/vfs/driver_registry.cpp
+++ b/kernel/kernel/vfs/driver_registry.cpp
@@ -42,7 +42,7 @@ namespace kernel::vfs
{
if (instance)
{
- kapi::system::panic("[OS:FS] The filesystem driver registry was already initialized!");
+ kapi::system::panic("[OS:VFS] The filesystem driver registry was already initialized!");
}
instance.emplace();
@@ -55,7 +55,7 @@ namespace kernel::vfs
std::ranges::for_each(instances, [](auto entry) {
auto [descriptor, driver] = entry;
- kstd::println("[OS:FS] Registering filesystem driver '{}'", descriptor->name());
+ kstd::println("[OS:VFS] Registering filesystem driver '{}'", descriptor->name());
instance->add(descriptor->name(), driver);
});
}
@@ -64,7 +64,7 @@ namespace kernel::vfs
{
if (!instance)
{
- kapi::system::panic("[OS:FS] The filesystem driver registry has not been initialized!");
+ kapi::system::panic("[OS:VFS] The filesystem driver registry has not been initialized!");
}
return *instance;
@@ -84,7 +84,7 @@ namespace kernel::vfs
auto result = m_drivers.emplace(name, driver);
if (!result.second)
{
- kstd::println(kstd::print_sink::stderr, "[OS:FS] Tried to register duplicate filesystem driver '{}'!", name);
+ kstd::println(kstd::print_sink::stderr, "[OS:VFS] Tried to register duplicate filesystem driver '{}'!", name);
}
return result.second;
diff --git a/kernel/kernel/vfs/mount.cpp b/kernel/kernel/vfs/mount.cpp
index 3f99f733..a48558f1 100644
--- a/kernel/kernel/vfs/mount.cpp
+++ b/kernel/kernel/vfs/mount.cpp
@@ -28,7 +28,7 @@ namespace kernel::vfs
{
if (!m_filesystem)
{
- kapi::system::panic("[FILESYSTEM] mount initialized with null filesystem.");
+ kapi::system::panic("[OS:VFS] mount initialized with null filesystem.");
}
}
@@ -59,7 +59,7 @@ namespace kernel::vfs
{
if (!fs)
{
- kapi::system::panic("[OS:FS] Tried to mount a null filesystem!");
+ kapi::system::panic("[OS:VFS] Tried to mount a null filesystem!");
}
auto mount_result = fs->mount(backing_inode);
@@ -123,7 +123,7 @@ namespace kernel::vfs
{
if (m_ref_count == 0)
{
- kapi::system::panic("[FILESYSTEM] decrement_ref_count() was called but ref_count is 0");
+ kapi::system::panic("[OS:VFS] decrement_ref_count() was called but ref_count is 0");
}
m_ref_count -= 1;
diff --git a/kernel/kernel/vfs/open_file_descriptor.cpp b/kernel/kernel/vfs/open_file_descriptor.cpp
index 4f0581d2..985aab50 100644
--- a/kernel/kernel/vfs/open_file_descriptor.cpp
+++ b/kernel/kernel/vfs/open_file_descriptor.cpp
@@ -4,9 +4,9 @@
#include <kernel/vfs/error.hpp>
#include <kapi/filesystem.hpp>
+#include <kapi/system.hpp>
#include <kstd/memory.hpp>
-#include <kstd/os/error.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
@@ -20,7 +20,7 @@ namespace kernel::vfs
{
if (!dentry)
{
- kstd::os::panic("[FILESYSTEM] open_file_descriptor constructed with null dentry.");
+ kapi::system::panic("[OS:VFS] open_file_descriptor constructed with null dentry.");
}
}
diff --git a/kernel/kernel/vfs/open_file_table.cpp b/kernel/kernel/vfs/open_file_table.cpp
index 108f4e11..c2f0465a 100644
--- a/kernel/kernel/vfs/open_file_table.cpp
+++ b/kernel/kernel/vfs/open_file_table.cpp
@@ -24,7 +24,7 @@ namespace kernel::vfs
{
if (global_open_file_table)
{
- kapi::system::panic("[FILESYSTEM] Open file table has already been initialized.");
+ kapi::system::panic("[OS:VFS] Open file table has already been initialized.");
}
global_open_file_table.emplace(open_file_table{});
@@ -34,7 +34,7 @@ namespace kernel::vfs
{
if (!global_open_file_table)
{
- kapi::system::panic("[FILESYSTEM] Open file table has not been initialized.");
+ kapi::system::panic("[OS:VFS] Open file table has not been initialized.");
}
return *global_open_file_table;
diff --git a/libs/acpi/acpi/data/madt.hpp b/libs/acpi/acpi/data/madt.hpp
index 2bff7470..4a929a42 100644
--- a/libs/acpi/acpi/data/madt.hpp
+++ b/libs/acpi/acpi/data/madt.hpp
@@ -61,7 +61,7 @@ namespace acpi
{
if (type() != EntryType::this_type)
{
- kstd::os::panic("Invalid cast");
+ kstd::os::panic("[ACPI:DATA] Invalid cast");
}
return reinterpret_cast<EntryType const &>(*this);
}
diff --git a/libs/kstd/kstd/bits/basic_string.hpp b/libs/kstd/kstd/bits/basic_string.hpp
index a718bccc..1f8b60af 100644
--- a/libs/kstd/kstd/bits/basic_string.hpp
+++ b/libs/kstd/kstd/bits/basic_string.hpp
@@ -137,7 +137,7 @@ namespace kstd
{
if (!source && count)
{
- os::panic("Tried to construct string from null pointer!");
+ os::panic("[KSTD:STR] Tried to construct string from null pointer!");
}
if (count > capacity())
@@ -333,7 +333,7 @@ namespace kstd
{
if (string == nullptr)
{
- os::panic("Tried to construct string from null pointer!");
+ os::panic("[KSTD:STR] Tried to construct string from null pointer!");
}
auto incoming_length = traits_type::length(string);
@@ -454,7 +454,7 @@ namespace kstd
{
if (position >= size())
{
- os::panic("Invalid index in string element access");
+ os::panic("[KSTD:STR] Invalid index in string element access");
}
return m_data[position];
@@ -468,7 +468,7 @@ namespace kstd
{
if (position >= size())
{
- os::panic("Invalid index in string element access");
+ os::panic("[KSTD:STR] Invalid index in string element access");
}
return m_data[position];
@@ -673,7 +673,7 @@ namespace kstd
{
if (new_capacity > max_size())
{
- os::panic("Tried to allocate more memory than possible");
+ os::panic("[KSTD:STR] Tried to allocate more memory than possible");
}
if (new_capacity <= capacity())
@@ -733,7 +733,7 @@ namespace kstd
{
if (index > size())
{
- os::panic("Index out of bounds while inserting into string");
+ os::panic("[KSTD:STR] Index out of bounds while inserting into string");
}
if (count == 0uz)
@@ -770,7 +770,7 @@ namespace kstd
{
if (string == nullptr)
{
- os::panic("Tried to insert nullptr string");
+ os::panic("[KSTD:STR] Tried to insert nullptr string");
}
return do_insert(index, std::basic_string_view<value_type, traits_type>{string});
@@ -788,7 +788,7 @@ namespace kstd
{
if (range == nullptr)
{
- os::panic("Tried to insert nullptr range");
+ os::panic("[KSTD:STR] Tried to insert nullptr range");
}
return do_insert(index, std::basic_string_view<value_type, traits_type>{range, length});
@@ -880,7 +880,7 @@ namespace kstd
{
if (string == nullptr)
{
- os::panic("Attempted to append nullptr string");
+ os::panic("[KSTD:STR] Attempted to append nullptr string");
}
if (count == 0)
@@ -1312,7 +1312,7 @@ namespace kstd
{
if (rhs == nullptr)
{
- os::panic("Tried to compare a string with nullptr");
+ os::panic("[KSTD:STR] Tried to compare a string with nullptr");
}
return lhs == std::basic_string_view<value_type, traits_type>{rhs};
@@ -1322,7 +1322,7 @@ namespace kstd
{
if (rhs == nullptr)
{
- os::panic("Tried to compare a string with nullptr");
+ os::panic("[KSTD:STR] Tried to compare a string with nullptr");
}
return std::basic_string_view<value_type, traits_type>{lhs} == rhs;
@@ -1349,7 +1349,7 @@ namespace kstd
{
if (rhs == nullptr)
{
- os::panic("Tried to compare a string with nullptr");
+ os::panic("[KSTD:STR] Tried to compare a string with nullptr");
}
return lhs <=> std::basic_string_view<value_type, traits_type>{rhs};
@@ -1359,7 +1359,7 @@ namespace kstd
{
if (rhs == nullptr)
{
- os::panic("Tried to compare a string with nullptr");
+ os::panic("[KSTD:STR] Tried to compare a string with nullptr");
}
return std::basic_string_view<value_type, traits_type>{lhs} <=> rhs;
@@ -1381,7 +1381,7 @@ namespace kstd
{
if (count > max_size())
{
- os::panic("Tried to allocate more memory than possible");
+ os::panic("[KSTD:STR] Tried to allocate more memory than possible");
}
auto to_allocate = (exact ? count : std::min(std::max(count, 2 * capacity()), max_size())) + 1;
@@ -1397,7 +1397,7 @@ namespace kstd
{
if (index > size())
{
- os::panic("Index out of bounds while inserting into string");
+ os::panic("[KSTD:STR] Index out of bounds while inserting into string");
}
if (view.size() == 0uz)
diff --git a/libs/kstd/kstd/bits/format/context.hpp b/libs/kstd/kstd/bits/format/context.hpp
index d5f2f4d9..69766592 100644
--- a/libs/kstd/kstd/bits/format/context.hpp
+++ b/libs/kstd/kstd/bits/format/context.hpp
@@ -41,7 +41,7 @@ namespace kstd
{
if (id >= args.size())
{
- kstd::os::panic("[kstd:format] argument index out of range!");
+ kstd::os::panic("[KSTD:FMT] argument index out of range!");
}
return args[id];
}
diff --git a/libs/kstd/kstd/bits/format/error.hpp b/libs/kstd/kstd/bits/format/error.hpp
index c0cb53d7..30cb7523 100644
--- a/libs/kstd/kstd/bits/format/error.hpp
+++ b/libs/kstd/kstd/bits/format/error.hpp
@@ -15,7 +15,7 @@ namespace kstd::bits::format
}
else
{
- kstd::os::panic("Error while formatting a string.");
+ kstd::os::panic("[KSTD:FMT] Error while formatting a string.");
}
}
diff --git a/libs/kstd/kstd/bits/format/formatter/ordering.hpp b/libs/kstd/kstd/bits/format/formatter/ordering.hpp
index 78322262..73d2cac6 100644
--- a/libs/kstd/kstd/bits/format/formatter/ordering.hpp
+++ b/libs/kstd/kstd/bits/format/formatter/ordering.hpp
@@ -40,7 +40,7 @@ namespace kstd
{
return context.push(specifiers.alternative_form ? "<" : "less");
}
- kstd::os::panic("[kstd:format] Invalid strong ordering value!");
+ kstd::os::panic("[KSTD:FMT] Invalid strong ordering value!");
}
};
@@ -69,7 +69,7 @@ namespace kstd
{
return context.push(specifiers.alternative_form ? "<" : "less");
}
- kstd::os::panic("[kstd:format] Invalid weak ordering value!");
+ kstd::os::panic("[KSTD:FMT] Invalid weak ordering value!");
}
};
@@ -102,7 +102,7 @@ namespace kstd
{
return context.push(specifiers.alternative_form ? "<=>" : "unordered");
}
- kstd::os::panic("[kstd:format] Invalid partial ordering value!");
+ kstd::os::panic("[KSTD:FMT] Invalid partial ordering value!");
}
};
diff --git a/libs/kstd/kstd/bits/mutex/mutex.cpp b/libs/kstd/kstd/bits/mutex/mutex.cpp
index f1f43141..6dabb5dd 100644
--- a/libs/kstd/kstd/bits/mutex/mutex.cpp
+++ b/libs/kstd/kstd/bits/mutex/mutex.cpp
@@ -13,7 +13,7 @@ namespace kstd
{
if (m_locked.test(std::memory_order_relaxed))
{
- os::panic("[KSTD] Tried to destroy a locked mutex.");
+ os::panic("[KSTD:THR] Tried to destroy a locked mutex.");
}
}
diff --git a/libs/kstd/kstd/bits/observer_ptr.hpp b/libs/kstd/kstd/bits/observer_ptr.hpp
index e63e5d77..260d9d33 100644
--- a/libs/kstd/kstd/bits/observer_ptr.hpp
+++ b/libs/kstd/kstd/bits/observer_ptr.hpp
@@ -130,7 +130,7 @@ namespace kstd
{
if (m_ptr == nullptr)
{
- os::panic("[kstd:observer_ptr] Dereferencing a null observer pointer");
+ os::panic("[KSTD:MEM] Dereferencing a null observer pointer");
}
}
diff --git a/libs/kstd/kstd/flat_map.hpp b/libs/kstd/kstd/flat_map.hpp
index e140f7dd..c9a33b4a 100644
--- a/libs/kstd/kstd/flat_map.hpp
+++ b/libs/kstd/kstd/flat_map.hpp
@@ -112,7 +112,7 @@ namespace kstd
{
if (m_index >= m_containers->keys.size())
{
- os::panic("[kstd::flat_map] Iterator out of range");
+ os::panic("[KSTD:FLM] Iterator out of range");
}
return {m_containers->keys[m_index], m_containers->values[m_index]};
}
@@ -199,7 +199,7 @@ namespace kstd
{
if (it.m_index >= it.m_containers->keys.size())
{
- os::panic("[kstd::flat_map] Iterator out of range");
+ os::panic("[KSTD:FLM] Iterator out of range");
}
return rvalue_reference{static_cast<rvalue_reference::first_type>(it.m_containers->keys[it.m_index]),
@@ -470,7 +470,7 @@ namespace kstd
{
return found->second;
}
- os::panic("[kstd::flat_map] Key not found");
+ os::panic("[KSTD:FLM] Key not found");
}
//! Get a reference to the mapped value associated with the given key.
@@ -487,7 +487,7 @@ namespace kstd
{
return found->second;
}
- os::panic("[kstd::flat_map] Key not found");
+ os::panic("[KSTD:FLM] Key not found");
}
//! Get a reference to the mapped value associated with the given key, or insert a default one if none exists.
diff --git a/libs/kstd/kstd/libc/stdlib.cpp b/libs/kstd/kstd/libc/stdlib.cpp
index 7ed051fa..098bcd25 100644
--- a/libs/kstd/kstd/libc/stdlib.cpp
+++ b/libs/kstd/kstd/libc/stdlib.cpp
@@ -12,7 +12,7 @@ namespace kstd::libc
[[noreturn, gnu::weak]] auto free(void *) -> void
{
- kstd::os::panic("Tried to call free.");
+ kstd::os::panic("[KSTD:MEM] Tried to call free.");
}
}
diff --git a/libs/kstd/kstd/vector.hpp b/libs/kstd/kstd/vector.hpp
index 71c380fc..5a56381b 100644
--- a/libs/kstd/kstd/vector.hpp
+++ b/libs/kstd/kstd/vector.hpp
@@ -551,7 +551,7 @@ namespace kstd
if (new_capacity > max_size())
{
- kstd::os::panic("[kstd:vector] Tried to reserve more space than theoretically possible.");
+ kstd::os::panic("[KSTD:VEC] Tried to reserve more space than theoretically possible.");
}
reallocate_exactly(new_capacity);
@@ -580,7 +580,7 @@ namespace kstd
if (new_size > max_size())
{
- kstd::os::panic("[kstd:vector] Tried to resize more space than theoretically possible.");
+ kstd::os::panic("[KSTD:VEC] Tried to resize more space than theoretically possible.");
}
if (new_size > capacity())
@@ -744,7 +744,7 @@ namespace kstd
{
if (position == end())
{
- os::panic("[kstd:vector] Attempted to erase end()!");
+ os::panic("[KSTD:VEC] Attempted to erase end()!");
}
auto prefix_size = std::ranges::distance(cbegin(), position);
@@ -959,7 +959,7 @@ namespace kstd
{
if (index >= m_size)
{
- os::panic("[kstd:vector] Attempted to read element at invalid index");
+ os::panic("[KSTD:VEC] Attempted to read element at invalid index");
}
}