diff options
author | Stefani Seibold <stefani@seibold.net> | 2013-11-14 17:32:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-14 19:32:23 -0500 |
commit | 498d319bb512992ef0784c278fa03679f2f5649d (patch) | |
tree | 2793b41c3a98b858d24aa833ccc2bfb2f6d60974 /include/linux/kfifo.h | |
parent | a019e48cfbfb358786326db3dbc1c565b8f14a56 (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.h | 47 |
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); \ |