Index: sys/callout.h =================================================================== RCS file: /cvsroot/src/sys/sys/callout.h,v retrieving revision 1.18 diff -u -r1.18 callout.h --- sys/callout.h 2003/07/20 16:25:58 1.18 +++ sys/callout.h 2003/09/25 08:45:24 @@ -68,10 +68,26 @@ #ifndef _SYS_CALLOUT_H_ #define _SYS_CALLOUT_H_ +/* + * The following funkyness is to appease gcc's strict aliasing. + */ +struct callout; struct callout_circq { - struct callout_circq *cq_next; /* next element */ - struct callout_circq *cq_prev; /* previous element */ + /* next element */ + union { + struct callout *elem; + struct callout_circq *list; + } cq_next; + /* previous element */ + union { + struct callout *elem; + struct callout_circq *list; + } cq_prev; }; +#define cq_next_e cq_next.elem +#define cq_prev_e cq_prev.elem +#define cq_next_l cq_next.list +#define cq_prev_l cq_prev.list struct callout { struct callout_circq c_list; /* linkage on queue */ @@ -86,7 +102,7 @@ #define CALLOUT_INVOKING 0x0008 /* callout function is being invoked */ #define CALLOUT_INITIALIZER_SETFUNC(func, arg) \ - { { NULL, NULL }, func, arg, 0, 0 } + { {{NULL}, {NULL}}, func, arg, 0, 0 } #define CALLOUT_INITIALIZER CALLOUT_INITIALIZER_SETFUNC(NULL, NULL) Index: kern/kern_timeout.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_timeout.c,v retrieving revision 1.10 diff -u -r1.10 kern_timeout.c --- kern/kern_timeout.c 2003/09/07 21:28:16 1.10 +++ kern/kern_timeout.c 2003/09/25 08:45:25 @@ -139,41 +139,42 @@ * Circular queue definitions. */ -#define CIRCQ_INIT(elem) \ +#define CIRCQ_INIT(list) \ do { \ - (elem)->cq_next = (elem); \ - (elem)->cq_prev = (elem); \ + (list)->cq_next_l = (list); \ + (list)->cq_prev_l = (list); \ } while (/*CONSTCOND*/0) #define CIRCQ_INSERT(elem, list) \ do { \ - (elem)->cq_prev = (list)->cq_prev; \ - (elem)->cq_next = (list); \ - (list)->cq_prev->cq_next = (elem); \ - (list)->cq_prev = (elem); \ + (elem)->cq_prev_e = (list)->cq_prev_e; \ + (elem)->cq_next_l = (list); \ + (list)->cq_prev_l->cq_next_l = (elem); \ + (list)->cq_prev_l = (elem); \ } while (/*CONSTCOND*/0) #define CIRCQ_APPEND(fst, snd) \ do { \ if (!CIRCQ_EMPTY(snd)) { \ - (fst)->cq_prev->cq_next = (snd)->cq_next; \ - (snd)->cq_next->cq_prev = (fst)->cq_prev; \ - (snd)->cq_prev->cq_next = (fst); \ - (fst)->cq_prev = (snd)->cq_prev; \ + (fst)->cq_prev_l->cq_next_l = (snd)->cq_next_l; \ + (snd)->cq_next_l->cq_prev_l = (fst)->cq_prev_l; \ + (snd)->cq_prev_l->cq_next_l = (fst); \ + (fst)->cq_prev_l = (snd)->cq_prev_l; \ CIRCQ_INIT(snd); \ } \ } while (/*CONSTCOND*/0) #define CIRCQ_REMOVE(elem) \ do { \ - (elem)->cq_next->cq_prev = (elem)->cq_prev; \ - (elem)->cq_prev->cq_next = (elem)->cq_next; \ + (elem)->cq_next_l->cq_prev_e = (elem)->cq_prev_e; \ + (elem)->cq_prev_l->cq_next_e = (elem)->cq_next_e; \ } while (/*CONSTCOND*/0) -#define CIRCQ_FIRST(elem) ((elem)->cq_next) +#define CIRCQ_FIRST(list) ((list)->cq_next_e) +#define CIRCQ_NEXT(elem) ((elem)->cq_next_e) +#define CIRCQ_LAST(elem,list) ((elem)->cq_next_l == (list)) +#define CIRCQ_EMPTY(list) ((list)->cq_next_l == (list)) -#define CIRCQ_EMPTY(elem) (CIRCQ_FIRST(elem) == (elem)) - /* * Some of the "math" in here is a bit tricky. * @@ -379,8 +380,7 @@ CALLOUT_LOCK(s); while (!CIRCQ_EMPTY(&timeout_todo)) { - - c = (struct callout *)CIRCQ_FIRST(&timeout_todo); /* XXX */ + c = CIRCQ_FIRST(&timeout_todo); CIRCQ_REMOVE(&c->c_list); /* If due run it, otherwise insert it into the right bucket. */ @@ -412,12 +412,13 @@ db_show_callout_bucket(struct callout_circq *bucket) { struct callout *c; - struct callout_circq *p; db_expr_t offset; char *name; - for (p = CIRCQ_FIRST(bucket); p != bucket; p = CIRCQ_FIRST(p)) { - c = (struct callout *)p; /* XXX */ + if (CIRCQ_EMPTY(bucket)) + return; + + for (c = CIRCQ_FIRST(bucket); /*nothing*/; c = CIRCQ_NEXT(&c->c_list)) { db_find_sym_and_offset((db_addr_t)(intptr_t)c->c_func, &name, &offset); name = name ? name : "?"; @@ -430,6 +431,9 @@ c->c_time - hardclock_ticks, (int)((bucket - timeout_wheel) / WHEELSIZE), (int)(bucket - timeout_wheel), (u_long) c->c_arg, name); + + if (CIRCQ_LAST(&c->c_list, bucket)) + break; } }