* [PATCH 6/6] new kfifo API v0.3 - add record handling functions
@ 2009-08-14 11:45 Stefani Seibold
0 siblings, 0 replies; only message in thread
From: Stefani Seibold @ 2009-08-14 11:45 UTC (permalink / raw)
To: linux-kernel; +Cc: Andrew Morton, Arnd Bergmann, Andi Kleen, Amerigo Wang
This is patch 6/6 of the new kfifo API:
Add kfifo_in_rec() - puts some record data into the FIFO
Add kfifo_out_rec() - gets some record data from the FIFO
Add kfifo_from_user_rec() - puts some data from user space into the FIFO
Add kfifo_to_user_rec() - gets data from the FIFO and write it to user space
Add kfifo_peek_rec() - gets the size of the next FIFO record field
Add kfifo_skip_rec() - skip the next fifo out record
Do some code reorg
Three kinds of records will be supported:
a.) Fix size records.
The @recsize parameter is than 0 and exactly @len bytes will be copied
b.) Varible size records with 1 byte length field
The @recsize parameter is than 1 and a record of 0-255 bytes will be copied
b.) Varible size records with 2 byte length field
The @recsize parameter is than 2 and a record of 0-65535 bytes will be copied
include/linux/kfifo.h | 325 ++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/kfifo.c | 295 +++++++++++++++++++++++++++++++--------------
2 files changed, 527 insertions(+), 93 deletions(-)
Signed-off-by: Stefani Seibold <stefani@seibold.net>
diff -u -N -r linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h
--- linux-2.6.31-rc4-kfifo6/include/linux/kfifo.h 2009-08-14 11:52:27.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/include/linux/kfifo.h 2009-08-14 11:48:54.000000000 +0200
@@ -255,4 +255,329 @@
return off & (fifo->size - 1);
}
+/**
+ * __kfifo_peek_n internal helper function for determinate the length of
+ * the next record in the fifo
+ */
+static inline unsigned int __kfifo_peek_n(struct kfifo *fifo,
+ unsigned int recsize)
+{
+#define __KFIFO_GET(fifo, off, shift) \
+ ((fifo)->buffer[__kfifo_off((fifo), (fifo)->out+(off))] << (shift))
+
+ unsigned int l;
+
+ l = __KFIFO_GET(fifo, 0, 0);
+
+ if (--recsize)
+ l |= __KFIFO_GET(fifo, 1, 8);
+
+ return l;
+}
+
+/**
+ * __kfifo_poke_n internal helper function for storing the length of
+ * the next record into the fifo
+ */
+static inline void __kfifo_poke_n(struct kfifo *fifo,
+ unsigned int recsize, unsigned int n)
+{
+#define __KFIFO_PUT(fifo, off, val, shift) \
+ ( \
+ (fifo)->buffer[__kfifo_off((fifo), (fifo)->in+(off))] = \
+ (unsigned char)((val) >> (shift)) \
+ )
+
+ __KFIFO_PUT(fifo, 0, n, 0);
+
+ if (--recsize)
+ __KFIFO_PUT(fifo, 1, n, 8);
+}
+
+/**
+ * __kfifo_in_... internal functions for put date into the fifo
+ * do not call it directly, use kfifo_in_rec() instead
+ */
+extern unsigned int __kfifo_in_n(struct kfifo *fifo,
+ const unsigned char *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_in_generic(struct kfifo *fifo,
+ const unsigned char *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_in_rec(struct kfifo *fifo,
+ const unsigned char *from, unsigned int n, unsigned int recsize)
+{
+ unsigned int ret;
+
+ ret = __kfifo_in_n(fifo, from, n, recsize);
+
+ if (ret > n)
+ return ret;
+
+ if (likely(ret == 0)) {
+ if (recsize)
+ __kfifo_poke_n(fifo, recsize, n);
+ __kfifo_add_in(fifo, n + recsize);
+ }
+ return ret;
+}
+
+/**
+ * kfifo_in_rec - puts some record data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the FIFO and returns
+ * the number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_in_rec(struct kfifo *fifo,
+ unsigned char *from, unsigned int n, unsigned int recsize)
+{
+ if (!__builtin_constant_p(recsize))
+ return __kfifo_in_generic(fifo, from, n, recsize);
+
+ return __kfifo_in_rec(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_out_... internal functions for get date from the fifo
+ * do not call it directly, use kfifo_out_rec() instead
+ */
+extern unsigned int __kfifo_out_n(struct kfifo *fifo,
+ unsigned char *to, unsigned int n, unsigned int reclen,
+ unsigned int recsize);
+
+extern unsigned int __kfifo_out_generic(struct kfifo *fifo,
+ unsigned char *to, unsigned int n,
+ unsigned int recsize, unsigned int *total);
+
+static inline unsigned int __kfifo_out_rec(struct kfifo *fifo,
+ unsigned char *to, unsigned int n, unsigned int recsize,
+ unsigned int *total)
+{
+ unsigned int l;
+
+ if (!recsize) {
+ l = n;
+ if (total)
+ *total = l;
+ } else {
+ l = __kfifo_peek_n(fifo, recsize);
+ if (total)
+ *total = l;
+ if (n < l)
+ return l;
+ }
+
+ return __kfifo_out_n(fifo, to, n, l, recsize);
+}
+
+/**
+ * kfifo_out_rec - gets some record data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to @to and returns the
+ * number of bytes which cannot be copied.
+ * A returned value greater than the @n value means that the record doesn't
+ * fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_out_rec(struct kfifo *fifo,
+ unsigned char *to, unsigned int n, unsigned int recsize,
+ unsigned int *total)
+
+{
+ if (!__builtin_constant_p(recsize))
+ return __kfifo_out_generic(fifo, to, n, recsize, total);
+
+ return __kfifo_out_rec(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_from_user_... internal functions for transfer from user space into
+ * the fifo. do not call it directly, use kfifo_from_user_rec() instead
+ */
+extern unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+ const void __user *from, unsigned int n, unsigned int recsize);
+
+extern unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+ const void __user *from, unsigned int n, unsigned int recsize);
+
+static inline unsigned int __kfifo_from_user_rec(struct kfifo *fifo,
+ const void __user *from, unsigned int n, unsigned int recsize)
+{
+ unsigned int ret;
+
+ ret = __kfifo_from_user_n(fifo, from, n, recsize);
+
+ if (ret > n)
+ return ret;
+
+ if (likely(ret == 0)) {
+ if (recsize)
+ __kfifo_poke_n(fifo, recsize, n);
+ __kfifo_add_in(fifo, n + recsize);
+ }
+ return ret;
+}
+
+/**
+ * kfifo_from_user_rec - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @n: the length of the data to be added.
+ * @recsize: size of record field
+ *
+ * This function copies @n bytes from the @from into the
+ * FIFO and returns the number of bytes which cannot be copied.
+ *
+ * If the returned value is equal or less the @n value, the copy_from_user()
+ * functions has failed. Otherwise the record doesn't fit into the buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_from_user_rec(struct kfifo *fifo,
+ const void __user *from, unsigned int n, unsigned int recsize)
+{
+ if (__builtin_constant_p(recsize))
+ return __kfifo_from_user_rec(fifo, from, n, recsize);
+ return __kfifo_from_user_generic(fifo, from, n, recsize);
+}
+
+/**
+ * __kfifo_to_user_... internal functions for transfer fifo data into user space
+ * do not call it directly, use kfifo_to_user_rec() instead
+ */
+extern unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+ void __user *to, unsigned int n, unsigned int reclen,
+ unsigned int recsize);
+
+extern unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+ void __user *to, unsigned int n, unsigned int recsize,
+ unsigned int *total);
+
+static inline unsigned int __kfifo_to_user_rec(struct kfifo *fifo,
+ void __user *to, unsigned int n,
+ unsigned int recsize, unsigned int *total)
+{
+ unsigned int l;
+
+ if (!recsize) {
+ l = n;
+ if (total)
+ *total = l;
+ } else {
+ l = __kfifo_peek_n(fifo, recsize);
+ if (total)
+ *total = l;
+ if (n < l)
+ return l;
+ }
+
+ return __kfifo_to_user_n(fifo, to, n, l, recsize);
+}
+
+/**
+ * kfifo_to_user_rec - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @n: the size of the destination buffer.
+ * @recsize: size of record field
+ * @total: pointer where the total number of to copied bytes should stored
+ *
+ * This function copies at most @n bytes from the FIFO to the @to.
+ * In case of an error, the function returns the number of bytes which cannot
+ * be copied.
+ * If the returned value is equal or less the @n value, the copy_to_user()
+ * functions has failed. Otherwise the record doesn't fit into the @to buffer.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+static inline __must_check unsigned int kfifo_to_user_rec(struct kfifo *fifo,
+ void __user *to, unsigned int n, unsigned int recsize,
+ unsigned int *total)
+{
+ if (__builtin_constant_p(recsize))
+ return __kfifo_to_user_rec(fifo, to, n, recsize, total);
+ return __kfifo_to_user_generic(fifo, to, n, recsize, total);
+}
+
+/**
+ * __kfifo_peek_... internal functions for peek into the next fifo record
+ * do not call it directly, use kfifo_peek_rec() instead
+ */
+extern unsigned int __kfifo_peek_generic(struct kfifo *fifo,
+ unsigned int recsize);
+
+/**
+ * kfifo_peek_rec - gets the size of the next FIFO record data
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function returns the size of the next FIFO record in number of bytes
+ */
+static inline __must_check unsigned int kfifo_peek_rec(struct kfifo *fifo,
+ unsigned int recsize)
+{
+ if (__builtin_constant_p(recsize)) {
+ if (!recsize)
+ return kfifo_len(fifo);
+ return __kfifo_peek_n(fifo, recsize);
+ }
+ return __kfifo_peek_generic(fifo, recsize);
+}
+
+/**
+ * __kfifo_skip_... internal functions for skip the next fifo record
+ * do not call it directly, use kfifo_skip_rec() instead
+ */
+extern void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize);
+
+static inline void __kfifo_skip_rec(struct kfifo *fifo,
+ unsigned int recsize)
+{
+ unsigned int l;
+
+ if (recsize) {
+ l = __kfifo_peek_n(fifo, recsize);
+
+ if (l + recsize <= kfifo_len(fifo)) {
+ __kfifo_add_out(fifo, l + recsize);
+ return;
+ }
+ }
+ kfifo_reset_out(fifo);
+}
+
+/**
+ * kfifo_skip_rec - skip the next fifo out record
+ * @fifo: the fifo to be used.
+ * @recsize: size of record field
+ *
+ * This function skips the next FIFO record
+ */
+static inline void kfifo_skip_rec(struct kfifo *fifo,
+ unsigned int recsize)
+{
+ if (__builtin_constant_p(recsize))
+ __kfifo_skip_rec(fifo, recsize);
+ else
+ __kfifo_skip_generic(fifo, recsize);
+}
+
#endif
diff -u -N -r linux-2.6.31-rc4-kfifo6/kernel/kfifo.c linux-2.6.31-rc4-kfifo7/kernel/kfifo.c
--- linux-2.6.31-rc4-kfifo6/kernel/kfifo.c 2009-08-14 11:54:51.000000000 +0200
+++ linux-2.6.31-rc4-kfifo7/kernel/kfifo.c 2009-08-14 11:50:51.000000000 +0200
@@ -114,27 +114,11 @@
}
EXPORT_SYMBOL(kfifo_skip);
-/**
- * kfifo_in - puts some data into the FIFO
- * @fifo: the fifo to be used.
- * @from: the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from buffer into
- * the FIFO depending on the free space, and returns the number of
- * bytes copied.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_in(struct kfifo *fifo,
- const unsigned char *from, unsigned int len)
+static inline void __kfifo_in_data(struct kfifo *fifo,
+ const unsigned char *from, unsigned int len, unsigned int off)
{
- unsigned int off;
unsigned int l;
- len = min(len, fifo->size - fifo->in + fifo->out);
-
/*
* Ensure that we sample the fifo->out index -before- we
* start putting bytes into the kfifo.
@@ -142,7 +126,7 @@
smp_mb();
- off += __kfifo_off(fifo, fifo->in+off);
+ off += __kfifo_off(fifo, fifo->in + off);
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - off);
@@ -150,33 +134,13 @@
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, from + l, len - l);
-
- __kfifo_add_in(fifo, len);
-
- return len;
}
-EXPORT_SYMBOL(kfifo_in);
-/**
- * kfifo_out - gets some data from the FIFO
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_out(struct kfifo *fifo,
- unsigned char *to, unsigned int len)
+static inline void __kfifo_out_data(struct kfifo *fifo,
+ unsigned char *to, unsigned int len, unsigned int off)
{
- unsigned int off;
unsigned int l;
- len = min(len, fifo->in - fifo->out);
-
/*
* Ensure that we sample the fifo->in index -before- we
* start removing bytes from the kfifo.
@@ -184,7 +148,7 @@
smp_rmb();
- off += __kfifo_off(fifo, fifo->out);
+ off += __kfifo_off(fifo, fifo->out + off);
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - off);
@@ -192,34 +156,14 @@
/* then get the rest (if any) from the beginning of the buffer */
memcpy(to + l, fifo->buffer, len - l);
-
- __kfifo_add_out(fifo, len);
-
- return len;
}
-EXPORT_SYMBOL(kfifo_out);
-/**
- * kfifo_from_user - puts some data from user space into the FIFO
- * @fifo: the fifo to be used.
- * @from: pointer to the data to be added.
- * @len: the length of the data to be added.
- *
- * This function copies at most @len bytes from the @from into the
- * FIFO depending and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_from_user(struct kfifo *fifo,
- const void __user *from, unsigned int len)
+static inline unsigned int __kfifo_from_user_data(struct kfifo *fifo,
+ const void __user *from, unsigned int len, unsigned int off)
{
- unsigned int off;
unsigned int l;
int ret;
- len = min(len, fifo->size - fifo->in + fifo->out);
-
/*
* Ensure that we sample the fifo->out index -before- we
* start putting bytes into the kfifo.
@@ -227,49 +171,30 @@
smp_mb();
- off = __kfifo_off(fifo, fifo->in);
+ off = __kfifo_off(fifo, fifo->in + off);
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - off);
-
ret = copy_from_user(fifo->buffer + off, from, l);
if (unlikely(ret))
- return l - ret;
+ return ret + len - l;
/* then put the rest (if any) at the beginning of the buffer */
ret = copy_from_user(fifo->buffer, from + l, len - l);
if (unlikely(ret))
- return len - ret;
+ return ret;
- __kfifo_add_in(fifo, len);
-
- return len;
+ return 0;
}
-EXPORT_SYMBOL(kfifo_from_user);
-/**
- * kfifo_to_user - gets data from the FIFO and write it to user space
- * @fifo: the fifo to be used.
- * @to: where the data must be copied.
- * @len: the size of the destination buffer.
- *
- * This function copies at most @len bytes from the FIFO into the
- * @to buffer and returns the number of copied bytes.
- *
- * Note that with only one concurrent reader and one concurrent
- * writer, you don't need extra locking to use these functions.
- */
-unsigned int kfifo_to_user(struct kfifo *fifo,
- void __user *to, unsigned int len)
+static inline unsigned int __kfifo_to_user_data(struct kfifo *fifo,
+ void __user *to, unsigned int len, unsigned int off)
{
- unsigned int off;
unsigned int l;
int ret;
- len = min(len, fifo->in - fifo->out);
-
/*
* Ensure that we sample the fifo->in index -before- we
* start removing bytes from the kfifo.
@@ -277,25 +202,209 @@
smp_rmb();
- off = __kfifo_off(fifo, fifo->out);
+ off = __kfifo_off(fifo, fifo->out + off);
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - off);
-
ret = copy_to_user(to, fifo->buffer + off, l);
if (unlikely(ret))
- return l - ret;
+ return ret + len - l;
/* then get the rest (if any) from the beginning of the buffer */
ret = copy_to_user(to + l, fifo->buffer, len - l);
if (unlikely(ret))
- return len - ret;
+ return ret;
+
+ return 0;
+}
+
+unsigned int __kfifo_in_n(struct kfifo *fifo,
+ const unsigned char *from, unsigned int len, unsigned int recsize)
+{
+ if (kfifo_avail(fifo) < len + recsize)
+ return len + 1;
+
+ __kfifo_in_data(fifo, from, len, recsize);
+ return 0;
+}
+EXPORT_SYMBOL(__kfifo_in_n);
+
+/**
+ * kfifo_in - puts some data into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from buffer into
+ * the FIFO depending on the free space, and returns the number of
+ * bytes copied.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_in(struct kfifo *fifo, const unsigned char *from,
+ unsigned int len)
+{
+ len = min(kfifo_avail(fifo), len);
+ __kfifo_in_data(fifo, from, len, 0);
+ __kfifo_add_in(fifo, len);
+ return len;
+}
+EXPORT_SYMBOL(kfifo_in);
+
+unsigned int __kfifo_in_generic(struct kfifo *fifo,
+ const unsigned char *from, unsigned int len, unsigned int recsize)
+{
+ return __kfifo_in_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_in_generic);
+
+unsigned int __kfifo_out_n(struct kfifo *fifo,
+ unsigned char *to, unsigned int len, unsigned int reclen,
+ unsigned int recsize)
+{
+ if (kfifo_len(fifo) < reclen + recsize)
+ return len;
+
+ __kfifo_out_data(fifo, to, len, recsize);
+ __kfifo_add_out(fifo, reclen + recsize);
+ return 0;
+}
+EXPORT_SYMBOL(__kfifo_out_n);
+
+/**
+ * kfifo_out - gets some data from the FIFO
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_out(struct kfifo *fifo, unsigned char *to, unsigned int len)
+{
+ len = min(kfifo_len(fifo), len);
+
+ __kfifo_out_data(fifo, to, len, 0);
__kfifo_add_out(fifo, len);
return len;
}
+EXPORT_SYMBOL(kfifo_out);
+
+unsigned int __kfifo_out_generic(struct kfifo *fifo,
+ unsigned char *to, unsigned int len, unsigned int recsize,
+ unsigned int *total)
+{
+ return __kfifo_out_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_out_generic);
+
+unsigned int __kfifo_from_user_n(struct kfifo *fifo,
+ const void __user *from, unsigned int len, unsigned int recsize)
+{
+ if (kfifo_avail(fifo) < len + recsize)
+ return len + 1;
+
+ return __kfifo_from_user_data(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_n);
+
+/**
+ * kfifo_from_user - puts some data from user space into the FIFO
+ * @fifo: the fifo to be used.
+ * @from: pointer to the data to be added.
+ * @len: the length of the data to be added.
+ *
+ * This function copies at most @len bytes from the @from into the
+ * FIFO depending and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_from_user(struct kfifo *fifo,
+ const void __user *from, unsigned int len)
+{
+ len = min(kfifo_avail(fifo), len);
+ len -= __kfifo_from_user_data(fifo, from, len, 0);
+ __kfifo_add_in(fifo, len);
+ return len;
+}
+EXPORT_SYMBOL(kfifo_from_user);
+
+unsigned int __kfifo_from_user_generic(struct kfifo *fifo,
+ const void __user *from, unsigned int len, unsigned int recsize)
+{
+ return __kfifo_from_user_rec(fifo, from, len, recsize);
+}
+EXPORT_SYMBOL(__kfifo_from_user_generic);
+
+unsigned int __kfifo_to_user_n(struct kfifo *fifo,
+ void __user *to, unsigned int len, unsigned int reclen,
+ unsigned int recsize)
+{
+ unsigned int ret;
+
+ if (kfifo_len(fifo) < reclen + recsize)
+ return len;
+
+ ret = __kfifo_to_user_data(fifo, to, reclen, recsize);
+
+ if (likely(ret == 0))
+ __kfifo_add_out(fifo, reclen + recsize);
+
+ return ret;
+}
+EXPORT_SYMBOL(__kfifo_to_user_n);
+
+/**
+ * kfifo_to_user - gets data from the FIFO and write it to user space
+ * @fifo: the fifo to be used.
+ * @to: where the data must be copied.
+ * @len: the size of the destination buffer.
+ *
+ * This function copies at most @len bytes from the FIFO into the
+ * @to buffer and returns the number of copied bytes.
+ *
+ * Note that with only one concurrent reader and one concurrent
+ * writer, you don't need extra locking to use these functions.
+ */
+unsigned int kfifo_to_user(struct kfifo *fifo,
+ void __user *to, unsigned int len)
+{
+ len = min(kfifo_len(fifo), len);
+ len -= __kfifo_to_user_data(fifo, to, len, 0);
+ __kfifo_add_out(fifo, len);
+ return len;
+}
EXPORT_SYMBOL(kfifo_to_user);
+unsigned int __kfifo_to_user_generic(struct kfifo *fifo,
+ void __user *to, unsigned int len, unsigned int recsize,
+ unsigned int *total)
+{
+ return __kfifo_to_user_rec(fifo, to, len, recsize, total);
+}
+EXPORT_SYMBOL(__kfifo_to_user_generic);
+
+unsigned int __kfifo_peek_generic(struct kfifo *fifo, unsigned int recsize)
+{
+ if (recsize == 0)
+ return kfifo_avail(fifo);
+
+ return __kfifo_peek_n(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_peek_generic);
+
+void __kfifo_skip_generic(struct kfifo *fifo, unsigned int recsize)
+{
+ __kfifo_skip_rec(fifo, recsize);
+}
+EXPORT_SYMBOL(__kfifo_skip_generic);
+
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2009-08-14 11:45 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-14 11:45 [PATCH 6/6] new kfifo API v0.3 - add record handling functions Stefani Seibold
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.