The following reply was made to PR kern/175759; it has been noted by GNATS.
From: Andrey Simonenko <si...@comsys.ntu-kpi.kiev.ua> To: Gleb Smirnoff <gleb...@freebsd.org> Cc: freebsd-gnats-sub...@freebsd.org Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{} from <sys/queue.h> Date: Sat, 2 Feb 2013 12:53:04 +0200 What about the following change: 1. Allow a user to specify how many places to remember via QMD_TRACE_N. 2. Initialize struct qm_trace{} in *_INIT() and *_INITIALIZE(). 3. Lists' elements usually are not initialized, so first entry in the info[] array will have random index. 4. struct qm_trace{} is not anonymous, to allow it to be used in debugger scripts. I chose "unsigned long" for line number, but "int" or "unsigned int" also can be used. --- queue.h.orig 2012-11-19 14:38:37.000000000 +0200 +++ queue.h 2013-02-02 12:40:42.000000000 +0200 @@ -103,38 +103,54 @@ * */ #ifdef QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ + +#ifndef QMD_TRACE_N +# define QMD_TRACE_N 2 +#endif + +/* Store the last QMD_TRACE_N places the queue element or head was altered */ struct qm_trace { - char * lastfile; - int lastline; - char * prevfile; - int prevline; + unsigned int idx; + struct { + const char *file; + unsigned long line; + } info[QMD_TRACE_N]; }; -#define TRACEBUF struct qm_trace trace; -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#define QMD_TRACE_BUF struct qm_trace trace; +#define QMD_TRASHIT(x) do {(x) = (void *)-1;} while (0) #define QMD_SAVELINK(name, link) void **name = (void *)&(link) -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ +#define QMD_TRACE_INITIALIZER , { 0, { { __FILE__, __LINE__ } } } + +#define QMD_TRACE_INIT(x) do { \ + unsigned int __i; \ + (x)->trace.idx = 0; \ + (x)->trace.info[0].file = __FILE__; \ + (x)->trace.info[0].line = __LINE__; \ + for (__i = 1; __i < QMD_TRACE_N; ++__i) { \ + (x)->trace.info[__i].file = NULL; \ + (x)->trace.info[__i].line = 0; \ + } \ } while (0) -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ +#define QMD_TRACE(x) do { \ + (x)->trace.idx = ((x)->trace.idx + 1) % QMD_TRACE_N; \ + (x)->trace.info[(x)->trace.idx].file = __FILE__; \ + (x)->trace.info[(x)->trace.idx].line = __LINE__; \ } while (0) +#define QMD_TRACE_HEAD(head) QMD_TRACE(head) +#define QMD_TRACE_ELEM(elem) QMD_TRACE(elem) + #else +#define QMD_TRACE_BUF +#define QMD_TRACE_INITIALIZER +#define QMD_TRACE_INIT(x) #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) #define QMD_SAVELINK(name, link) -#define TRACEBUF -#define TRASHIT(x) +#define QMD_TRASHIT(x) #endif /* QUEUE_MACRO_DEBUG */ /* @@ -202,7 +218,7 @@ curelm = SLIST_NEXT(curelm, field); \ SLIST_REMOVE_AFTER(curelm, field); \ } \ - TRASHIT(*oldnext); \ + QMD_TRASHIT(*oldnext); \ } while (0) #define SLIST_REMOVE_AFTER(elm, field) do { \ @@ -303,7 +319,7 @@ curelm = STAILQ_NEXT(curelm, field); \ STAILQ_REMOVE_AFTER(head, curelm, field); \ } \ - TRASHIT(*oldnext); \ + QMD_TRASHIT(*oldnext); \ } while (0) #define STAILQ_REMOVE_AFTER(head, elm, field) do { \ @@ -436,8 +452,8 @@ LIST_NEXT((elm), field)->field.le_prev = \ (elm)->field.le_prev; \ *(elm)->field.le_prev = LIST_NEXT((elm), field); \ - TRASHIT(*oldnext); \ - TRASHIT(*oldprev); \ + QMD_TRASHIT(*oldnext); \ + QMD_TRASHIT(*oldprev); \ } while (0) #define LIST_SWAP(head1, head2, type, field) do { \ @@ -457,17 +473,17 @@ struct name { \ struct type *tqh_first; /* first element */ \ struct type **tqh_last; /* addr of last next element */ \ - TRACEBUF \ + QMD_TRACE_BUF \ } #define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } + { NULL, &(head).tqh_first QMD_TRACE_INITIALIZER } #define TAILQ_ENTRY(type) \ struct { \ struct type *tqe_next; /* next element */ \ struct type **tqe_prev; /* address of previous next element */ \ - TRACEBUF \ + QMD_TRACE_BUF \ } /* @@ -542,7 +558,7 @@ #define TAILQ_INIT(head) do { \ TAILQ_FIRST((head)) = NULL; \ (head)->tqh_last = &TAILQ_FIRST((head)); \ - QMD_TRACE_HEAD(head); \ + QMD_TRACE_INIT(head); \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ @@ -557,7 +573,7 @@ TAILQ_NEXT((listelm), field) = (elm); \ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ @@ -567,7 +583,7 @@ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ @@ -614,8 +630,8 @@ QMD_TRACE_HEAD(head); \ } \ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT(*oldnext); \ - TRASHIT(*oldprev); \ + QMD_TRASHIT(*oldnext); \ + QMD_TRASHIT(*oldprev); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) @@ -634,6 +650,8 @@ swap_first->field.tqe_prev = &(head2)->tqh_first; \ else \ (head2)->tqh_last = &(head2)->tqh_first; \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ } while (0) #endif /* !_SYS_QUEUE_H_ */ _______________________________________________ freebsd-bugs@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"