aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/kfifo.h
diff options
context:
space:
mode:
authorStefani Seibold <stefani@seibold.net>2013-11-14 17:32:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-14 19:32:23 -0500
commit498d319bb512992ef0784c278fa03679f2f5649d (patch)
tree2793b41c3a98b858d24aa833ccc2bfb2f6d60974 /include/linux/kfifo.h
parenta019e48cfbfb358786326db3dbc1c565b8f14a56 (diff)
kfifo API type safety
This patch enhances the type safety for the kfifo API. It is now safe to put const data into a non const FIFO and the API will now generate a compiler warning when reading from the fifo where the destination address is pointing to a const variable. As a side effect the kfifo_put() does now expect the value of an element instead a pointer to the element. This was suggested Russell King. It make the handling of the kfifo_put easier since there is no need to create a helper variable for getting the address of a pointer or to pass integers of different sizes. IMHO the API break is okay, since there are currently only six users of kfifo_put(). The code is also cleaner by kicking out the "if (0)" expressions. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Stefani Seibold <stefani@seibold.net> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/kfifo.h')
-rw-r--r--include/linux/kfifo.h47
1 files changed, 14 insertions, 33 deletions
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 10308c6a3d1c..552d51efb429 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * A generic kernel FIFO implementation 2 * A generic kernel FIFO implementation
3 * 3 *
4 * Copyright (C) 2009/2010 Stefani Seibold <stefani@seibold.net> 4 * Copyright (C) 2013 Stefani Seibold <stefani@seibold.net>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -67,9 +67,10 @@ struct __kfifo {
67 union { \ 67 union { \
68 struct __kfifo kfifo; \ 68 struct __kfifo kfifo; \
69 datatype *type; \ 69 datatype *type; \
70 const datatype *const_type; \
70 char (*rectype)[recsize]; \ 71 char (*rectype)[recsize]; \
71 ptrtype *ptr; \ 72 ptrtype *ptr; \
72 const ptrtype *ptr_const; \ 73 ptrtype const *ptr_const; \
73 } 74 }
74 75
75#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ 76#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \
@@ -386,16 +387,12 @@ __kfifo_int_must_check_helper( \
386#define kfifo_put(fifo, val) \ 387#define kfifo_put(fifo, val) \
387({ \ 388({ \
388 typeof((fifo) + 1) __tmp = (fifo); \ 389 typeof((fifo) + 1) __tmp = (fifo); \
389 typeof((val) + 1) __val = (val); \ 390 typeof(*__tmp->const_type) __val = (val); \
390 unsigned int __ret; \ 391 unsigned int __ret; \
391 const size_t __recsize = sizeof(*__tmp->rectype); \ 392 size_t __recsize = sizeof(*__tmp->rectype); \
392 struct __kfifo *__kfifo = &__tmp->kfifo; \ 393 struct __kfifo *__kfifo = &__tmp->kfifo; \
393 if (0) { \
394 typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
395 __dummy = (typeof(__val))NULL; \
396 } \
397 if (__recsize) \ 394 if (__recsize) \
398 __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ 395 __ret = __kfifo_in_r(__kfifo, &__val, sizeof(__val), \
399 __recsize); \ 396 __recsize); \
400 else { \ 397 else { \
401 __ret = !kfifo_is_full(__tmp); \ 398 __ret = !kfifo_is_full(__tmp); \
@@ -404,7 +401,7 @@ __kfifo_int_must_check_helper( \
404 ((typeof(__tmp->type))__kfifo->data) : \ 401 ((typeof(__tmp->type))__kfifo->data) : \
405 (__tmp->buf) \ 402 (__tmp->buf) \
406 )[__kfifo->in & __tmp->kfifo.mask] = \ 403 )[__kfifo->in & __tmp->kfifo.mask] = \
407 *(typeof(__tmp->type))__val; \ 404 (typeof(*__tmp->type))__val; \
408 smp_wmb(); \ 405 smp_wmb(); \
409 __kfifo->in++; \ 406 __kfifo->in++; \
410 } \ 407 } \
@@ -415,7 +412,7 @@ __kfifo_int_must_check_helper( \
415/** 412/**
416 * kfifo_get - get data from the fifo 413 * kfifo_get - get data from the fifo
417 * @fifo: address of the fifo to be used 414 * @fifo: address of the fifo to be used
418 * @val: the var where to store the data to be added 415 * @val: address where to store the data
419 * 416 *
420 * This macro reads the data from the fifo. 417 * This macro reads the data from the fifo.
421 * It returns 0 if the fifo was empty. Otherwise it returns the number 418 * It returns 0 if the fifo was empty. Otherwise it returns the number
@@ -428,12 +425,10 @@ __kfifo_int_must_check_helper( \
428__kfifo_uint_must_check_helper( \ 425__kfifo_uint_must_check_helper( \
429({ \ 426({ \
430 typeof((fifo) + 1) __tmp = (fifo); \ 427 typeof((fifo) + 1) __tmp = (fifo); \
431 typeof((val) + 1) __val = (val); \ 428 typeof(__tmp->ptr) __val = (val); \
432 unsigned int __ret; \ 429 unsigned int __ret; \
433 const size_t __recsize = sizeof(*__tmp->rectype); \ 430 const size_t __recsize = sizeof(*__tmp->rectype); \
434 struct __kfifo *__kfifo = &__tmp->kfifo; \ 431 struct __kfifo *__kfifo = &__tmp->kfifo; \
435 if (0) \
436 __val = (typeof(__tmp->ptr))0; \
437 if (__recsize) \ 432 if (__recsize) \
438 __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ 433 __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \
439 __recsize); \ 434 __recsize); \
@@ -456,7 +451,7 @@ __kfifo_uint_must_check_helper( \
456/** 451/**
457 * kfifo_peek - get data from the fifo without removing 452 * kfifo_peek - get data from the fifo without removing
458 * @fifo: address of the fifo to be used 453 * @fifo: address of the fifo to be used
459 * @val: the var where to store the data to be added 454 * @val: address where to store the data
460 * 455 *
461 * This reads the data from the fifo without removing it from the fifo. 456 * This reads the data from the fifo without removing it from the fifo.
462 * It returns 0 if the fifo was empty. Otherwise it returns the number 457 * It returns 0 if the fifo was empty. Otherwise it returns the number
@@ -469,12 +464,10 @@ __kfifo_uint_must_check_helper( \
469__kfifo_uint_must_check_helper( \ 464__kfifo_uint_must_check_helper( \
470({ \ 465({ \
471 typeof((fifo) + 1) __tmp = (fifo); \ 466 typeof((fifo) + 1) __tmp = (fifo); \
472 typeof((val) + 1) __val = (val); \ 467 typeof(__tmp->ptr) __val = (val); \
473 unsigned int __ret; \ 468 unsigned int __ret; \
474 const size_t __recsize = sizeof(*__tmp->rectype); \ 469 const size_t __recsize = sizeof(*__tmp->rectype); \
475 struct __kfifo *__kfifo = &__tmp->kfifo; \ 470 struct __kfifo *__kfifo = &__tmp->kfifo; \
476 if (0) \
477 __val = (typeof(__tmp->ptr))NULL; \
478 if (__recsize) \ 471 if (__recsize) \
479 __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ 472 __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \
480 __recsize); \ 473 __recsize); \
@@ -508,14 +501,10 @@ __kfifo_uint_must_check_helper( \
508#define kfifo_in(fifo, buf, n) \ 501#define kfifo_in(fifo, buf, n) \
509({ \ 502({ \
510 typeof((fifo) + 1) __tmp = (fifo); \ 503 typeof((fifo) + 1) __tmp = (fifo); \
511 typeof((buf) + 1) __buf = (buf); \ 504 typeof(__tmp->ptr_const) __buf = (buf); \
512 unsigned long __n = (n); \ 505 unsigned long __n = (n); \
513 const size_t __recsize = sizeof(*__tmp->rectype); \ 506 const size_t __recsize = sizeof(*__tmp->rectype); \
514 struct __kfifo *__kfifo = &__tmp->kfifo; \ 507 struct __kfifo *__kfifo = &__tmp->kfifo; \
515 if (0) { \
516 typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \
517 __dummy = (typeof(__buf))NULL; \
518 } \
519 (__recsize) ?\ 508 (__recsize) ?\
520 __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ 509 __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \
521 __kfifo_in(__kfifo, __buf, __n); \ 510 __kfifo_in(__kfifo, __buf, __n); \
@@ -561,14 +550,10 @@ __kfifo_uint_must_check_helper( \
561__kfifo_uint_must_check_helper( \ 550__kfifo_uint_must_check_helper( \
562({ \ 551({ \
563 typeof((fifo) + 1) __tmp = (fifo); \ 552 typeof((fifo) + 1) __tmp = (fifo); \
564 typeof((buf) + 1) __buf = (buf); \ 553 typeof(__tmp->ptr) __buf = (buf); \
565 unsigned long __n = (n); \ 554 unsigned long __n = (n); \
566 const size_t __recsize = sizeof(*__tmp->rectype); \ 555 const size_t __recsize = sizeof(*__tmp->rectype); \
567 struct __kfifo *__kfifo = &__tmp->kfifo; \ 556 struct __kfifo *__kfifo = &__tmp->kfifo; \
568 if (0) { \
569 typeof(__tmp->ptr) __dummy = NULL; \
570 __buf = __dummy; \
571 } \
572 (__recsize) ?\ 557 (__recsize) ?\
573 __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ 558 __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \
574 __kfifo_out(__kfifo, __buf, __n); \ 559 __kfifo_out(__kfifo, __buf, __n); \
@@ -773,14 +758,10 @@ __kfifo_uint_must_check_helper( \
773__kfifo_uint_must_check_helper( \ 758__kfifo_uint_must_check_helper( \
774({ \ 759({ \
775 typeof((fifo) + 1) __tmp = (fifo); \ 760 typeof((fifo) + 1) __tmp = (fifo); \
776 typeof((buf) + 1) __buf = (buf); \ 761 typeof(__tmp->ptr) __buf = (buf); \
777 unsigned long __n = (n); \ 762 unsigned long __n = (n); \
778 const size_t __recsize = sizeof(*__tmp->rectype); \ 763 const size_t __recsize = sizeof(*__tmp->rectype); \
779 struct __kfifo *__kfifo = &__tmp->kfifo; \ 764 struct __kfifo *__kfifo = &__tmp->kfifo; \
780 if (0) { \
781 typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \
782 __buf = __dummy; \
783 } \
784 (__recsize) ? \ 765 (__recsize) ? \
785 __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ 766 __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \
786 __kfifo_out_peek(__kfifo, __buf, __n); \ 767 __kfifo_out_peek(__kfifo, __buf, __n); \