From 7bb6b21c65fc4b8b93810c41df9272d2a4bdff5c Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sat, 15 Jan 2022 09:57:08 -0800 Subject: [PATCH] [kernel] Simplify kernel logger The logger had a lot of code that was due to it being in kutil instead of the kernel. Simplifying it a bit here in order to make the uart logger easier and eventual paring down of the logger easier. - Log areas are no longer hashes of their names, just an enum - Log level settings are no longer saved in 4 bits, just a byte - System signal updating is done in the logger now --- src/kernel/log.cpp | 12 +-- src/kernel/logger.cpp | 73 +++++------------- src/kernel/logger.h | 75 +++++++++---------- .../j6/include/j6/tables/log_areas.inc | 32 ++++---- 4 files changed, 72 insertions(+), 120 deletions(-) diff --git a/src/kernel/log.cpp b/src/kernel/log.cpp index 3be1583..cbf7616 100644 --- a/src/kernel/log.cpp +++ b/src/kernel/log.cpp @@ -8,7 +8,7 @@ #include "objects/system.h" #include "objects/thread.h" -static uint8_t log_buffer[0x10000]; +static uint8_t log_buffer[128 * 1024]; // The logger is initialized _before_ global constructors are called, // so that we can start log output immediately. Keep its constructor @@ -19,7 +19,7 @@ log::logger &g_logger = __g_logger_storage.value; static const uint8_t level_colors[] = {0x07, 0x07, 0x0f, 0x0b, 0x09}; static void -output_log(log::area_t area, log::level severity, const char *message) +output_log(logs area, log::level severity, const char *message) { auto *cons = console::get(); cons->set_color(level_colors[static_cast(severity)]); @@ -33,13 +33,6 @@ output_log(log::area_t area, log::level severity, const char *message) // For printf.c extern "C" void putchar_(char c) {} -static void -log_flush() -{ - system &sys = system::get(); - sys.assert_signal(j6_signal_system_has_log); -} - void logger_task() { @@ -47,7 +40,6 @@ logger_task() log::info(logs::task, "Starting kernel logger task"); g_logger.set_immediate(nullptr); - g_logger.set_flush(log_flush); thread &self = thread::current(); system &sys = system::get(); diff --git a/src/kernel/logger.cpp b/src/kernel/logger.cpp index 83e4f04..1edcd37 100644 --- a/src/kernel/logger.cpp +++ b/src/kernel/logger.cpp @@ -4,80 +4,45 @@ #include "assert.h" #include "logger.h" +#include "objects/system.h" #include "printf/printf.h" -namespace logs { -#define LOG(name, lvl) \ - const log::area_t name = #name ## _h; \ - const char * name ## _name = #name; -#include -#undef LOG -} - namespace log { logger *logger::s_log = nullptr; const char *logger::s_level_names[] = {"", "debug", "info", "warn", "error", "fatal"}; +const char *logger::s_area_names[] = { +#define LOG(name, lvl) #name , +#include +#undef LOG + nullptr +}; logger::logger(logger::immediate_cb output) : m_buffer(nullptr, 0), m_immediate(output), - m_flush(nullptr), m_sequence(0) { memset(&m_levels, 0, sizeof(m_levels)); - memset(&m_names, 0, sizeof(m_names)); s_log = this; } logger::logger(uint8_t *buffer, size_t size, logger::immediate_cb output) : m_buffer(buffer, size), m_immediate(output), - m_flush(nullptr), m_sequence(0) { memset(&m_levels, 0, sizeof(m_levels)); - memset(&m_names, 0, sizeof(m_names)); s_log = this; #define LOG(name, lvl) \ - register_area(logs::name, logs::name ## _name, log::level::lvl); + set_level(logs::name, log::level::lvl); #include #undef LOG } void -logger::set_level(area_t area, level l) -{ - unsigned uarea = static_cast(area); - uint8_t ulevel = static_cast(l) & 0x0f; - uint8_t &flags = m_levels[uarea / 2]; - if (uarea & 1) - flags = (flags & 0x0f) | (ulevel << 4); - else - flags = (flags & 0xf0) | ulevel; -} - -level -logger::get_level(area_t area) -{ - unsigned uarea = static_cast(area); - uint8_t &flags = m_levels[uarea / 2]; - if (uarea & 1) - return static_cast((flags & 0xf0) >> 4); - else - return static_cast(flags & 0x0f); -} - -void -logger::register_area(area_t area, const char *name, level verbosity) -{ - m_names[area] = name; - set_level(area, verbosity); -} - -void -logger::output(level severity, area_t area, const char *fmt, va_list args) +logger::output(level severity, logs area, const char *fmt, va_list args) { uint8_t buffer[256]; entry *header = reinterpret_cast(buffer); @@ -86,8 +51,9 @@ logger::output(level severity, area_t area, const char *fmt, va_list args) header->severity = severity; header->sequence = m_sequence++; - header->bytes += - vsnprintf(header->message, sizeof(buffer) - sizeof(entry), fmt, args); + size_t mlen = vsnprintf(header->message, sizeof(buffer) - sizeof(entry) - 1, fmt, args); + header->message[mlen] = 0; + header->bytes += mlen + 1; util::scoped_lock lock {m_lock}; @@ -99,19 +65,16 @@ logger::output(level severity, area_t area, const char *fmt, va_list args) uint8_t *out; size_t n = m_buffer.reserve(header->bytes, reinterpret_cast(&out)); - if (n < sizeof(entry)) { - m_buffer.commit(0); // Cannot even write the header, abort + if (n < header->bytes) { + m_buffer.commit(0); // Cannot write the message, give up return; } - if (n < header->bytes) - header->bytes = n; - memcpy(out, buffer, n); m_buffer.commit(n); - if (m_flush) - m_flush(); + system &sys = system::get(); + sys.assert_signal(j6_signal_system_has_log); } size_t @@ -138,7 +101,7 @@ logger::get_entry(void *buffer, size_t size) } #define LOG_LEVEL_FUNCTION(name) \ - void name (area_t area, const char *fmt, ...) { \ + void name (logs area, const char *fmt, ...) { \ logger *l = logger::s_log; \ if (!l) return; \ level limit = l->get_level(area); \ @@ -154,7 +117,7 @@ LOG_LEVEL_FUNCTION(info); LOG_LEVEL_FUNCTION(warn); LOG_LEVEL_FUNCTION(error); -void fatal(area_t area, const char *fmt, ...) +void fatal(logs area, const char *fmt, ...) { logger *l = logger::s_log; if (!l) return; diff --git a/src/kernel/logger.h b/src/kernel/logger.h index 9123f71..7c92411 100644 --- a/src/kernel/logger.h +++ b/src/kernel/logger.h @@ -8,21 +8,27 @@ #include #include +enum class logs : uint8_t { +#define LOG(name, lvl) name, +#include +#undef LOG + COUNT +}; + namespace log { -using area_t = uint8_t; enum class level : uint8_t { none, debug, info, warn, error, fatal, max }; +constexpr unsigned areas_count = + static_cast(logs::COUNT); + class logger { public: /// Callback type for immediate-mode logging - typedef void (*immediate_cb)(area_t, level, const char *); - - /// Callback type for log flushing - typedef void (*flush_cb)(); + typedef void (*immediate_cb)(logs, level, const char *); /// Default constructor. Creates a logger without a backing store. /// \arg output Immediate-mode logging output function @@ -34,23 +40,17 @@ public: /// \arg output Immediate-mode logging output function logger(uint8_t *buffer, size_t size, immediate_cb output = nullptr); - /// Register a log area for future use. - /// \arg area The key for the new area - /// \arg name The area name - /// \arg verbosity What level of logs to print for this area - void register_area(area_t area, const char *name, level verbosity); + /// Get the current immediate-mode callback + inline immediate_cb get_immediate() const { return m_immediate; } /// Register an immediate-mode log callback inline void set_immediate(immediate_cb cb) { m_immediate = cb; } - /// Register a flush callback - inline void set_flush(flush_cb cb) { m_flush = cb; } - /// Get the default logger. inline logger & get() { return *s_log; } /// Get the registered name for a given area - inline const char * area_name(area_t area) const { return m_names[area]; } + inline const char * area_name(logs area) const { return s_area_names[static_cast(area)]; } /// Get the name of a level inline const char * level_name(level l) const { return s_level_names[static_cast(l)]; } @@ -59,7 +59,7 @@ public: /// \arg severity The severity of the message /// \arg area The log area to write to /// \arg fmt A printf-like format string - inline void log(level severity, area_t area, const char *fmt, ...) + inline void log(level severity, logs area, const char *fmt, ...) { level limit = get_level(area); if (limit == level::none || severity < limit) @@ -74,7 +74,7 @@ public: struct entry { uint8_t bytes; - area_t area; + logs area; level severity; uint8_t sequence; char message[0]; @@ -91,22 +91,24 @@ public: inline bool has_log() const { return m_buffer.size(); } private: - friend void debug(area_t area, const char *fmt, ...); - friend void info (area_t area, const char *fmt, ...); - friend void warn (area_t area, const char *fmt, ...); - friend void error(area_t area, const char *fmt, ...); - friend void fatal(area_t area, const char *fmt, ...); + friend void debug(logs area, const char *fmt, ...); + friend void info (logs area, const char *fmt, ...); + friend void warn (logs area, const char *fmt, ...); + friend void error(logs area, const char *fmt, ...); + friend void fatal(logs area, const char *fmt, ...); - void output(level severity, area_t area, const char *fmt, va_list args); + void output(level severity, logs area, const char *fmt, va_list args); - void set_level(area_t area, level l); - level get_level(area_t area); + inline void set_level(logs area, level l) { + m_levels[static_cast(area)] = l; + } - static const unsigned num_areas = 1 << (sizeof(area_t) * 8); - uint8_t m_levels[num_areas / 2]; - const char *m_names[num_areas]; + inline level get_level(logs area) { + return m_levels[static_cast(area)]; + } + + level m_levels[areas_count]; immediate_cb m_immediate; - flush_cb m_flush; uint8_t m_sequence; @@ -114,21 +116,16 @@ private: util::spinlock m_lock; static logger *s_log; + static const char *s_area_names[areas_count+1]; static const char *s_level_names[static_cast(level::max)]; }; -void debug(area_t area, const char *fmt, ...); -void info (area_t area, const char *fmt, ...); -void warn (area_t area, const char *fmt, ...); -void error(area_t area, const char *fmt, ...); -void fatal(area_t area, const char *fmt, ...); +void debug(logs area, const char *fmt, ...); +void info (logs area, const char *fmt, ...); +void warn (logs area, const char *fmt, ...); +void error(logs area, const char *fmt, ...); +void fatal(logs area, const char *fmt, ...); extern log::logger &g_logger; } // namespace log - -namespace logs { -#define LOG(name, lvl) extern const log::area_t name; -#include -#undef LOG -} // namespace logs diff --git a/src/libraries/j6/include/j6/tables/log_areas.inc b/src/libraries/j6/include/j6/tables/log_areas.inc index 7be21fe..a85c5b6 100644 --- a/src/libraries/j6/include/j6/tables/log_areas.inc +++ b/src/libraries/j6/include/j6/tables/log_areas.inc @@ -1,16 +1,16 @@ -LOG(apic, info); -LOG(boot, debug); -LOG(clock, debug); -LOG(device, debug); -LOG(driver, info); -LOG(fs, info); -LOG(irq, info); -LOG(loader, debug); -LOG(memory, debug); -LOG(objs, debug); -LOG(paging, info); -LOG(sched, info); -LOG(syscall,info); -LOG(task, debug); -LOG(timer, debug); -LOG(vmem, debug); +LOG(apic, info) +LOG(boot, debug) +LOG(clock, debug) +LOG(device, debug) +LOG(driver, info) +LOG(fs, info) +LOG(irq, info) +LOG(loader, debug) +LOG(memory, debug) +LOG(objs, debug) +LOG(paging, info) +LOG(sched, info) +LOG(syscall,debug) +LOG(task, debug) +LOG(timer, debug) +LOG(vmem, debug)