From simon@comsys.ntu-kpi.kiev.ua  Fri Feb  1 11:43:51 2013
Return-Path: <simon@comsys.ntu-kpi.kiev.ua>
Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115])
	by hub.freebsd.org (Postfix) with ESMTP id 08C6C4DD
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  1 Feb 2013 11:43:51 +0000 (UTC)
	(envelope-from simon@comsys.ntu-kpi.kiev.ua)
Received: from comsys.kpi.ua (comsys.kpi.ua [77.47.192.42])
	by mx1.freebsd.org (Postfix) with ESMTP id 999CFEA8
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  1 Feb 2013 11:43:50 +0000 (UTC)
Received: from pm513-1.comsys.kpi.ua ([10.18.52.101] helo=pm513-1.comsys.ntu-kpi.kiev.ua)
	by comsys.kpi.ua with esmtpsa (TLSv1:AES256-SHA:256)
	(Exim 4.63)
	(envelope-from <simon@comsys.ntu-kpi.kiev.ua>)
	id 1U1F24-0000Yq-0L
	for FreeBSD-gnats-submit@freebsd.org; Fri, 01 Feb 2013 13:43:48 +0200
Received: by pm513-1.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1001)
	id 309701CC1E; Fri,  1 Feb 2013 13:43:46 +0200 (EET)
Message-Id: <20130201114346.GA35697@pm513-1.comsys.ntu-kpi.kiev.ua>
Date: Fri, 1 Feb 2013 13:43:46 +0200
From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: FreeBSD-gnats-submit@freebsd.org
Subject: Correct data types for fields of struct qm_trace{} from <sys/queue.h>

>Number:         175759
>Category:       kern
>Synopsis:       [headers] [patch] Correct data types for fields of struct qm_trace{} from <sys/queue.h>
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 01 11:50:00 UTC 2013
>Closed-Date:    Wed Jan 22 09:26:22 UTC 2014
>Last-Modified:  Wed Jan 22 09:26:22 UTC 2014
>Originator:     Andrey Simonenko
>Release:        FreeBSD 9.1-STABLE amd64
>Organization:
>Environment:
>Description:

If QUEUE_MACRO_DEBUG is defined and WARNS >= 4, then a program that
uses some macro definitions from <sys/queue.h> cannot be built because
of "warning: assignment discards qualifiers from pointer target type"
warnings.

1. File name fields should have "const char *" type.

2. Line number fields should have "long" or "unsigned long" type,
   considering C99 standard and its values for [U]INT_MAX, __LINE__
   and #line.

>How-To-Repeat:
>Fix:
--- queue.h.orig	2012-12-11 21:00:44.000000000 +0200
+++ queue.h	2013-01-31 13:37:13.000000000 +0200
@@ -105,10 +105,10 @@
 #ifdef QUEUE_MACRO_DEBUG
 /* Store the last 2 places the queue element or head was altered */
 struct qm_trace {
-	char * lastfile;
-	int lastline;
-	char * prevfile;
-	int prevline;
+	const char *lastfile;
+	unsigned long lastline;
+	const char *prevfile;
+	unsigned long prevline;
 };
 
 #define	TRACEBUF	struct qm_trace trace;

>Release-Note:
>Audit-Trail:

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Fri, 1 Feb 2013 17:04:27 +0400

 On Fri, Feb 01, 2013 at 01:43:46PM +0200, Andrey Simonenko wrote:
 A> If QUEUE_MACRO_DEBUG is defined and WARNS >= 4, then a program that
 A> uses some macro definitions from <sys/queue.h> cannot be built because
 A> of "warning: assignment discards qualifiers from pointer target type"
 A> warnings.
 
 Can you please provide a sample file? I can reproduce this with simple
 declaration of TAILQ_HEAD for example, neither with gcc nor clang.
 
 A> 1. File name fields should have "const char *" type.
 
 Paragraph 6.10.8 of standard says that __FILE__ is "a character string
 literal". It doesn't say that it can be referenced only by a pointer
 with const qualifier.
 
 However, the proposed change definitely makes sence.
 
 A> 2. Line number fields should have "long" or "unsigned long" type,
 A>    considering C99 standard and its values for [U]INT_MAX, __LINE__
 A>    and #line.
 
 Paragraph 6.10.8 of standard says that __LINE__ is "an integer constant".
 
 Paragraph 6.4.4.1 on integer constants says that "The type of an integer
 constant is the first of the corresponding list in which its value can
 be represented." The corresponding list starts with "int". According to
 paragraph 6.10.4 line number can't get bigger that 2147483647 (INT_MAX),
 and this value can be represented by int.
 
 Thus, I don't see where standard says that line number should be long.
 
 Correct me please, if I am wrong.
 
 -- 
 Totus tuus, Glebius.

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: Gleb Smirnoff <glebius@FreeBSD.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Fri, 1 Feb 2013 15:49:07 +0200

 On Fri, Feb 01, 2013 at 05:04:27PM +0400, Gleb Smirnoff wrote:
 > On Fri, Feb 01, 2013 at 01:43:46PM +0200, Andrey Simonenko wrote:
 > A> If QUEUE_MACRO_DEBUG is defined and WARNS >= 4, then a program that
 > A> uses some macro definitions from <sys/queue.h> cannot be built because
 > A> of "warning: assignment discards qualifiers from pointer target type"
 > A> warnings.
 > 
 > Can you please provide a sample file? I can reproduce this with simple
 > declaration of TAILQ_HEAD for example, neither with gcc nor clang.
 
 Tested on 9.1-STABLE with gcc (from the base system) and clang (from ports).
 
 queue.c:
 -------------------------------------------------------------------------
 #include <sys/queue.h>
 #include <stdlib.h>
 
 struct foo {
 	int x;
 };
 
 TAILQ_HEAD(foo_tailq, foo);
 
 int
 main(void)
 {
 	struct foo_tailq foo_tailq;
 
 	TAILQ_INIT(&foo_tailq);
 	return (0);
 }
 -------------------------------------------------------------------------
 
 Makefile:
 -------------------------------------------------------------------------
 PROG=queue
 
 DEBUG_FLAGS=-DQUEUE_MACRO_DEBUG
 
 WARNS=4
 
 NO_MAN=
 
 .include <bsd.prog.mk>
 -------------------------------------------------------------------------
 
 > 
 > A> 1. File name fields should have "const char *" type.
 > 
 > Paragraph 6.10.8 of standard says that __FILE__ is "a character string
 > literal". It doesn't say that it can be referenced only by a pointer
 > with const qualifier.
 > 
 > However, the proposed change definitely makes sence.
 
 Yes, but values these pointers are pointed to are not expected
 to be modified and pointing (char *) to __FILE__ will generate above
 given warning message.
 
 > 
 > A> 2. Line number fields should have "long" or "unsigned long" type,
 > A>    considering C99 standard and its values for [U]INT_MAX, __LINE__
 > A>    and #line.
 > 
 > Paragraph 6.10.8 of standard says that __LINE__ is "an integer constant".
 > 
 > Paragraph 6.4.4.1 on integer constants says that "The type of an integer
 > constant is the first of the corresponding list in which its value can
 > be represented." The corresponding list starts with "int". According to
 > paragraph 6.10.4 line number can't get bigger that 2147483647 (INT_MAX),
 > and this value can be represented by int.
 > 
 > Thus, I don't see where standard says that line number should be long.
 
 5.2.4.2.1 says "Their implementation-defined values shall be equal or
 greater in magnitude (absolute  value) to those shown, with the same sign."
 
          -- maximum value for an object of type int
             INT_MAX                     +32767 // 2^15-1
          -- maximum value for an object of type unsigned int
             UINT_MAX                     65535 // 2^16-1
          -- maximum value for an object of type long int
             LONG_MAX               +2147483647 // 2^31-1
          -- maximum value for an object of type unsigned long int
             ULONG_MAX               4294967295 // 2^32-1
 
 According to this information the closest integer data type to the maximum
 value of a line number given in #line is "long" or "unsigned long".
 
 Even if we assume that INT_MAX is bigger that 2^31-1 then specifying
 "unsigned long" in that structure (without changing the order of its fields)
 will not change its size on i386 and amd64.
 
 Also I think there is sense to give initial values for TRACEBUF in
 TAILQ_HEAD_INITIALIZER, since gcc and clang generate warnings for WARNS>=3.

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: Gleb Smirnoff <glebius@FreeBSD.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Fri, 1 Feb 2013 16:03:15 +0200

 On Fri, Feb 01, 2013 at 03:49:07PM +0200, Andrey Simonenko wrote:
 > 
 > Even if we assume that INT_MAX is bigger that 2^31-1 then specifying
 > "unsigned long" in that structure (without changing the order of its fields)
 > will not change its size on i386 and amd64.
 
 Typos correction:
 
 Even if we assume that INT_MAX is equal to 2^31-1 then specifying
 "unsigned long" in that structure (without changing the order of its fields)
 will not change its size on i386 and amd64.

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: Gleb Smirnoff <glebius@FreeBSD.org>
Cc: FreeBSD-gnats-submit@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_ */

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Mon, 4 Feb 2013 18:05:54 +0400

   Andrey,
 
 On Fri, Feb 01, 2013 at 03:49:07PM +0200, Andrey Simonenko wrote:
 A> > A> 1. File name fields should have "const char *" type.
 A> > 
 A> > Paragraph 6.10.8 of standard says that __FILE__ is "a character string
 A> > literal". It doesn't say that it can be referenced only by a pointer
 A> > with const qualifier.
 A> > 
 A> > However, the proposed change definitely makes sence.
 A> 
 A> Yes, but values these pointers are pointed to are not expected
 A> to be modified and pointing (char *) to __FILE__ will generate above
 A> given warning message.
 
 Thanks for sample code. 
 
 A> > A> 2. Line number fields should have "long" or "unsigned long" type,
 A> > A>    considering C99 standard and its values for [U]INT_MAX, __LINE__
 A> > A>    and #line.
 A> > 
 A> > Paragraph 6.10.8 of standard says that __LINE__ is "an integer constant".
 A> > 
 A> > Paragraph 6.4.4.1 on integer constants says that "The type of an integer
 A> > constant is the first of the corresponding list in which its value can
 A> > be represented." The corresponding list starts with "int". According to
 A> > paragraph 6.10.4 line number can't get bigger that 2147483647 (INT_MAX),
 A> > and this value can be represented by int.
 A> > 
 A> > Thus, I don't see where standard says that line number should be long.
 A> 
 A> 5.2.4.2.1 says "Their implementation-defined values shall be equal or
 A> greater in magnitude (absolute  value) to those shown, with the same sign."
 A> 
 A>          -- maximum value for an object of type int
 A>             INT_MAX                     +32767 // 2^15-1
 A>          -- maximum value for an object of type unsigned int
 A>             UINT_MAX                     65535 // 2^16-1
 A>          -- maximum value for an object of type long int
 A>             LONG_MAX               +2147483647 // 2^31-1
 A>          -- maximum value for an object of type unsigned long int
 A>             ULONG_MAX               4294967295 // 2^32-1
 A> 
 A> According to this information the closest integer data type to the maximum
 A> value of a line number given in #line is "long" or "unsigned long".
 A> 
 A> Even if we assume that INT_MAX is bigger that 2^31-1 then specifying
 A> "unsigned long" in that structure (without changing the order of its fields)
 A> will not change its size on i386 and amd64.
 
 Yes, my error was that I looked into INT_MAX on my machine, not in standard.
 Thanks again.
 
 -- 
 Totus tuus, Glebius.

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Mon, 4 Feb 2013 18:14:07 +0400

 --tEFtbjk+mNEviIIX
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
   Andrey,
 
   any additional comments for the attached patch. Is it ok from your
 viewpoint?
 
 -- 
 Totus tuus, Glebius.
 
 --tEFtbjk+mNEviIIX
 Content-Type: text/x-diff; charset=koi8-r
 Content-Disposition: attachment; filename="queue.h.diff"
 
 Index: queue.h
 ===================================================================
 --- queue.h	(revision 245741)
 +++ queue.h	(working copy)
 @@ -105,13 +105,14 @@
  #ifdef QUEUE_MACRO_DEBUG
  /* Store the last 2 places the queue element or head was altered */
  struct qm_trace {
 -	char * lastfile;
 -	int lastline;
 -	char * prevfile;
 -	int prevline;
 +	const char * lastfile;
 +	unsigned long lastline;
 +	const char * prevfile;
 +	unsigned long prevline;
  };
  
  #define	TRACEBUF	struct qm_trace trace;
 +#define	TRACEBUF_INITIALIZER	{ __FILE__, __LINE__, NULL, 0 } ,
  #define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
  #define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
  
 @@ -134,6 +135,7 @@
  #define	QMD_TRACE_HEAD(head)
  #define	QMD_SAVELINK(name, link)
  #define	TRACEBUF
 +#define	TRACEBUF_INITIALIZER
  #define	TRASHIT(x)
  #endif	/* QUEUE_MACRO_DEBUG */
  
 @@ -461,7 +463,7 @@
  }
  
  #define	TAILQ_HEAD_INITIALIZER(head)					\
 -	{ NULL, &(head).tqh_first }
 +	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
  
  #define	TAILQ_ENTRY(type)						\
  struct {								\
 
 --tEFtbjk+mNEviIIX--

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: Gleb Smirnoff <glebius@FreeBSD.org>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Mon, 4 Feb 2013 17:12:57 +0200

 repost: forgot to send to the group.
 
 On Mon, Feb 04, 2013 at 06:14:07PM +0400, Gleb Smirnoff wrote:
 >   Andrey,
 > 
 >   any additional comments for the attached patch. Is it ok from your
 > viewpoint?
 > 
 > -- 
 > Totus tuus, Glebius.
 
 > Index: queue.h
 > ===================================================================
 > --- queue.h	(revision 245741)
 > +++ queue.h	(working copy)
 > @@ -105,13 +105,14 @@
 >  #ifdef QUEUE_MACRO_DEBUG
 >  /* Store the last 2 places the queue element or head was altered */
 >  struct qm_trace {
 > -	char * lastfile;
 > -	int lastline;
 > -	char * prevfile;
 > -	int prevline;
 > +	const char * lastfile;
 > +	unsigned long lastline;
 > +	const char * prevfile;
 > +	unsigned long prevline;
 >  };
 >  
 >  #define	TRACEBUF	struct qm_trace trace;
 > +#define	TRACEBUF_INITIALIZER	{ __FILE__, __LINE__, NULL, 0 } ,
 >  #define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
 >  #define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
 >  
 > @@ -134,6 +135,7 @@
 >  #define	QMD_TRACE_HEAD(head)
 >  #define	QMD_SAVELINK(name, link)
 >  #define	TRACEBUF
 > +#define	TRACEBUF_INITIALIZER
 >  #define	TRASHIT(x)
 >  #endif	/* QUEUE_MACRO_DEBUG */
 >  
 > @@ -461,7 +463,7 @@
 >  }
 >  
 >  #define	TAILQ_HEAD_INITIALIZER(head)					\
 > -	{ NULL, &(head).tqh_first }
 > +	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
 >  
 >  #define	TAILQ_ENTRY(type)						\
 >  struct {								\
 
 Looks correct.
 
 What do you think about this idea:
 
 http://lists.freebsd.org/pipermail/freebsd-bugs/2013-February/051665.html
 
 it has more generic approach for such kind of debugging.

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: Bruce Evans <brde@optusnet.com.au>
Cc: Gleb Smirnoff <glebius@FreeBSD.org>, FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Tue, 5 Feb 2013 13:35:50 +0200

 Bruce Evans wrote:
 
 > Unsigned long is unnecessarily large.  It wastes space on 64-bit
 > arches.  The change doesn't change the wastage, because space was
 > already wasted on 64-bit arches by mispacking the struct (with
 > unnamed padding after the ints).  It changes the API unnecessarily
 > by changing signed variables to unsigned.  Sign variables are
 > easier to use, and changing to unsigned ones risks sign extension
 > bugs.
 
 I did not change order of fields to not change API, that's why
 bigger data type is used without changing size of that structure
 due to padding (at least for current sizes of int and long).
 
 > According to your quote of the C standard, int32_t is enough.  (I
 > couldn't find anything directly about either the type or limit of
 > __LINE__ in the n869.txt draft of C99, but #line is limited to 2**31-1.
 > n1124.pdf says much the same, except it says that __LINE__ is an integer
 > constant where n869.txt says that __LINE__ is a decimal constant.  Both
 > of these seem to be wrong -- "decimal constants" include floating point
 > ones, and "integer constants" include octal and hex ones.)
 
 Using [u]int32_t is enough. but it will require to include <stdint.h>
 if QUEUE_MACRO_DEBUG is defined.  By the way including just <sys/queue.h>
 is not enough because it does not include <stddef.h> for NULL.
 
 > The change preserves many style bugs:
 > - no prefix in member names
 > - member names not sorted inversely on size.  This gives the space
 >    wastage.
 > - member names not indented
 > - space between '*' and member names.
 
 I'll repeat my idea how to improve QUEUE_MACRO_DEBUG, I did not
 post it in the first message, because it contains more changes:
 
 1. Allow a user to specify how many places to remember via QMD_TRACE_N.
    by default this value is 2 (as now).
 
 2. Initialize struct qm_trace{} in *_INIT() and *_INITIALIZER(),
    all initialized HEADs will have defined values in trace information.
 
 3. All trace information is saved in the info[QMD_TRACE_N] array, each
    element is a structure with file name and line number.  If QMD_TRACE_N
    is small, then this array can be split into two arrays to save space;
    if QMD_TRACE_N is big, then one array will work faster because of CPU
    cache lines.
 
 4. Lists' elements usually are not initialized (via bzero() for example),
    so first entry in the info[] array will have some random index for
    lists' elements.
 
 5. Using info[] array allows to specify arbitrary number of elements and
    does not require to move data from one element into another (as now).
    Position in array is (idx = (idx + 1) % QMD_TRACE_N) and during
    debugging at will be necessary to look at info[idx] to find the most
    recent change of HEAD or element.
 
 So, the main change is (I improved it, because of optimization):
 
 #define	QMD_TRACE(x) do {						\
 	unsigned int __idx;						\
 	__idx = ((x)->trace.idx + 1) % QMD_TRACE_N;			\
 	(x)->trace.idx = __idx;						\
 	(x)->trace.info[__idx].file = __FILE__;				\
 	(x)->trace.info[__idx].line = __LINE__;				\
 } while (0)
 
 It cam seem that this change makes QUEUE_MACRO_DEBUG more complex.
 Actually using info[] array with 2 elements (default value) should work
 faster than current implementation, since it does not require to copy
 data lastline -> prevline and lastfile -> prevfile, and that for(;;) in
 QMD_TRACE_INIT() for 1 element should be unrolled.
 
 Comparing generated code for QMD_TRACE under FreeBSD/amd64 9.1-STABLE
 by gcc from the base system and by clang-3.2 from Ports for the following
 file with -DQMD_TRACE_N=2^x (for non 2^x values the code will be more
 complex) and "-O2 -DQUEUE_MACRO_DEBUG":
 
 ------
 #include <stddef.h>
 #ifdef QUEUE_DEFAULT
 # include <sys/queue.h>
 #else
 # include "queue.h"
 #endif
 
 struct foo {
 	int x;
 	int y;
 	TAILQ_ENTRY(foo) link;
 };
 
 TAILQ_HEAD(foo_tailq, foo);
 
 void
 func(struct foo_tailq *foo_tailq, struct foo *foo)
 {
 	TAILQ_REMOVE(foo_tailq, foo, link);
 }
 ------
 
 1. GCC: 
 
    Now:    6 cmds: 4 mov to mem, 2 mov from mem.
    New: 9-10 cmds: 3 mov to mem, 1 mov from mem, 5 cmds with regs.
 
 2. clang:
 
    Now:    6 cmds: 4 mov to mem, 2 mov from mem.
    New:    7 cmds: 3 mov to mem, 1 mov from mem, 3 cmds with regs.
 
 The diff can be found here:
 
 http://lists.freebsd.org/pipermail/freebsd-bugs/2013-February/051665.html
 
 It contains many lines, because I renamed some debugging related macro
 names to improve style, added debugging to TAILQ_SWAP(), corrected
 TAILQ_INSERT_AFTER() and TAILQ_INSERT_BEFORE() (added parentheses for
 listelm).

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
Cc: Bruce Evans <brde@optusnet.com.au>, FreeBSD-gnats-submit@freebsd.org
Subject: Re: kern/175759: Correct data types for fields of struct qm_trace{}
 from <sys/queue.h>
Date: Tue, 5 Feb 2013 16:02:18 +0400

 On Tue, Feb 05, 2013 at 01:35:50PM +0200, Andrey Simonenko wrote:
 A> > Unsigned long is unnecessarily large.  It wastes space on 64-bit
 A> > arches.  The change doesn't change the wastage, because space was
 A> > already wasted on 64-bit arches by mispacking the struct (with
 A> > unnamed padding after the ints).  It changes the API unnecessarily
 A> > by changing signed variables to unsigned.  Sign variables are
 A> > easier to use, and changing to unsigned ones risks sign extension
 A> > bugs.
 A> 
 A> I did not change order of fields to not change API, that's why
 A> bigger data type is used without changing size of that structure
 A> due to padding (at least for current sizes of int and long).
 
 We don't claim to be ABI stable for binaries that contain additional
 debugging information. They don't go into releases, and they alredy
 are incompatible with non-debugging binaries.
 
 So this isn't a problem.
 
 
 -- 
 Totus tuus, Glebius.
State-Changed-From-To: open->patched 
State-Changed-By: glebius 
State-Changed-When: Wed Feb 6 07:27:36 UTC 2013 
State-Changed-Why:  
Committed, thanks. 


Responsible-Changed-From-To: freebsd-bugs->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Wed Feb 6 07:27:36 UTC 2013 
Responsible-Changed-Why:  
Committed, thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=175759 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/175759: commit references a PR
Date: Wed,  6 Feb 2013 07:27:33 +0000 (UTC)

 Author: glebius
 Date: Wed Feb  6 07:27:25 2013
 New Revision: 246387
 URL: http://svnweb.freebsd.org/changeset/base/246387
 
 Log:
   Fixes to QUEUE_MACRO_DEBUG support:
    - Add const quilifiers to fields that store value of __FILE__.
    - Use long type for fields that store value of __LINE__.
    - Sort and style(9) debugging fields.
    - Add initializer for debugging fields into TAILQ_INITIALIZER macro.
   
   PR:		175759
   Submitted by:	Andrey Simonenko <simon comsys.ntu-kpi.kiev.ua>
   Reviewed by:	bde
 
 Modified:
   head/sys/sys/queue.h
 
 Modified: head/sys/sys/queue.h
 ==============================================================================
 --- head/sys/sys/queue.h	Wed Feb  6 07:20:09 2013	(r246386)
 +++ head/sys/sys/queue.h	Wed Feb  6 07:27:25 2013	(r246387)
 @@ -105,13 +105,14 @@
  #ifdef QUEUE_MACRO_DEBUG
  /* Store the last 2 places the queue element or head was altered */
  struct qm_trace {
 -	char * lastfile;
 -	int lastline;
 -	char * prevfile;
 -	int prevline;
 +	unsigned long	 lastline;
 +	unsigned long	 prevline;
 +	const char	*lastfile;
 +	const char	*prevfile;
  };
  
  #define	TRACEBUF	struct qm_trace trace;
 +#define	TRACEBUF_INITIALIZER	{ __FILE__, __LINE__, NULL, 0 } ,
  #define	TRASHIT(x)	do {(x) = (void *)-1;} while (0)
  #define	QMD_SAVELINK(name, link)	void **name = (void *)&(link)
  
 @@ -134,6 +135,7 @@ struct qm_trace {
  #define	QMD_TRACE_HEAD(head)
  #define	QMD_SAVELINK(name, link)
  #define	TRACEBUF
 +#define	TRACEBUF_INITIALIZER
  #define	TRASHIT(x)
  #endif	/* QUEUE_MACRO_DEBUG */
  
 @@ -461,7 +463,7 @@ struct name {								\
  }
  
  #define	TAILQ_HEAD_INITIALIZER(head)					\
 -	{ NULL, &(head).tqh_first }
 +	{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
  
  #define	TAILQ_ENTRY(type)						\
  struct {								\
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: glebius 
State-Changed-When: Wed Jan 22 09:25:57 UTC 2014 
State-Changed-Why:  
Available in 10.0-RELEASE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=175759 
>Unformatted:
