[kernel] Add a 'log available' signal to block on
There was previously no good way to block log-display tasks, either the fb driver or the kernel log task. Now the system object has a signal (j6_signal_system_has_log) that gets asserted when the log is written to.
This commit is contained in:
@@ -19,17 +19,20 @@ class logger
|
||||
{
|
||||
public:
|
||||
/// Callback type for immediate-mode logging
|
||||
typedef void (*immediate)(area_t, level, const char *);
|
||||
typedef void (*immediate_cb)(area_t, level, const char *);
|
||||
|
||||
/// Callback type for log flushing
|
||||
typedef void (*flush_cb)();
|
||||
|
||||
/// Default constructor. Creates a logger without a backing store.
|
||||
/// \arg output Immediate-mode logging output function
|
||||
logger(immediate output = nullptr);
|
||||
logger(immediate_cb output = nullptr);
|
||||
|
||||
/// Constructor. Logs are written to the given buffer.
|
||||
/// \arg buffer Buffer to which logs are written
|
||||
/// \arg size Size of `buffer`, in bytes
|
||||
/// \arg output Immediate-mode logging output function
|
||||
logger(uint8_t *buffer, size_t size, immediate output = nullptr);
|
||||
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
|
||||
@@ -38,7 +41,10 @@ public:
|
||||
void register_area(area_t area, const char *name, level verbosity);
|
||||
|
||||
/// Register an immediate-mode log callback
|
||||
inline void set_immediate(immediate cb) { m_immediate = cb; }
|
||||
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; }
|
||||
@@ -77,9 +83,13 @@ public:
|
||||
/// Get the next log entry from the buffer
|
||||
/// \arg buffer The buffer to copy the log message into
|
||||
/// \arg size Size of the passed-in buffer, in bytes
|
||||
/// \returns Number of bytes copied into the buffer
|
||||
/// \returns The size of the log entry (if larger than the
|
||||
/// buffer, then no data was copied)
|
||||
size_t get_entry(void *buffer, size_t size);
|
||||
|
||||
/// Get whether there is currently data in the log buffer
|
||||
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, ...);
|
||||
@@ -95,7 +105,8 @@ private:
|
||||
static const unsigned num_areas = 1 << (sizeof(area_t) * 8);
|
||||
uint8_t m_levels[num_areas / 2];
|
||||
const char *m_names[num_areas];
|
||||
immediate m_immediate;
|
||||
immediate_cb m_immediate;
|
||||
flush_cb m_flush;
|
||||
|
||||
uint8_t m_sequence;
|
||||
|
||||
|
||||
@@ -21,9 +21,10 @@ using kutil::memcpy;
|
||||
logger *logger::s_log = nullptr;
|
||||
const char *logger::s_level_names[] = {"", "debug", "info", "warn", "error", "fatal"};
|
||||
|
||||
logger::logger(logger::immediate output) :
|
||||
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));
|
||||
@@ -31,9 +32,10 @@ logger::logger(logger::immediate output) :
|
||||
s_log = this;
|
||||
}
|
||||
|
||||
logger::logger(uint8_t *buffer, size_t size, logger::immediate output) :
|
||||
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));
|
||||
@@ -107,6 +109,9 @@ logger::output(level severity, area_t area, const char *fmt, va_list args)
|
||||
|
||||
memcpy(out, buffer, n);
|
||||
m_buffer.commit(n);
|
||||
|
||||
if (m_flush)
|
||||
m_flush();
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -114,7 +119,6 @@ logger::get_entry(void *buffer, size_t size)
|
||||
{
|
||||
void *out;
|
||||
size_t out_size = m_buffer.get_block(&out);
|
||||
entry *ent = reinterpret_cast<entry *>(out);
|
||||
if (out_size == 0 || out == 0)
|
||||
return 0;
|
||||
|
||||
@@ -122,13 +126,13 @@ logger::get_entry(void *buffer, size_t size)
|
||||
if (out_size < sizeof(entry))
|
||||
return 0;
|
||||
|
||||
kassert(size >= ent->bytes, "Didn't pass a big enough buffer");
|
||||
if (size < ent->bytes)
|
||||
return 0;
|
||||
entry *ent = reinterpret_cast<entry *>(out);
|
||||
if (size >= out_size) {
|
||||
memcpy(buffer, out, ent->bytes);
|
||||
m_buffer.consume(ent->bytes);
|
||||
}
|
||||
|
||||
memcpy(buffer, out, ent->bytes);
|
||||
m_buffer.consume(ent->bytes);
|
||||
return ent->bytes;
|
||||
return out_size;
|
||||
}
|
||||
|
||||
#define LOG_LEVEL_FUNCTION(name) \
|
||||
|
||||
Reference in New Issue
Block a user