syslog/syslog_rpmsg.c: improve syslog_rpmsg performance

use copy buffer instead of single assignment

Signed-off-by: yuanyongjian <yuanyongjian@xiaomi.com>
This commit is contained in:
yuanyongjian 2024-02-04 21:59:20 +08:00 committed by Xiang Xiao
parent 6e5c81e061
commit 8713638687
1 changed files with 48 additions and 28 deletions

View File

@ -80,8 +80,8 @@ struct syslog_rpmsg_s
****************************************************************************/ ****************************************************************************/
static void syslog_rpmsg_work(FAR void *priv_); static void syslog_rpmsg_work(FAR void *priv_);
static void syslog_rpmsg_putchar(FAR struct syslog_rpmsg_s *priv, int ch, static void syslog_rpmsg_addbuf(FAR struct syslog_rpmsg_s *priv,
bool last); FAR const char *buffer, size_t len);
static void syslog_rpmsg_device_created(FAR struct rpmsg_device *rdev, static void syslog_rpmsg_device_created(FAR struct rpmsg_device *rdev,
FAR void *priv_); FAR void *priv_);
static void syslog_rpmsg_device_destroy(FAR struct rpmsg_device *rdev, static void syslog_rpmsg_device_destroy(FAR struct rpmsg_device *rdev,
@ -189,10 +189,19 @@ static void syslog_rpmsg_work(FAR void *priv_)
} }
} }
static void syslog_rpmsg_putchar(FAR struct syslog_rpmsg_s *priv, int ch, static void syslog_rpmsg_addbuf(FAR struct syslog_rpmsg_s *priv,
bool last) FAR const char *buffer, size_t len)
{ {
if (priv->head + 1 - priv->tail >= priv->size) bool overwritten = false;
size_t offset;
size_t tail;
if (len <= 0)
{
return;
}
if (priv->head + len - priv->tail >= priv->size)
{ {
bool ret = false; bool ret = false;
@ -203,26 +212,42 @@ static void syslog_rpmsg_putchar(FAR struct syslog_rpmsg_s *priv, int ch,
if (!ret) if (!ret)
{ {
/* Overwrite */ overwritten = true;
priv->buffer[SYSLOG_RPMSG_TAILOFF(priv)] = 0;
priv->tail++;
} }
} }
priv->buffer[SYSLOG_RPMSG_HEADOFF(priv)] = ch & 0xff; offset = SYSLOG_RPMSG_HEADOFF(priv);
priv->head++; tail = priv->size - offset;
if (len > tail)
{
memcpy(&priv->buffer[offset], buffer, tail);
memcpy(priv->buffer, buffer + tail, len - tail);
}
else
{
memcpy(&priv->buffer[offset], buffer, len);
}
priv->head += len;
if (overwritten)
{
priv->tail = priv->head - priv->size;
priv->buffer[priv->tail] = 0;
priv->tail++;
}
if (priv->flush) if (priv->flush)
{ {
#if defined(CONFIG_ARCH_LOWPUTC) #if defined(CONFIG_ARCH_LOWPUTC)
up_putc(ch); up_nputs(buffer, len);
#endif #endif
priv->flush++;
priv->flush += len;
return; return;
} }
if (last && !priv->suspend && is_rpmsg_ept_ready(&priv->ept)) if (!priv->suspend && is_rpmsg_ept_ready(&priv->ept))
{ {
clock_t delay = SYSLOG_RPMSG_WORK_DELAY; clock_t delay = SYSLOG_RPMSG_WORK_DELAY;
size_t space = SYSLOG_RPMSG_SPACE(priv); size_t space = SYSLOG_RPMSG_SPACE(priv);
@ -340,11 +365,12 @@ static ssize_t syslog_rpmsg_file_write(FAR struct file *filep,
int syslog_rpmsg_putc(FAR syslog_channel_t *channel, int ch) int syslog_rpmsg_putc(FAR syslog_channel_t *channel, int ch)
{ {
FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg;
irqstate_t flags; irqstate_t flags;
char tmp = ch;
UNUSED(channel);
flags = enter_critical_section(); flags = enter_critical_section();
syslog_rpmsg_putchar(priv, ch, true); syslog_rpmsg_addbuf(&g_syslog_rpmsg, &tmp, 1);
leave_critical_section(flags); leave_critical_section(flags);
return ch; return ch;
@ -363,12 +389,13 @@ int syslog_rpmsg_flush(FAR syslog_channel_t *channel)
priv->flush = priv->tail; priv->flush = priv->tail;
} }
while (priv->flush < priv->head) if (priv->flush < priv->head)
{ {
size_t len = priv->head - priv->flush;
#if defined(CONFIG_ARCH_LOWPUTC) #if defined(CONFIG_ARCH_LOWPUTC)
up_putc(priv->buffer[SYSLOG_RPMSG_FLUSHOFF(priv)]); up_nputs(&priv->buffer[SYSLOG_RPMSG_FLUSHOFF(priv)], len);
#endif #endif
priv->flush++; priv->flush += len;
} }
leave_critical_section(flags); leave_critical_section(flags);
@ -380,15 +407,8 @@ ssize_t syslog_rpmsg_write(FAR syslog_channel_t *channel,
FAR const char *buffer, size_t buflen) FAR const char *buffer, size_t buflen)
{ {
FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg; FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg;
irqstate_t flags; irqstate_t flags = enter_critical_section();
size_t nwritten; syslog_rpmsg_addbuf(priv, buffer, buflen);
flags = enter_critical_section();
for (nwritten = 1; nwritten <= buflen; nwritten++)
{
syslog_rpmsg_putchar(priv, *buffer++, nwritten == buflen);
}
leave_critical_section(flags); leave_critical_section(flags);
return buflen; return buflen;