syslog: Add sc_write_force callback

It is used to write the log message to the channel immediately
when the log message is generated in the interrupt context, which
is faster than the normal force callback.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-06-21 08:16:55 +08:00 committed by Alan Carvalho de Assis
parent e62c915972
commit efd1b838e6
7 changed files with 75 additions and 68 deletions

View File

@ -91,6 +91,7 @@ static const struct syslog_channel_ops_s g_rpmsg_channel_ops =
syslog_rpmsg_putc,
syslog_rpmsg_putc,
syslog_rpmsg_flush,
syslog_rpmsg_write,
syslog_rpmsg_write
};
@ -106,6 +107,7 @@ static const struct syslog_channel_ops_s g_rtt_channel_ops =
syslog_rtt_putc,
syslog_rtt_putc,
NULL,
syslog_rtt_write,
syslog_rtt_write
};
@ -262,9 +264,6 @@ int syslog_channel(FAR struct syslog_channel_s *channel)
if (channel != NULL)
{
DEBUGASSERT(channel->sc_ops->sc_putc != NULL &&
channel->sc_ops->sc_force != NULL);
#if (CONFIG_SYSLOG_MAX_CHANNELS == 1)
g_syslog_channel[0] = channel;
return OK;

View File

@ -106,6 +106,7 @@ static const struct syslog_channel_ops_s g_syslog_dev_ops =
syslog_dev_force,
syslog_dev_flush,
syslog_dev_write,
NULL,
syslog_dev_uninitialize
};

View File

@ -76,16 +76,18 @@ int syslog_flush(void)
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
if (g_syslog_channel[i] == NULL)
FAR struct syslog_channel_s *channel = g_syslog_channel[i];
if (channel == NULL)
{
break;
}
/* Then flush all of the buffered output to the SYSLOG device */
if (g_syslog_channel[i]->sc_ops->sc_flush != NULL)
if (channel->sc_ops->sc_flush != NULL)
{
g_syslog_channel[i]->sc_ops->sc_flush(g_syslog_channel[i]);
channel->sc_ops->sc_flush(channel);
}
}

View File

@ -83,15 +83,24 @@ int syslog_putc(int ch)
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
if (g_syslog_channel[i] == NULL)
FAR struct syslog_channel_s *channel = g_syslog_channel[i];
if (channel == NULL)
{
break;
}
DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL);
if (channel->sc_ops->sc_force != NULL)
{
channel->sc_ops->sc_force(channel, ch);
}
else
{
char tmp = ch;
g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i],
ch);
DEBUGASSERT(channel->sc_ops->sc_write_force != NULL);
channel->sc_ops->sc_write_force(channel, &tmp, 1);
}
}
}
}
@ -107,14 +116,23 @@ int syslog_putc(int ch)
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
if (g_syslog_channel[i] == NULL)
FAR struct syslog_channel_s *channel = g_syslog_channel[i];
if (channel == NULL)
{
break;
}
DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL);
g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i], ch);
if (channel->sc_ops->sc_putc != NULL)
{
channel->sc_ops->sc_putc(channel, ch);
}
else
{
char tmp = ch;
DEBUGASSERT(channel->sc_ops->sc_write != NULL);
channel->sc_ops->sc_write(channel, &tmp, 1);
}
}
}

View File

@ -63,9 +63,10 @@ void syslog_stream_uninit(FAR struct syslog_channel_s *channel);
static const struct syslog_channel_ops_s g_syslog_stream_ops =
{
syslog_stream_putc,
syslog_stream_force,
NULL,
syslog_stream_flush,
syslog_stream_write,
syslog_stream_write,
syslog_stream_uninit
};
@ -135,31 +136,6 @@ static int syslog_stream_putc(FAR struct syslog_channel_s *channel, int ch)
return OK;
}
/****************************************************************************
* Name: syslog_stream_force
*
* Description:
* Force output in interrupt context.
*
* Input Parameters:
* channel - Handle to syslog channel to be used.
* ch - The character to add to the SYSLOG (must be positive).
*
* Returned Value:
* On success, the character is echoed back to the caller. A negated
* errno value is returned on any failure.
*
****************************************************************************/
static int syslog_stream_force(FAR struct syslog_channel_s *channel, int ch)
{
FAR struct syslog_stream_s *chan =
(FAR struct syslog_stream_s *)channel;
lib_stream_putc(chan->stream, ch);
return OK;
}
/****************************************************************************
* Name: syslog_stream_flush
*

View File

@ -57,31 +57,43 @@
static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
{
int i;
size_t nwritten = 0;
int i;
if (up_interrupt_context() || sched_idletask())
{
for (nwritten = 0; nwritten < buflen; nwritten++)
{
#ifdef CONFIG_SYSLOG_INTBUFFER
if (up_interrupt_context())
if (up_interrupt_context())
{
for (nwritten = 0; nwritten < buflen; nwritten++)
{
syslog_add_intbuffer(buffer[nwritten]);
}
else
}
else
#endif
{
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
if (g_syslog_channel[i] == NULL)
{
break;
}
FAR struct syslog_channel_s *channel = g_syslog_channel[i];
DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL);
g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i],
buffer[nwritten]);
if (channel == NULL)
{
break;
}
if (channel->sc_ops->sc_write_force != NULL)
{
nwritten =
channel->sc_ops->sc_write_force(channel, buffer, buflen);
}
else
{
DEBUGASSERT(channel->sc_ops->sc_force != NULL);
for (nwritten = 0; nwritten < buflen; nwritten++)
{
channel->sc_ops->sc_force(channel, buffer[nwritten]);
}
}
}
}
@ -90,25 +102,23 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
{
for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++)
{
if (g_syslog_channel[i] == NULL)
FAR struct syslog_channel_s *channel = g_syslog_channel[i];
if (channel == NULL)
{
break;
}
if (g_syslog_channel[i]->sc_ops->sc_write)
if (channel->sc_ops->sc_write != NULL)
{
nwritten =
g_syslog_channel[i]->sc_ops->sc_write(g_syslog_channel[i],
buffer, buflen);
nwritten = channel->sc_ops->sc_write(channel, buffer, buflen);
}
else
{
DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL);
DEBUGASSERT(channel->sc_ops->sc_putc != NULL);
for (nwritten = 0; nwritten < buflen; nwritten++)
{
g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i],
buffer[nwritten]);
channel->sc_ops->sc_putc(channel, buffer[nwritten]);
}
}
}

View File

@ -100,11 +100,12 @@ typedef CODE void (*syslog_close_t)(FAR struct syslog_channel_s *channel);
struct syslog_channel_ops_s
{
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
syslog_write_t sc_write; /* Write multiple bytes */
syslog_close_t sc_close; /* Channel close callback */
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
syslog_write_t sc_write; /* Write multiple bytes */
syslog_write_t sc_write_force; /* Write multiple bytes for interrupt handlers */
syslog_close_t sc_close; /* Channel close callback */
};
/* This structure provides the interface to a SYSLOG channel */