drivers/pipe:add PIPEIOC_POLLTHRES to set POLLIN/POLLOUT threshold

Signed-off-by: 田昕 <tianxin7@xiaomi.com>
This commit is contained in:
田昕 2023-01-06 20:51:14 +08:00 committed by Xiang Xiao
parent fae5aef4fe
commit 587305723e
3 changed files with 96 additions and 24 deletions

View File

@ -60,6 +60,26 @@
# define pipe_dumpbuffer(m,a,n)
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: pipecommon_bufferused
****************************************************************************/
static pipe_ndx_t pipecommon_bufferused(FAR struct pipe_dev_s *dev)
{
if (dev->d_wrndx >= dev->d_rdndx)
{
return dev->d_wrndx - dev->d_rdndx;
}
else
{
return dev->d_bufsize + dev->d_wrndx - dev->d_rdndx;
}
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -417,9 +437,14 @@ ssize_t pipecommon_read(FAR struct file *filep, FAR char *buffer, size_t len)
nread++;
}
/* Notify all poll/select waiters that they can write to the FIFO */
/* Notify all poll/select waiters that they can write to the
* FIFO when buffer can accept more than d_polloutthrd bytes.
*/
poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLOUT);
if (pipecommon_bufferused(dev) < (dev->d_bufsize - dev->d_polloutthrd))
{
poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLOUT);
}
/* Notify all waiting writers that bytes have been removed from the
* buffer.
@ -527,10 +552,14 @@ ssize_t pipecommon_write(FAR struct file *filep, FAR const char *buffer,
if ((size_t)nwritten >= len)
{
/* Notify all poll/select waiters that they can read from the
* FIFO.
* FIFO when buffer used exceeds poll threshold.
*/
poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS, POLLIN);
if (pipecommon_bufferused(dev) > dev->d_pollinthrd)
{
poll_notify(dev->d_fds, CONFIG_DEV_PIPE_NPOLLWAITERS,
POLLIN);
}
/* Yes.. Notify all of the waiting readers that more data is
* available.
@ -661,28 +690,23 @@ int pipecommon_poll(FAR struct file *filep, FAR struct pollfd *fds,
* First, determine how many bytes are in the buffer
*/
if (dev->d_wrndx >= dev->d_rdndx)
{
nbytes = dev->d_wrndx - dev->d_rdndx;
}
else
{
nbytes = dev->d_bufsize + dev->d_wrndx - dev->d_rdndx;
}
nbytes = pipecommon_bufferused(dev);
/* Notify the POLLOUT event if the pipe is not full, but only if
/* Notify the POLLOUT event if the pipe buffer can accept
* more than d_polloutthrd bytes, but only if
* there is readers.
*/
eventset = 0;
if ((filep->f_oflags & O_WROK) && (nbytes < (dev->d_bufsize - 1)))
if ((filep->f_oflags & O_WROK) &&
nbytes < (dev->d_bufsize - dev->d_polloutthrd))
{
eventset |= POLLOUT;
}
/* Notify the POLLIN event if the pipe is not empty */
/* Notify the POLLIN event if buffer used exceeds poll threshold */
if ((filep->f_oflags & O_RDOK) && (nbytes > 0))
if ((filep->f_oflags & O_RDOK) && (nbytes > dev->d_pollinthrd))
{
eventset |= POLLIN;
}
@ -772,6 +796,34 @@ int pipecommon_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
case PIPEIOC_POLLINTHRD:
{
pipe_ndx_t threshold = (pipe_ndx_t)arg;
if (threshold >= dev->d_bufsize)
{
ret = -EINVAL;
break;
}
dev->d_pollinthrd = threshold;
ret = OK;
}
break;
case PIPEIOC_POLLOUTTHRD:
{
pipe_ndx_t threshold = (pipe_ndx_t)arg;
if (threshold >= dev->d_bufsize)
{
ret = -EINVAL;
break;
}
dev->d_polloutthrd = threshold;
ret = OK;
}
break;
case FIONWRITE: /* Number of bytes waiting in send queue */
case FIONREAD: /* Number of bytes available for reading */
{

View File

@ -120,6 +120,8 @@ struct pipe_dev_s
pipe_ndx_t d_wrndx; /* Index in d_buffer to save next byte written */
pipe_ndx_t d_rdndx; /* Index in d_buffer to return the next byte read */
pipe_ndx_t d_bufsize; /* allocated size of d_buffer in bytes */
pipe_ndx_t d_pollinthrd; /* Buffer threshold for POLLIN to occur */
pipe_ndx_t d_polloutthrd; /* Buffer threshold for POLLOUT to occur */
uint8_t d_nwriters; /* Number of reference counts for write access */
uint8_t d_nreaders; /* Number of reference counts for read access */
uint8_t d_flags; /* See PIPE_FLAG_* definitions */

View File

@ -405,15 +405,33 @@
/* FIFOs and pipe driver ioctl definitions **********************************/
#define _PIPEIOCVALID(c) (_IOC_TYPE(c)==_PIPEBASE)
#define _PIPEIOC(nr) _IOC(_PIPEBASE,nr)
#define _PIPEIOCVALID(c) (_IOC_TYPE(c)==_PIPEBASE)
#define _PIPEIOC(nr) _IOC(_PIPEBASE,nr)
#define PIPEIOC_POLICY _PIPEIOC(0x0001) /* Set buffer policy
* IN: unsigned long integer
* 0=free on last close
* (default)
* 1=fre when empty
* OUT: None */
#define PIPEIOC_POLICY _PIPEIOC(0x0001) /* Set buffer policy
* IN: unsigned long integer
* 0=free on last close
* (default)
* 1=fre when empty
* OUT: None */
#define PIPEIOC_POLLINTHRD _PIPEIOC(0x0002) /* Set pipe POLLIN
* notifty buffer threshold.
* IN: unsigned long integer.
* POLLIN only occurs when
* buffer contains more
* bytes than the
* threshold.
* OUT: None */
#define PIPEIOC_POLLOUTTHRD _PIPEIOC(0x0003) /* Set pipe POLLOUT
* notifty buffer threshold.
* IN: unsigned long integer.
* POLLOUT only occurs
* when buffer can accept
* more bytes than
* threshold.
* OUT: None */
/* RTC driver ioctl definitions *********************************************/