Message ID | 20230522153144.30610-4-philmd@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | hw/char/pl011: Implement TX (async) FIFO to avoid blocking the main loop | expand |
On [2023 May 22] Mon 17:31:35, Philippe Mathieu-Daudé wrote: > To be able to poke at FIFO content without popping it, > introduce the fifo8_peek_buf() method by factoring > common content from fifo8_pop_buf(). > > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> > --- > include/qemu/fifo8.h | 26 ++++++++++++++++++++++++++ > util/fifo8.c | 22 ++++++++++++++++++---- > 2 files changed, 44 insertions(+), 4 deletions(-) > > diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h > index d0d02bc73d..7acf6d1347 100644 > --- a/include/qemu/fifo8.h > +++ b/include/qemu/fifo8.h > @@ -93,6 +93,32 @@ uint8_t fifo8_pop(Fifo8 *fifo); > */ > const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); > > +/** > + * fifo8_peek_buf: > + * @fifo: FIFO to poke from > + * @max: maximum number of bytes to pop > + * @numptr: pointer filled with number of bytes returned (can be NULL) > + * > + * Pop a number of elements from the FIFO up to a maximum of max. The buffer s/Pop/Peek into/ > + * containing the popped data is returned. This buffer points directly into s/popped data/data peeked into/ If above sounds good: Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com> > + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs > + * are called on the FIFO. (Above sounds as if it happens automatically to me but I'm not english native, a suggestion could be to put something as below "clients are responsible for tracking this") > + * > + * The function may return fewer bytes than requested when the data wraps > + * around in the ring buffer; in this case only a contiguous part of the data > + * is returned. > + * > + * The number of valid bytes returned is populated in *numptr; will always > + * return at least 1 byte. max must not be 0 or greater than the number of > + * bytes in the FIFO. > + * > + * Clients are responsible for checking the availability of requested data > + * using fifo8_num_used(). > + * > + * Returns: A pointer to peekable data. > + */ > +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); > + > /** > * fifo8_reset: > * @fifo: FIFO to reset > diff --git a/util/fifo8.c b/util/fifo8.c > index 032e985440..e12477843e 100644 > --- a/util/fifo8.c > +++ b/util/fifo8.c > @@ -66,7 +66,8 @@ uint8_t fifo8_pop(Fifo8 *fifo) > return ret; > } > > -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max, > + uint32_t *numptr, bool do_pop) > { > uint8_t *ret; > uint32_t num; > @@ -74,15 +75,28 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > assert(max > 0 && max <= fifo->num); > num = MIN(fifo->capacity - fifo->head, max); > ret = &fifo->data[fifo->head]; > - fifo->head += num; > - fifo->head %= fifo->capacity; > - fifo->num -= num; > + > + if (do_pop) { > + fifo->head += num; > + fifo->head %= fifo->capacity; > + fifo->num -= num; > + } > if (numptr) { > *numptr = num; > } > return ret; > } > > +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +{ > + return fifo8_peekpop_buf(fifo, max, numptr, false); > +} > + > +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +{ > + return fifo8_peekpop_buf(fifo, max, numptr, true); > +} > + > void fifo8_reset(Fifo8 *fifo) > { > fifo->num = 0; > -- > 2.38.1 > >
Philippe Mathieu-Daudé <philmd@linaro.org> writes: > To be able to poke at FIFO content without popping it, peek/poke are different operations in my head. You peek to read stuff and poke to change stuff, or at least thats what I did in BASIC back in the 80s. Either way I don't think peek and poke are synonyms. > introduce the fifo8_peek_buf() method by factoring > common content from fifo8_pop_buf(). > > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> > --- > include/qemu/fifo8.h | 26 ++++++++++++++++++++++++++ > util/fifo8.c | 22 ++++++++++++++++++---- > 2 files changed, 44 insertions(+), 4 deletions(-) > > diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h > index d0d02bc73d..7acf6d1347 100644 > --- a/include/qemu/fifo8.h > +++ b/include/qemu/fifo8.h > @@ -93,6 +93,32 @@ uint8_t fifo8_pop(Fifo8 *fifo); > */ > const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); > > +/** > + * fifo8_peek_buf: fifo8_peek_buf() - read upto max bytes from the fifo > + * @fifo: FIFO to poke from > + * @max: maximum number of bytes to pop > + * @numptr: pointer filled with number of bytes returned (can be NULL) > + * > + * Pop a number of elements from the FIFO up to a maximum of max. The buffer > + * containing the popped data is returned. This buffer points directly into > + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs > + * are called on the FIFO. > + * > + * The function may return fewer bytes than requested when the data wraps > + * around in the ring buffer; in this case only a contiguous part of the data > + * is returned. > + * > + * The number of valid bytes returned is populated in *numptr; will always > + * return at least 1 byte. max must not be 0 or greater than the number of > + * bytes in the FIFO. > + * > + * Clients are responsible for checking the availability of requested data > + * using fifo8_num_used(). > + * > + * Returns: A pointer to peekable data. > + */ > +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); > + > /** > * fifo8_reset: > * @fifo: FIFO to reset > diff --git a/util/fifo8.c b/util/fifo8.c > index 032e985440..e12477843e 100644 > --- a/util/fifo8.c > +++ b/util/fifo8.c > @@ -66,7 +66,8 @@ uint8_t fifo8_pop(Fifo8 *fifo) > return ret; > } > > -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max, > + uint32_t *numptr, bool do_pop) > { > uint8_t *ret; > uint32_t num; > @@ -74,15 +75,28 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > assert(max > 0 && max <= fifo->num); > num = MIN(fifo->capacity - fifo->head, max); > ret = &fifo->data[fifo->head]; > - fifo->head += num; > - fifo->head %= fifo->capacity; > - fifo->num -= num; > + > + if (do_pop) { > + fifo->head += num; > + fifo->head %= fifo->capacity; > + fifo->num -= num; > + } > if (numptr) { > *numptr = num; > } > return ret; > } > > +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +{ > + return fifo8_peekpop_buf(fifo, max, numptr, false); > +} > + > +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) > +{ > + return fifo8_peekpop_buf(fifo, max, numptr, true); > +} > + > void fifo8_reset(Fifo8 *fifo) > { > fifo->num = 0;
diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h index d0d02bc73d..7acf6d1347 100644 --- a/include/qemu/fifo8.h +++ b/include/qemu/fifo8.h @@ -93,6 +93,32 @@ uint8_t fifo8_pop(Fifo8 *fifo); */ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); +/** + * fifo8_peek_buf: + * @fifo: FIFO to poke from + * @max: maximum number of bytes to pop + * @numptr: pointer filled with number of bytes returned (can be NULL) + * + * Pop a number of elements from the FIFO up to a maximum of max. The buffer + * containing the popped data is returned. This buffer points directly into + * the FIFO backing store and data is invalidated once any of the fifo8_* APIs + * are called on the FIFO. + * + * The function may return fewer bytes than requested when the data wraps + * around in the ring buffer; in this case only a contiguous part of the data + * is returned. + * + * The number of valid bytes returned is populated in *numptr; will always + * return at least 1 byte. max must not be 0 or greater than the number of + * bytes in the FIFO. + * + * Clients are responsible for checking the availability of requested data + * using fifo8_num_used(). + * + * Returns: A pointer to peekable data. + */ +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr); + /** * fifo8_reset: * @fifo: FIFO to reset diff --git a/util/fifo8.c b/util/fifo8.c index 032e985440..e12477843e 100644 --- a/util/fifo8.c +++ b/util/fifo8.c @@ -66,7 +66,8 @@ uint8_t fifo8_pop(Fifo8 *fifo) return ret; } -const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) +static const uint8_t *fifo8_peekpop_buf(Fifo8 *fifo, uint32_t max, + uint32_t *numptr, bool do_pop) { uint8_t *ret; uint32_t num; @@ -74,15 +75,28 @@ const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) assert(max > 0 && max <= fifo->num); num = MIN(fifo->capacity - fifo->head, max); ret = &fifo->data[fifo->head]; - fifo->head += num; - fifo->head %= fifo->capacity; - fifo->num -= num; + + if (do_pop) { + fifo->head += num; + fifo->head %= fifo->capacity; + fifo->num -= num; + } if (numptr) { *numptr = num; } return ret; } +const uint8_t *fifo8_peek_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) +{ + return fifo8_peekpop_buf(fifo, max, numptr, false); +} + +const uint8_t *fifo8_pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *numptr) +{ + return fifo8_peekpop_buf(fifo, max, numptr, true); +} + void fifo8_reset(Fifo8 *fifo) { fifo->num = 0;
To be able to poke at FIFO content without popping it, introduce the fifo8_peek_buf() method by factoring common content from fifo8_pop_buf(). Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- include/qemu/fifo8.h | 26 ++++++++++++++++++++++++++ util/fifo8.c | 22 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-)