Add kfifo_out_prepare and kfifo_out_finish macros. These allow direct
access to the fifo buffer for reading.

These macros do not make sense for data-record fifos and would not
apply in that context.

Equivalent macros could be added for fifo direct write operations.

Signed-off-by: Matthew Hollingworth <mdholl...@gmail.com>
---
 include/linux/kfifo.h |   48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 10308c6..24f6024 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -787,6 +787,54 @@ __kfifo_uint_must_check_helper( \
 }) \
 )

+/**
+ * kfifo_out_prepare - setup a pointer for direct output buffer access
+ * @fifo: address of the fifo to be used
+ * @pbuf: address of buffer pointer to be initialized
+ *
+ * This macro sets the provided buffer pointer to the address of the
+ * current fifo output location.
+ * It returns the maximum number of contiguous elements which can be read
+ * out from this location. A zero means there is no data in the fifo.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these macros.
+ */
+#define kfifo_out_prepare(fifo, pbuf) \
+__kfifo_uint_must_check_helper( \
+({ \
+       typeof((fifo) + 1) __tmp = (fifo);  \
+       typeof((*pbuf) + 1) * __pbuf = (pbuf); \
+       struct __kfifo *__kfifo = &__tmp->kfifo; \
+       unsigned int size = __kfifo->mask + 1; \
+       unsigned int off = __kfifo->out & __kfifo->mask; \
+       *__pbuf = (__is_kfifo_ptr(__tmp) ? \
+               ((typeof(__tmp->type))__kfifo->data) : \
+               (__tmp->buf)) + off; \
+       min(size - off, __kfifo->in - __kfifo->out); \
+}) \
+)
+
+/**
+ * kfifo_out_finish - finish a direct output buffer access operation
+ * @fifo: address of the fifo to be used
+ * @len: number of elements which were read out
+ *
+ * This macro finishes a direct output buffer access operation. The out
+ * counter will be updated by the len parameter. No error checking will
+ * be done.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these macros.
+ */
+#define kfifo_out_finish(fifo, len) \
+(void)({ \
+       typeof((fifo) + 1) __tmp = (fifo);  \
+       struct __kfifo *__kfifo = &__tmp->kfifo; \
+       unsigned int __len = (len); \
+       __kfifo->out += __len; \
+})
+
 extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size,
        size_t esize, gfp_t gfp_mask);

--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to