syslog/ramlog: Prepare to support the multiple reader

1.Remove RAMLOG_OVERWRITE option and related code
2.Broadcast the readability to all reader and poller

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2023-11-18 18:14:25 +08:00 committed by Xiang Xiao
parent 6a8c638d57
commit e920883458
3 changed files with 16 additions and 109 deletions

View File

@ -45,7 +45,6 @@ CONFIG_PHOTON_WDG_THREAD=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAMLOG=y
CONFIG_RAMLOG_BUFSIZE=2048
CONFIG_RAMLOG_OVERWRITE=y
CONFIG_RAMLOG_SYSLOG=y
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000

View File

@ -54,13 +54,6 @@ config RAMLOG_NPOLLWAITERS
---help---
The maximum number of threads that may be waiting on the poll method.
config RAMLOG_OVERWRITE
bool "RAMLOG overwrite circular buffer"
default n
---help---
Enable overwrite of circular buffer. If RAMLOG buffer overflows,
overwrite it from the top of buffer and always keep the latest log.
config RAMLOG_POLLTHRESHOLD
int "The threshold value of circular buffer to notify poll waiters"
default 1

View File

@ -83,11 +83,11 @@ struct ramlog_dev_s
/* Helper functions */
#ifndef CONFIG_RAMLOG_NONBLOCKING
static int ramlog_readnotify(FAR struct ramlog_dev_s *priv);
static void ramlog_readnotify(FAR struct ramlog_dev_s *priv);
#endif
static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv,
pollevent_t eventset);
static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch);
static void ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch);
/* Character driver methods */
@ -166,16 +166,15 @@ static size_t ramlog_bufferused(FAR struct ramlog_dev_s *priv)
****************************************************************************/
#ifndef CONFIG_RAMLOG_NONBLOCKING
static int ramlog_readnotify(FAR struct ramlog_dev_s *priv)
static void ramlog_readnotify(FAR struct ramlog_dev_s *priv)
{
irqstate_t flags;
int i;
/* Notify all waiting readers that they can read from the FIFO */
flags = enter_critical_section();
for (i = 0; ; i++)
for (; ; )
{
int semcount = 0;
@ -189,10 +188,6 @@ static int ramlog_readnotify(FAR struct ramlog_dev_s *priv)
}
leave_critical_section(flags);
/* Return number of notified readers. */
return i;
}
#endif
@ -286,7 +281,7 @@ static void ramlog_initbuf(void)
* Name: ramlog_addchar
****************************************************************************/
static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch)
static void ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch)
{
irqstate_t flags;
size_t nexthead;
@ -308,7 +303,7 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch)
if (ch == '\r')
{
leave_critical_section(flags);
return OK;
return;
}
/* Pre-pend a carriage before a linefeed */
@ -333,7 +328,6 @@ again:
if (nexthead == priv->rl_tail)
{
#ifdef CONFIG_RAMLOG_OVERWRITE
/* Yes... Overwrite with the latest log in the circular buffer */
priv->rl_buffer[priv->rl_tail] = '\0';
@ -342,12 +336,6 @@ again:
{
priv->rl_tail = 0;
}
#else
/* Yes... Return an indication that nothing was saved in the buffer. */
leave_critical_section(flags);
return -EBUSY;
#endif
}
/* No... copy the byte and re-enable interrupts */
@ -364,7 +352,6 @@ again:
#endif
leave_critical_section(flags);
return OK;
}
/****************************************************************************
@ -374,8 +361,7 @@ again:
static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv,
FAR const char *buffer, size_t len)
{
int readers_waken;
ssize_t nwritten;
size_t nwritten;
char ch;
int ret;
@ -385,7 +371,7 @@ static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv,
return ret;
}
for (nwritten = 0; (size_t)nwritten < len; nwritten++)
for (nwritten = 0; nwritten < len; nwritten++)
{
/* Get the next character to output */
@ -393,40 +379,20 @@ static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv,
/* Then output the character */
ret = ramlog_addchar(priv, ch);
if (ret < 0)
{
/* The buffer is full and nothing was saved. The remaining
* data to be written is dropped on the floor.
*/
break;
}
ramlog_addchar(priv, ch);
}
/* Was anything written? */
if (nwritten > 0)
{
readers_waken = 0;
#ifndef CONFIG_RAMLOG_NONBLOCKING
/* Are there threads waiting for read data? */
readers_waken = ramlog_readnotify(priv);
ramlog_readnotify(priv);
#endif
/* If there are multiple readers, some of them might block despite
* POLLIN because first reader might read all data. Favor readers
* and notify poll waiters only if no reader was awakened, even if
* the latter may starve.
*
* This also implies we do not have to make these two notify
* operations a critical section.
*/
if (readers_waken == 0 &&
ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
if (ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
{
/* Notify all poll/select waiters that they can read from the
* FIFO.
@ -547,14 +513,7 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
* anything already before waiting.
*/
nread = ret;
/* Break out to return what we have. Note, we can't exactly
* "break" out because whichever error occurred, we do not hold
* the exclusion mutex.
*/
goto errout_without_lock;
return ret;
}
#endif /* CONFIG_RAMLOG_NONBLOCKING */
}
@ -585,17 +544,6 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
nxmutex_unlock(&priv->rl_lock);
/* Notify all poll/select waiters that they can write to the FIFO */
#ifndef CONFIG_RAMLOG_NONBLOCKING
errout_without_lock:
#endif
if (nread > 0)
{
ramlog_pollnotify(priv, POLLOUT);
}
/* Return the number of characters actually read */
return nread;
@ -662,9 +610,8 @@ static int ramlog_file_poll(FAR struct file *filep, FAR struct pollfd *fds,
{
FAR struct inode *inode = filep->f_inode;
FAR struct ramlog_dev_s *priv;
pollevent_t eventset;
pollevent_t eventset = POLLOUT;
irqstate_t flags;
size_t next_head;
int ret;
int i;
@ -712,21 +659,7 @@ static int ramlog_file_poll(FAR struct file *filep, FAR struct pollfd *fds,
/* Should immediately notify on any of the requested events? */
eventset = 0;
flags = enter_critical_section();
next_head = priv->rl_head + 1;
if (next_head >= priv->rl_bufsize)
{
next_head = 0;
}
/* First, check if the receive buffer is not full. */
if (next_head != priv->rl_tail)
{
eventset |= POLLOUT;
}
/* Check if the receive buffer is not empty. */
@ -846,38 +779,20 @@ void ramlog_syslog_register(void)
int ramlog_putc(FAR struct syslog_channel_s *channel, int ch)
{
FAR struct ramlog_dev_s *priv = &g_sysdev;
int readers_waken = 0;
int ret;
UNUSED(channel);
/* Add the character to the RAMLOG */
ret = ramlog_addchar(priv, ch);
if (ret < 0)
{
/* The buffer is full and 'ch' was not saved. */
return ret;
}
ramlog_addchar(priv, ch);
#ifndef CONFIG_RAMLOG_NONBLOCKING
/* Are there threads waiting for read data? */
readers_waken = ramlog_readnotify(priv);
ramlog_readnotify(priv);
#endif
/* If there are multiple readers, some of them might block despite
* POLLIN because first reader might read all data. Favor readers
* and notify poll waiters only if no reader was awakened, even if
* the latter may starve.
*
* This also implies we do not have to make these two notify
* operations a critical section.
*/
if (readers_waken == 0 &&
ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
if (ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
{
/* Notify all poll/select waiters that they can read from the FIFO */