From 56577b55b710dfbc6b869496a14704918c6a9239 Mon Sep 17 00:00:00 2001 From: Balazs Gerofi Date: Thu, 10 May 2012 14:15:14 +0900 Subject: [PATCH] separate kmsg lock and print functions for multi-line atomic messages --- kernel/debug.c | 60 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/kernel/debug.c b/kernel/debug.c index ae8897e5..8ed287d5 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -7,6 +7,7 @@ struct aal_kmsg_buf kmsg_buf AAL_KMSG_ALIGN; extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); +extern int sprintf(char * buf, const char *fmt, ...); static aal_spinlock_t kmsg_lock; /* TODO: lock */ @@ -18,7 +19,7 @@ void kputs(char *buf) flags = aal_mc_spinlock_lock(&kmsg_lock); if (len + kmsg_buf.tail > kmsg_buf.len) { - len = kmsg_buf.len - kmsg_buf.tail; + kmsg_buf.tail = 0; } strncpy(kmsg_buf.str + kmsg_buf.tail, buf, len); @@ -27,27 +28,65 @@ void kputs(char *buf) aal_mc_spinlock_unlock(&kmsg_lock, flags); } -int kprintf(const char *format, ...) +#define KPRINTF_LOCAL_BUF_LEN 1024 + +int kprintf_lock() { - int len; + return aal_mc_spinlock_lock(&kmsg_lock); +} + +void kprintf_unlock(int irqflags) +{ + aal_mc_spinlock_unlock(&kmsg_lock, irqflags); +} + +/* Caller must hold kmsg_lock! */ +int __kprintf(const char *format, ...) +{ + int len = 0; va_list va; - unsigned long flags; + char buf[KPRINTF_LOCAL_BUF_LEN]; + /* Copy into the local buf */ va_start(va, format); + len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len, format, va); + va_end(va); - flags = aal_mc_spinlock_lock(&kmsg_lock); - if (kmsg_buf.tail >= kmsg_buf.len - 1) { + /* Append to kmsg buffer */ + if (kmsg_buf.tail + len > kmsg_buf.len) { kmsg_buf.tail = 0; } - len = vsnprintf(kmsg_buf.str + kmsg_buf.tail, - kmsg_buf.len - kmsg_buf.tail, format, va); + memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); + kmsg_buf.tail += len; + + return len; +} + +int kprintf(const char *format, ...) +{ + int len = 0; + va_list va; + unsigned long flags; + char buf[KPRINTF_LOCAL_BUF_LEN]; + + flags = aal_mc_spinlock_lock(&kmsg_lock); + + /* Copy into the local buf */ + va_start(va, format); + len += vsnprintf(buf + len, KPRINTF_LOCAL_BUF_LEN - len, format, va); + va_end(va); + + /* Append to kmsg buffer */ + if (kmsg_buf.tail + len > kmsg_buf.len) { + kmsg_buf.tail = 0; + } + + memcpy(kmsg_buf.str + kmsg_buf.tail, buf, len); kmsg_buf.tail += len; aal_mc_spinlock_unlock(&kmsg_lock, flags); - va_end(va); - return len; } @@ -56,4 +95,5 @@ void kmsg_init(void) aal_mc_spinlock_init(&kmsg_lock); kmsg_buf.tail = 0; kmsg_buf.len = sizeof(kmsg_buf.str); + memset(kmsg_buf.str, 0, kmsg_buf.len); }