From 064c65357be85989989f2c94a04535be4eb156fb Mon Sep 17 00:00:00 2001 From: chao an Date: Wed, 11 Dec 2024 15:34:19 +0800 Subject: [PATCH] syslog/channel: unify syslog channel writing to reduce redundant code unify syslog channel writing to reduce redundant code Signed-off-by: chao an --- drivers/syslog/syslog.h | 22 +++ drivers/syslog/syslog_intbuffer.c | 82 +--------- drivers/syslog/syslog_write.c | 257 ++++++++++-------------------- 3 files changed, 110 insertions(+), 251 deletions(-) diff --git a/drivers/syslog/syslog.h b/drivers/syslog/syslog.h index eec0f7f12d70a..13d4acb20d077 100644 --- a/drivers/syslog/syslog.h +++ b/drivers/syslog/syslog.h @@ -230,6 +230,28 @@ int syslog_add_intbuffer(int ch); #ifdef CONFIG_SYSLOG_INTBUFFER int syslog_flush_intbuffer(bool force); #endif + +/**************************************************************************** + * Name: syslog_write_foreach + * + * Description: + * This provides a default write method for syslog devices that do not + * support multiple byte writes This functions simply loops, outputting + * one character at a time. + * + * Input Parameters: + * buffer - The buffer containing the data to be output + * buflen - The number of bytes in the buffer + * force - Use the force() method of the channel vs. the putc() method. + * + * Returned Value: + * On success, the number of characters written is returned. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +ssize_t syslog_write_foreach(FAR const char *buffer, + size_t buflen, bool force); #endif /* CONFIG_SYSLOG */ #undef EXTERN diff --git a/drivers/syslog/syslog_intbuffer.c b/drivers/syslog/syslog_intbuffer.c index eb1da33abf21b..701148adb7107 100644 --- a/drivers/syslog/syslog_intbuffer.c +++ b/drivers/syslog/syslog_intbuffer.c @@ -185,46 +185,11 @@ int syslog_add_intbuffer(int ch) if (inuse == CONFIG_SYSLOG_INTBUFSIZE - 1) { - int oldch = syslog_remove_intbuffer(); - int i; + char oldch = syslog_remove_intbuffer(); - for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) - { - FAR syslog_channel_t *channel = g_syslog_channel[i]; - - if (channel == NULL) - { - break; - } - -#ifdef CONFIG_SYSLOG_IOCTL - if (channel->sc_state & SYSLOG_CHANNEL_DISABLE) - { - continue; - } -#endif - - if (channel->sc_ops->sc_force == NULL) - { - continue; - } - -#ifdef CONFIG_SYSLOG_CRLF - /* Check for LF */ - - if (oldch == '\n' && - !(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) - { - /* Add CR */ + syslog_write_foreach(&oldch, 1, true); - channel->sc_ops->sc_force(channel, '\r'); - } -#endif - - channel->sc_ops->sc_force(channel, oldch); - } - - ret = -ENOSPC; + ret = -ENOSPC; } /* Copy one character */ @@ -265,7 +230,7 @@ int syslog_add_intbuffer(int ch) int syslog_flush_intbuffer(bool force) { irqstate_t flags; - int ch; + char ch; /* This logic is performed with the scheduler disabled to protect from * concurrent modification by other tasks. @@ -275,8 +240,6 @@ int syslog_flush_intbuffer(bool force) for (; ; ) { - int i; - /* Transfer one character to time. This is inefficient, but is * done in this way to: (1) Deal with concurrent modification of * the interrupt buffer from interrupt activity, (2) Avoid keeper @@ -290,42 +253,7 @@ int syslog_flush_intbuffer(bool force) break; } - for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) - { - FAR syslog_channel_t *channel = g_syslog_channel[i]; - syslog_putc_t putfunc; - - if (channel == NULL) - { - break; - } - -#ifdef CONFIG_SYSLOG_IOCTL - if (channel->sc_state & SYSLOG_CHANNEL_DISABLE) - { - continue; - } -#endif - - /* Select which putc function to use for this flush */ - - putfunc = force ? channel->sc_ops->sc_force : - channel->sc_ops->sc_putc; - -#ifdef CONFIG_SYSLOG_CRLF - /* Check for LF */ - - if (ch == '\n' && - !(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) - { - /* Add CR */ - - putfunc(channel, '\r'); - } -#endif - - putfunc(channel, ch); - } + syslog_write_foreach(&ch, 1, force); } leave_critical_section(flags); diff --git a/drivers/syslog/syslog_write.c b/drivers/syslog/syslog_write.c index 33788e5d38781..2756e8715c459 100644 --- a/drivers/syslog/syslog_write.c +++ b/drivers/syslog/syslog_write.c @@ -77,7 +77,11 @@ static bool syslog_safe_to_block(void) } /**************************************************************************** - * Name: syslog_default_write + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: syslog_write_foreach * * Description: * This provides a default write method for syslog devices that do not @@ -94,227 +98,117 @@ static bool syslog_safe_to_block(void) * ****************************************************************************/ -static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen) +ssize_t syslog_write_foreach(FAR const char *buffer, + size_t buflen, bool force) { + syslog_write_t write; + syslog_putc_t putc; size_t nwritten; + ssize_t ret; + int i; - if (!syslog_safe_to_block()) + for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) { -#ifdef CONFIG_SYSLOG_INTBUFFER - if (up_interrupt_context()) + FAR syslog_channel_t *channel = g_syslog_channel[i]; + + if (channel == NULL) { - for (nwritten = 0; nwritten < buflen; nwritten++) - { - syslog_add_intbuffer(buffer[nwritten]); - } + break; + } + +#ifdef CONFIG_SYSLOG_IOCTL + if (channel->sc_state & SYSLOG_CHANNEL_DISABLE) + { + continue; } - else #endif + + write = !force ? channel->sc_ops->sc_write : + channel->sc_ops->sc_write_force; + if (write != NULL) { - int i; + nwritten = 0; - for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) +#ifdef CONFIG_SYSLOG_CRLF + if (!(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) { - FAR syslog_channel_t *channel = g_syslog_channel[i]; - nwritten = 0; - - if (channel == NULL) - { - break; - } + size_t head; -#ifdef CONFIG_SYSLOG_IOCTL - if (channel->sc_state & SYSLOG_CHANNEL_DISABLE) - { - continue; - } -#endif - - if (channel->sc_ops->sc_write_force != NULL) + for (head = 0; head < buflen; head++) { -#ifdef CONFIG_SYSLOG_CRLF - if (!(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) + if (buffer[head] != '\n') { - size_t head; - - for (head = 0; head < buflen; head++) - { - ssize_t ret; - - /* Check for LF */ - - if (buffer[head] != '\n') - { - continue; - } - - ret = channel->sc_ops->sc_write_force(channel, - buffer + nwritten, - head - nwritten); - if (ret < 0) - { - return ret; - } - - ret = channel->sc_ops->sc_write_force(channel, - "\r\n", 2); - if (ret < 0) - { - return ret; - } - - nwritten = head + 1; - } + continue; } -#endif - if (nwritten < buflen) + ret = write(channel, buffer + nwritten, head - nwritten); + if (ret >= 0) { - ssize_t ret; - - ret = channel->sc_ops->sc_write_force(channel, - buffer + nwritten, - buflen - nwritten); - if (ret < 0) - { - return ret; - } - else - { - nwritten += ret; - } + ret = write(channel, "\r\n", 2); } - } - else - { - DEBUGASSERT(channel->sc_ops->sc_force != NULL); - for (nwritten = 0; nwritten < buflen; nwritten++) - { -#ifdef CONFIG_SYSLOG_CRLF - /* Check for LF */ - if (buffer[nwritten] == '\n' && - !(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) - { - /* Add CR */ + if (ret < 0) + { + return ret; + } - channel->sc_ops->sc_force(channel, '\r'); - } + nwritten = head + 1; + } + } #endif - channel->sc_ops->sc_force(channel, buffer[nwritten]); - } + if (nwritten < buflen) + { + ret = write(channel, buffer + nwritten, buflen - nwritten); + if (ret < 0) + { + return ret; + } + else + { + nwritten += ret; } } } - } - else - { - int i; - - for (i = 0; i < CONFIG_SYSLOG_MAX_CHANNELS; i++) + else { - FAR syslog_channel_t *channel = g_syslog_channel[i]; - nwritten = 0; - - if (channel == NULL) - { - break; - } - -#ifdef CONFIG_SYSLOG_IOCTL - if (channel->sc_state & SYSLOG_CHANNEL_DISABLE) + putc = !force ? channel->sc_ops->sc_putc : + channel->sc_ops->sc_force; + if (putc == NULL) { continue; } -#endif - - if (channel->sc_ops->sc_write != NULL) - { #ifdef CONFIG_SYSLOG_CRLF - if (!(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) - { - size_t head; - - for (head = 0; head < buflen; head++) - { - size_t ret; - - /* Check for LF */ - - if (buffer[head] != '\n') - { - continue; - } - - ret = channel->sc_ops->sc_write(channel, - buffer + nwritten, - head - nwritten); - if (ret < 0) - { - return ret; - } - - /* Add CR */ - - ret = channel->sc_ops->sc_write(channel, "\r\n", 2); - if (ret < 0) - { - return ret; - } - - nwritten = head + 1; - } - } + if (channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF) #endif - - if (nwritten < buflen) + { + for (nwritten = 0; nwritten < buflen; nwritten++) { - ssize_t ret; - - ret = channel->sc_ops->sc_write(channel, - buffer + nwritten, - buflen - nwritten); - if (ret < 0) - { - return ret; - } - else - { - nwritten += ret; - } + putc(channel, buffer[nwritten]); } } +#ifdef CONFIG_SYSLOG_CRLF else { - DEBUGASSERT(channel->sc_ops->sc_putc != NULL); for (nwritten = 0; nwritten < buflen; nwritten++) { -#ifdef CONFIG_SYSLOG_CRLF - /* Check for LF */ - - if (buffer[nwritten] == '\n' && - !(channel->sc_state & SYSLOG_CHANNEL_DISABLE_CRLF)) + if (buffer[nwritten] == '\n') { /* Add CR */ - channel->sc_ops->sc_putc(channel, '\r'); + putc(channel, '\r'); } -#endif - channel->sc_ops->sc_putc(channel, buffer[nwritten]); + putc(channel, buffer[nwritten]); } } +#endif } } return nwritten; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: syslog_write * @@ -333,8 +227,23 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen) ssize_t syslog_write(FAR const char *buffer, size_t buflen) { + bool force; + + force = !syslog_safe_to_block(); + #ifdef CONFIG_SYSLOG_INTBUFFER - if (!up_interrupt_context() && !sched_idletask()) + if (force) + { + size_t nwritten; + + for (nwritten = 0; nwritten < buflen; nwritten++) + { + syslog_add_intbuffer(buffer[nwritten]); + } + + return buflen; + } + else { /* Flush any characters that may have been added to the interrupt * buffer. @@ -344,5 +253,5 @@ ssize_t syslog_write(FAR const char *buffer, size_t buflen) } #endif - return syslog_default_write(buffer, buflen); + return syslog_write_foreach(buffer, buflen, force); }