lib: sbi: Speed-up sbi_printf() and friends using nputs()

The sbi_printf() is slow for semihosting because it prints one
character at a time. To speed-up sbi_printf() for semihosting,
we use a temporary buffer and nputs().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
This commit is contained in:
Anup Patel 2023-01-13 14:53:53 +05:30 committed by Anup Patel
parent 29285aead0
commit 65c2190b47

View file

@ -14,7 +14,11 @@
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_string.h>
#define CONSOLE_TBUF_MAX 256
static const struct sbi_console_device *console_dev = NULL;
static char console_tbuf[CONSOLE_TBUF_MAX];
static u32 console_tbuf_len;
static spinlock_t console_out_lock = SPIN_LOCK_INITIALIZER;
bool sbi_isprintable(char c)
@ -42,30 +46,10 @@ void sbi_putc(char ch)
}
}
void sbi_puts(const char *str)
{
unsigned long p, len;
spin_lock(&console_out_lock);
if (console_dev && console_dev->console_puts) {
p = 0;
len = sbi_strlen(str);
while (p < len)
p += console_dev->console_puts(&str[p], len - p);
} else {
while (*str) {
sbi_putc(*str);
str++;
}
}
spin_unlock(&console_out_lock);
}
unsigned long sbi_nputs(const char *str, unsigned long len)
static unsigned long nputs(const char *str, unsigned long len)
{
unsigned long i, ret;
spin_lock(&console_out_lock);
if (console_dev && console_dev->console_puts) {
ret = console_dev->console_puts(str, len);
} else {
@ -73,6 +57,33 @@ unsigned long sbi_nputs(const char *str, unsigned long len)
sbi_putc(str[i]);
ret = len;
}
return ret;
}
static void nputs_all(const char *str, unsigned long len)
{
unsigned long p = 0;
while (p < len)
p += nputs(&str[p], len - p);
}
void sbi_puts(const char *str)
{
unsigned long len = sbi_strlen(str);
spin_lock(&console_out_lock);
nputs_all(str, len);
spin_unlock(&console_out_lock);
}
unsigned long sbi_nputs(const char *str, unsigned long len)
{
unsigned long ret;
spin_lock(&console_out_lock);
ret = nputs(str, len);
spin_unlock(&console_out_lock);
return ret;
@ -225,12 +236,30 @@ static int printi(char **out, u32 *out_len, long long i, int b, int sg,
static int print(char **out, u32 *out_len, const char *format, va_list args)
{
int width, flags;
int pc = 0;
char scr[2];
int width, flags, pc = 0;
char scr[2], *tout;
bool use_tbuf = (!out) ? true : false;
unsigned long long tmp;
/*
* The console_tbuf is protected by console_out_lock and
* print() is always called with console_out_lock held
* when out == NULL.
*/
if (use_tbuf) {
console_tbuf_len = CONSOLE_TBUF_MAX;
tout = console_tbuf;
out = &tout;
out_len = &console_tbuf_len;
}
for (; *format != 0; ++format) {
if (use_tbuf && !console_tbuf_len) {
nputs_all(console_tbuf, CONSOLE_TBUF_MAX);
console_tbuf_len = CONSOLE_TBUF_MAX;
tout = console_tbuf;
}
if (*format == '%') {
++format;
width = flags = 0;
@ -356,6 +385,9 @@ literal:
}
}
if (use_tbuf && console_tbuf_len < CONSOLE_TBUF_MAX)
nputs_all(console_tbuf, CONSOLE_TBUF_MAX - console_tbuf_len);
return pc;
}