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:
parent
6a8c638d57
commit
e920883458
@ -45,7 +45,6 @@ CONFIG_PHOTON_WDG_THREAD=y
|
|||||||
CONFIG_PREALLOC_TIMERS=4
|
CONFIG_PREALLOC_TIMERS=4
|
||||||
CONFIG_RAMLOG=y
|
CONFIG_RAMLOG=y
|
||||||
CONFIG_RAMLOG_BUFSIZE=2048
|
CONFIG_RAMLOG_BUFSIZE=2048
|
||||||
CONFIG_RAMLOG_OVERWRITE=y
|
|
||||||
CONFIG_RAMLOG_SYSLOG=y
|
CONFIG_RAMLOG_SYSLOG=y
|
||||||
CONFIG_RAM_SIZE=114688
|
CONFIG_RAM_SIZE=114688
|
||||||
CONFIG_RAM_START=0x20000000
|
CONFIG_RAM_START=0x20000000
|
||||||
|
@ -54,13 +54,6 @@ config RAMLOG_NPOLLWAITERS
|
|||||||
---help---
|
---help---
|
||||||
The maximum number of threads that may be waiting on the poll method.
|
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
|
config RAMLOG_POLLTHRESHOLD
|
||||||
int "The threshold value of circular buffer to notify poll waiters"
|
int "The threshold value of circular buffer to notify poll waiters"
|
||||||
default 1
|
default 1
|
||||||
|
@ -83,11 +83,11 @@ struct ramlog_dev_s
|
|||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
|
|
||||||
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
#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
|
#endif
|
||||||
static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv,
|
static void ramlog_pollnotify(FAR struct ramlog_dev_s *priv,
|
||||||
pollevent_t eventset);
|
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 */
|
/* Character driver methods */
|
||||||
|
|
||||||
@ -166,16 +166,15 @@ static size_t ramlog_bufferused(FAR struct ramlog_dev_s *priv)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
#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;
|
irqstate_t flags;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Notify all waiting readers that they can read from the FIFO */
|
/* Notify all waiting readers that they can read from the FIFO */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
|
|
||||||
for (i = 0; ; i++)
|
for (; ; )
|
||||||
{
|
{
|
||||||
int semcount = 0;
|
int semcount = 0;
|
||||||
|
|
||||||
@ -189,10 +188,6 @@ static int ramlog_readnotify(FAR struct ramlog_dev_s *priv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
/* Return number of notified readers. */
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -286,7 +281,7 @@ static void ramlog_initbuf(void)
|
|||||||
* Name: ramlog_addchar
|
* 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;
|
irqstate_t flags;
|
||||||
size_t nexthead;
|
size_t nexthead;
|
||||||
@ -308,7 +303,7 @@ static int ramlog_addchar(FAR struct ramlog_dev_s *priv, char ch)
|
|||||||
if (ch == '\r')
|
if (ch == '\r')
|
||||||
{
|
{
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
return OK;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pre-pend a carriage before a linefeed */
|
/* Pre-pend a carriage before a linefeed */
|
||||||
@ -333,7 +328,6 @@ again:
|
|||||||
|
|
||||||
if (nexthead == priv->rl_tail)
|
if (nexthead == priv->rl_tail)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_RAMLOG_OVERWRITE
|
|
||||||
/* Yes... Overwrite with the latest log in the circular buffer */
|
/* Yes... Overwrite with the latest log in the circular buffer */
|
||||||
|
|
||||||
priv->rl_buffer[priv->rl_tail] = '\0';
|
priv->rl_buffer[priv->rl_tail] = '\0';
|
||||||
@ -342,12 +336,6 @@ again:
|
|||||||
{
|
{
|
||||||
priv->rl_tail = 0;
|
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 */
|
/* No... copy the byte and re-enable interrupts */
|
||||||
@ -364,7 +352,6 @@ again:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -374,8 +361,7 @@ 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)
|
||||||
{
|
{
|
||||||
int readers_waken;
|
size_t nwritten;
|
||||||
ssize_t nwritten;
|
|
||||||
char ch;
|
char ch;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -385,7 +371,7 @@ static ssize_t ramlog_addbuf(FAR struct ramlog_dev_s *priv,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (nwritten = 0; (size_t)nwritten < len; nwritten++)
|
for (nwritten = 0; nwritten < len; nwritten++)
|
||||||
{
|
{
|
||||||
/* Get the next character to output */
|
/* 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 */
|
/* Then output the character */
|
||||||
|
|
||||||
ret = ramlog_addchar(priv, ch);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Was anything written? */
|
/* Was anything written? */
|
||||||
|
|
||||||
if (nwritten > 0)
|
if (nwritten > 0)
|
||||||
{
|
{
|
||||||
readers_waken = 0;
|
|
||||||
|
|
||||||
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
||||||
/* Are there threads waiting for read data? */
|
/* Are there threads waiting for read data? */
|
||||||
|
|
||||||
readers_waken = ramlog_readnotify(priv);
|
ramlog_readnotify(priv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If there are multiple readers, some of them might block despite
|
if (ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
/* Notify all poll/select waiters that they can read from the
|
/* Notify all poll/select waiters that they can read from the
|
||||||
* FIFO.
|
* FIFO.
|
||||||
@ -547,14 +513,7 @@ static ssize_t ramlog_file_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
* anything already before waiting.
|
* anything already before waiting.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nread = ret;
|
return 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;
|
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_RAMLOG_NONBLOCKING */
|
#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);
|
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 the number of characters actually read */
|
||||||
|
|
||||||
return nread;
|
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 inode *inode = filep->f_inode;
|
||||||
FAR struct ramlog_dev_s *priv;
|
FAR struct ramlog_dev_s *priv;
|
||||||
pollevent_t eventset;
|
pollevent_t eventset = POLLOUT;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
size_t next_head;
|
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
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? */
|
/* Should immediately notify on any of the requested events? */
|
||||||
|
|
||||||
eventset = 0;
|
|
||||||
|
|
||||||
flags = enter_critical_section();
|
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. */
|
/* 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)
|
int ramlog_putc(FAR struct syslog_channel_s *channel, int ch)
|
||||||
{
|
{
|
||||||
FAR struct ramlog_dev_s *priv = &g_sysdev;
|
FAR struct ramlog_dev_s *priv = &g_sysdev;
|
||||||
int readers_waken = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
UNUSED(channel);
|
UNUSED(channel);
|
||||||
|
|
||||||
/* Add the character to the RAMLOG */
|
/* Add the character to the RAMLOG */
|
||||||
|
|
||||||
ret = ramlog_addchar(priv, ch);
|
ramlog_addchar(priv, ch);
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
/* The buffer is full and 'ch' was not saved. */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
#ifndef CONFIG_RAMLOG_NONBLOCKING
|
||||||
/* Are there threads waiting for read data? */
|
/* Are there threads waiting for read data? */
|
||||||
|
|
||||||
readers_waken = ramlog_readnotify(priv);
|
ramlog_readnotify(priv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If there are multiple readers, some of them might block despite
|
if (ramlog_bufferused(priv) >= CONFIG_RAMLOG_POLLTHRESHOLD)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
/* Notify all poll/select waiters that they can read from the FIFO */
|
/* Notify all poll/select waiters that they can read from the FIFO */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user