1
0
Fork 0
forked from nuttx/nuttx-update

syslog/ramlog: improve ramlog performance

replace char copy to memcpy to improve the performance

Signed-off-by: chao an <anchao@lixiang.com>
This commit is contained in:
chao an 2023-12-14 21:39:37 +08:00 committed by Xiang Xiao
parent 31a6ffa15c
commit b67c9e6ca7

View file

@ -110,7 +110,6 @@ struct ramlog_dev_s
static void ramlog_readnotify(FAR struct ramlog_dev_s *priv); static void ramlog_readnotify(FAR struct ramlog_dev_s *priv);
#endif #endif
static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv); static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv);
static void ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch);
/* Character driver methods */ /* Character driver methods */
@ -236,48 +235,36 @@ static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv)
} }
/**************************************************************************** /****************************************************************************
* Name: ramlog_addchar * Name: ramlog_copybuf
****************************************************************************/ ****************************************************************************/
static void ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch) static void ramlog_copybuf(FAR struct ramlog_dev_s *priv,
FAR const char *buffer, size_t len)
{ {
FAR struct ramlog_header_s *header = priv->rl_header; FAR struct ramlog_header_s *header = priv->rl_header;
FAR char *buf = header->rl_buffer;
uint32_t offset;
uint32_t tail;
#ifdef CONFIG_RAMLOG_SYSLOG if (len <= 0)
if (priv == &g_sysdev && header->rl_magic != RAMLOG_MAGIC_NUMBER)
{
memset(header, 0, sizeof(g_sysbuffer));
header->rl_magic = RAMLOG_MAGIC_NUMBER;
}
#endif
#ifdef CONFIG_RAMLOG_CRLF
/* Ignore carriage returns */
if (ch == '\r')
{ {
return; return;
} }
/* Pre-pend a carriage before a linefeed */ offset = header->rl_head % priv->rl_bufsize;
tail = priv->rl_bufsize - offset;
if (ch == '\n') if (len > tail)
{ {
ch = '\r'; memcpy(&buf[offset], buffer, tail);
memcpy(buf, buffer + tail, len - tail);
}
else
{
memcpy(&buf[offset], buffer, len);
} }
again: header->rl_head += len;
#endif
header->rl_buffer[header->rl_head++ % priv->rl_bufsize] = ch;
#ifdef CONFIG_RAMLOG_CRLF
if (ch == '\r')
{
ch = '\n';
goto again;
}
#endif
} }
/**************************************************************************** /****************************************************************************
@ -287,28 +274,68 @@ again:
static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv, static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv,
FAR const char *buffer, size_t len) FAR const char *buffer, size_t len)
{ {
#if defined(CONFIG_RAMLOG_SYSLOG) || defined(CONFIG_RAMLOG_CRLF)
FAR struct ramlog_header_s *header = priv->rl_header;
#endif
size_t buflen = len;
irqstate_t flags; irqstate_t flags;
size_t nwritten; #ifdef CONFIG_RAMLOG_CRLF
char ch; FAR const char *end;
FAR const char *pos;
FAR char *buf;
#endif
/* Disable interrupts (in case we are NOT called from interrupt handler) */ /* Disable interrupts (in case we are NOT called from interrupt handler) */
flags = enter_critical_section(); flags = enter_critical_section();
for (nwritten = 0; nwritten < len; nwritten++) #ifdef CONFIG_RAMLOG_SYSLOG
if (header->rl_magic != RAMLOG_MAGIC_NUMBER && priv == &g_sysdev)
{ {
/* Get the next character to output */ memset(header, 0, sizeof(g_sysbuffer));
header->rl_magic = RAMLOG_MAGIC_NUMBER;
ch = buffer[nwritten];
/* Then output the character */
ramlog_addchar(priv, ch);
} }
#endif
if (buflen > priv->rl_bufsize)
{
buffer += buflen - priv->rl_bufsize;
buflen = priv->rl_bufsize;
}
#ifdef CONFIG_RAMLOG_CRLF
buf = header->rl_buffer;
end = buffer + buflen;
pos = buffer;
do
{
/* Ignore carriage returns */
if (*pos == '\r' || *pos == '\n')
{
ramlog_copybuf(priv, buffer, pos - buffer);
buffer = pos + 1;
}
/* Pre-pend a carriage before a linefeed */
if (*pos == '\n')
{
buf[header->rl_head++ % priv->rl_bufsize] = '\r';
buf[header->rl_head++ % priv->rl_bufsize] = '\n';
}
}
while (++pos != end);
ramlog_copybuf(priv, buffer, pos - buffer);
#else
ramlog_copybuf(priv, buffer, buflen);
#endif
/* Was anything written? */ /* Was anything written? */
if (nwritten > 0) if (len > 0)
{ {
#ifndef CONFIG_RAMLOG_NONBLOCKING #ifndef CONFIG_RAMLOG_NONBLOCKING
/* Are there threads waiting for read data? */ /* Are there threads waiting for read data? */
@ -341,9 +368,10 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
FAR struct ramlog_header_s *header = priv->rl_header; FAR struct ramlog_header_s *header = priv->rl_header;
FAR struct ramlog_user_s *upriv = filep->f_priv; FAR struct ramlog_user_s *upriv = filep->f_priv;
irqstate_t flags; irqstate_t flags;
uint32_t tail; uint32_t ncopy;
ssize_t nread; ssize_t nread;
char ch; uint32_t tail;
uint32_t pos;
/* If the circular buffer is empty, then wait for something to be written /* If the circular buffer is empty, then wait for something to be written
* to it. This function may NOT be called from an interrupt handler. * to it. This function may NOT be called from an interrupt handler.
@ -355,15 +383,6 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
flags = enter_critical_section(); flags = enter_critical_section();
/* Determine whether the read pointer is overwritten */
if (header->rl_head - upriv->rl_tail > priv->rl_bufsize)
{
upriv->rl_tail = header->rl_head - priv->rl_bufsize;
}
tail = upriv->rl_tail % priv->rl_bufsize;
/* Loop until something is read */ /* Loop until something is read */
for (nread = 0; (size_t)nread < len; ) for (nread = 0; (size_t)nread < len; )
@ -423,24 +442,38 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
} }
else else
{ {
/* Determine whether the read pointer is overwritten */
if (header->rl_head - upriv->rl_tail > priv->rl_bufsize)
{
upriv->rl_tail = header->rl_head - priv->rl_bufsize;
}
/* The circular buffer is not empty, get the next byte from the /* The circular buffer is not empty, get the next byte from the
* tail index. * tail index.
*/ */
ch = header->rl_buffer[tail]; pos = upriv->rl_tail % priv->rl_bufsize;
ncopy = header->rl_head - upriv->rl_tail;
tail = priv->rl_bufsize - pos;
/* Increment the tail index. */ if (ncopy > len - nread)
upriv->rl_tail++;
if (++tail >= priv->rl_bufsize)
{ {
tail = 0; ncopy = len - nread;
} }
/* Add the character to the user buffer. */ if (ncopy > tail)
{
memcpy(&buffer[nread], &header->rl_buffer[pos], tail);
memcpy(&buffer[nread + tail], header->rl_buffer, ncopy - tail);
}
else
{
memcpy(&buffer[nread], &header->rl_buffer[pos], ncopy);
}
buffer[nread] = ch; upriv->rl_tail += ncopy;
nread++; nread += ncopy;
} }
} }
@ -687,26 +720,13 @@ void ramlog_syslog_register(void)
#ifdef CONFIG_RAMLOG_SYSLOG #ifdef CONFIG_RAMLOG_SYSLOG
int ramlog_putc(FAR struct syslog_channel_s *channel, int ch) int ramlog_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
FAR struct ramlog_dev_s *priv = &g_sysdev; char cch = ch;
irqstate_t flags;
UNUSED(channel); UNUSED(channel);
/* Add the character to the RAMLOG */ /* Add the character to the RAMLOG */
flags = enter_critical_section(); ramlog_addbuf(&g_sysdev, &cch, 1);
ramlog_addchar(priv, ch);
#ifndef CONFIG_RAMLOG_NONBLOCKING
/* Are there threads waiting for read data? */
ramlog_readnotify(priv);
#endif
/* Notify all poll/select waiters that they can read from the FIFO */
ramlog_pollnotify(priv);
leave_critical_section(flags);
/* Return the character added on success */ /* Return the character added on success */
@ -716,9 +736,7 @@ int ramlog_putc(FAR struct syslog_channel_s *channel, int ch)
ssize_t ramlog_write(FAR struct syslog_channel_s *channel, ssize_t ramlog_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen) FAR const char *buffer, size_t buflen)
{ {
FAR struct ramlog_dev_s *priv = &g_sysdev; return ramlog_addbuf(&g_sysdev, buffer, buflen);
return ramlog_addbuf(priv, buffer, buflen);
} }
#endif #endif