[RFC][PATCH 1/1] kfifo: add macros for direct buffer read access

From: Matthew Hollingworth
Date: Tue Aug 13 2013 - 01:52:51 EST


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 <mdholling@xxxxxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/