Index: sys/sys/queue.h =================================================================== RCS file: /cvsroot/src/sys/sys/queue.h,v retrieving revision 1.55 diff -p -r1.55 queue.h *** sys/sys/queue.h 17 Jul 2013 15:50:59 -0000 1.55 --- sys/sys/queue.h 16 Nov 2013 00:42:39 -0000 *************** struct { \ *** 602,619 **** /* * Circular queue definitions. */ #if defined(_KERNEL) && defined(QUEUEDEBUG) #define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ ! if ((head)->cqh_first != (void *)(head) && \ ! (head)->cqh_first->field.cqe_prev != (void *)(head)) \ panic("CIRCLEQ head forw %p %s:%d", (head), \ __FILE__, __LINE__); \ ! if ((head)->cqh_last != (void *)(head) && \ ! (head)->cqh_last->field.cqe_next != (void *)(head)) \ panic("CIRCLEQ head back %p %s:%d", (head), \ __FILE__, __LINE__); #define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ ! if ((elm)->field.cqe_next == (void *)(head)) { \ if ((head)->cqh_last != (elm)) \ panic("CIRCLEQ elm last %p %s:%d", (elm), \ __FILE__, __LINE__); \ --- 602,638 ---- /* * Circular queue definitions. */ + + /* + * We use this ugly hack to work around the fact that the CIRCLEQ + * macros violate the C aliasing rules by comparing 'struct name *' + * and 'struct type *' (see CIRCLEQ_HEAD() below). Modern compilers + * (such as GCC 4.8) declare this to be always false and this makes + * most of the macros below not function correctly. + * + * This hack is only to be used for comparisons and thus can be + * fully const. Do not use for assignment. + */ + static inline const void * __launder_type(const void *x); + static inline const void * + __launder_type(const void *x) + { + __asm volatile("" : "+r" (x)); + return x; + } + #if defined(_KERNEL) && defined(QUEUEDEBUG) #define QUEUEDEBUG_CIRCLEQ_HEAD(head, field) \ ! if ((head)->cqh_first != __launder_type(head) && \ ! (head)->cqh_first->field.cqe_prev != __launder_type(head)) \ panic("CIRCLEQ head forw %p %s:%d", (head), \ __FILE__, __LINE__); \ ! if ((head)->cqh_last != __launder_type(head) && \ ! (head)->cqh_last->field.cqe_next != __launder_type(head)) \ panic("CIRCLEQ head back %p %s:%d", (head), \ __FILE__, __LINE__); #define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field) \ ! if ((elm)->field.cqe_next == __launder_type(head)) { \ if ((head)->cqh_last != (elm)) \ panic("CIRCLEQ elm last %p %s:%d", (elm), \ __FILE__, __LINE__); \ *************** struct { \ *** 622,628 **** panic("CIRCLEQ elm forw %p %s:%d", (elm), \ __FILE__, __LINE__); \ } \ ! if ((elm)->field.cqe_prev == (void *)(head)) { \ if ((head)->cqh_first != (elm)) \ panic("CIRCLEQ elm first %p %s:%d", (elm), \ __FILE__, __LINE__); \ --- 641,647 ---- panic("CIRCLEQ elm forw %p %s:%d", (elm), \ __FILE__, __LINE__); \ } \ ! if ((elm)->field.cqe_prev == __launder_type(head)) { \ if ((head)->cqh_first != (elm)) \ panic("CIRCLEQ elm first %p %s:%d", (elm), \ __FILE__, __LINE__); \ *************** struct { \ *** 668,674 **** QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ (elm)->field.cqe_prev = (listelm); \ ! if ((listelm)->field.cqe_next == (void *)(head)) \ (head)->cqh_last = (elm); \ else \ (listelm)->field.cqe_next->field.cqe_prev = (elm); \ --- 687,693 ---- QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ (elm)->field.cqe_next = (listelm)->field.cqe_next; \ (elm)->field.cqe_prev = (listelm); \ ! if ((listelm)->field.cqe_next == __launder_type(head)) \ (head)->cqh_last = (elm); \ else \ (listelm)->field.cqe_next->field.cqe_prev = (elm); \ *************** struct { \ *** 680,686 **** QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ (elm)->field.cqe_next = (listelm); \ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ ! if ((listelm)->field.cqe_prev == (void *)(head)) \ (head)->cqh_first = (elm); \ else \ (listelm)->field.cqe_prev->field.cqe_next = (elm); \ --- 699,705 ---- QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field) \ (elm)->field.cqe_next = (listelm); \ (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ ! if ((listelm)->field.cqe_prev == __launder_type(head)) \ (head)->cqh_first = (elm); \ else \ (listelm)->field.cqe_prev->field.cqe_next = (elm); \ *************** struct { \ *** 690,697 **** #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ (elm)->field.cqe_next = (head)->cqh_first; \ ! (elm)->field.cqe_prev = (void *)(head); \ ! if ((head)->cqh_last == (void *)(head)) \ (head)->cqh_last = (elm); \ else \ (head)->cqh_first->field.cqe_prev = (elm); \ --- 709,716 ---- #define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ (elm)->field.cqe_next = (head)->cqh_first; \ ! (elm)->field.cqe_prev = (void *)head; \ ! if ((head)->cqh_last == __launder_type(head)) \ (head)->cqh_last = (elm); \ else \ (head)->cqh_first->field.cqe_prev = (elm); \ *************** struct { \ *** 700,708 **** #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ ! (elm)->field.cqe_next = (void *)(head); \ (elm)->field.cqe_prev = (head)->cqh_last; \ ! if ((head)->cqh_first == (void *)(head)) \ (head)->cqh_first = (elm); \ else \ (head)->cqh_last->field.cqe_next = (elm); \ --- 719,727 ---- #define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ ! (elm)->field.cqe_next = (void *)head; \ (elm)->field.cqe_prev = (head)->cqh_last; \ ! if ((head)->cqh_first == __launder_type(head)) \ (head)->cqh_first = (elm); \ else \ (head)->cqh_last->field.cqe_next = (elm); \ *************** struct { \ *** 712,723 **** #define CIRCLEQ_REMOVE(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \ ! if ((elm)->field.cqe_next == (void *)(head)) \ (head)->cqh_last = (elm)->field.cqe_prev; \ else \ (elm)->field.cqe_next->field.cqe_prev = \ (elm)->field.cqe_prev; \ ! if ((elm)->field.cqe_prev == (void *)(head)) \ (head)->cqh_first = (elm)->field.cqe_next; \ else \ (elm)->field.cqe_prev->field.cqe_next = \ --- 731,742 ---- #define CIRCLEQ_REMOVE(head, elm, field) do { \ QUEUEDEBUG_CIRCLEQ_HEAD((head), field) \ QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field) \ ! if ((elm)->field.cqe_next == __launder_type(head)) \ (head)->cqh_last = (elm)->field.cqe_prev; \ else \ (elm)->field.cqe_next->field.cqe_prev = \ (elm)->field.cqe_prev; \ ! if ((elm)->field.cqe_prev == __launder_type(head)) \ (head)->cqh_first = (elm)->field.cqe_next; \ else \ (elm)->field.cqe_prev->field.cqe_next = \ *************** struct { \ *** 727,755 **** #define CIRCLEQ_FOREACH(var, head, field) \ for ((var) = ((head)->cqh_first); \ ! (var) != (const void *)(head); \ (var) = ((var)->field.cqe_next)) #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ for ((var) = ((head)->cqh_last); \ ! (var) != (const void *)(head); \ (var) = ((var)->field.cqe_prev)) /* * Circular queue access methods. */ ! #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) #define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_LAST(head) ((head)->cqh_last) #define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) #define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) #define CIRCLEQ_LOOP_NEXT(head, elm, field) \ ! (((elm)->field.cqe_next == (void *)(head)) \ ? ((head)->cqh_first) \ : (elm->field.cqe_next)) #define CIRCLEQ_LOOP_PREV(head, elm, field) \ ! (((elm)->field.cqe_prev == (void *)(head)) \ ? ((head)->cqh_last) \ : (elm->field.cqe_prev)) --- 746,774 ---- #define CIRCLEQ_FOREACH(var, head, field) \ for ((var) = ((head)->cqh_first); \ ! (var) != (const void *)__launder_type(head); \ (var) = ((var)->field.cqe_next)) #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ for ((var) = ((head)->cqh_last); \ ! (var) != (const void *)__launder_type(head); \ (var) = ((var)->field.cqe_prev)) /* * Circular queue access methods. */ ! #define CIRCLEQ_EMPTY(head) ((head)->cqh_first == __launder_type(head)) #define CIRCLEQ_FIRST(head) ((head)->cqh_first) #define CIRCLEQ_LAST(head) ((head)->cqh_last) #define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) #define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) #define CIRCLEQ_LOOP_NEXT(head, elm, field) \ ! (((elm)->field.cqe_next == __launder_type(head)) \ ? ((head)->cqh_first) \ : (elm->field.cqe_next)) #define CIRCLEQ_LOOP_PREV(head, elm, field) \ ! (((elm)->field.cqe_prev == __launder_type(head)) \ ? ((head)->cqh_last) \ : (elm->field.cqe_prev))