From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46651) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bv0LW-0005Jg-D1 for qemu-devel@nongnu.org; Fri, 14 Oct 2016 07:08:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bv0LQ-0003El-4t for qemu-devel@nongnu.org; Fri, 14 Oct 2016 07:08:13 -0400 References: <1476394254-7987-1-git-send-email-duanj@linux.vnet.ibm.com> <1476394254-7987-3-git-send-email-duanj@linux.vnet.ibm.com> <20161014104447.GC2030@work-vm> From: Paolo Bonzini Message-ID: <897cd09c-dc83-202d-52af-8df381b967f2@redhat.com> Date: Fri, 14 Oct 2016 13:07:57 +0200 MIME-Version: 1.0 In-Reply-To: <20161014104447.GC2030@work-vm> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [QEMU PATCH v6 2/2] migration: migrate QTAILQ List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Dr. David Alan Gilbert" , Jianjun Duan Cc: qemu-devel@nongnu.org, qemu-ppc@nongnu.org, dmitry@daynix.com, peter.maydell@linaro.org, kraxel@redhat.com, mst@redhat.com, david@gibson.dropbear.id.au, veroniabahaa@gmail.com, quintela@redhat.com, amit.shah@redhat.com, mreitz@redhat.com, kwolf@redhat.com, rth@twiddle.net, aurelien@aurel32.net, leon.alrae@imgtec.com, blauwirbel@gmail.com, mark.cave-ayland@ilande.co.uk, mdroth@linux.vnet.ibm.com On 14/10/2016 12:44, Dr. David Alan Gilbert wrote: >> > +#define QTAILQ_RAW_INSERT_TAIL(head, elm, entry) do { \ >> > + *((void **) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET)) = NULL; \ >> > + *((void **) ((char *) (elm) + (entry) + QTAILQ_PREV_OFFSET)) = \ >> > + *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET)); \ >> > + **((void ***)((char *) (head) + QTAILQ_LAST_OFFSET)) = (elm); \ >> > + *((void **) ((char *) (head) + QTAILQ_LAST_OFFSET)) = \ >> > + (void *) ((char *) (elm) + (entry) + QTAILQ_NEXT_OFFSET); \ >> > +} while (/*CONSTCOND*/0) > I wonder if there's a simpler way to do this; I'm not sure this works, but something like: > > struct QTAILQDummy { > char dummy; > }; > > QTAILQ_HEAD(QTAILQRawHead, struct QTAILQDummy) > typedef QTAILQ_ENTRY(struct QTAILQDummy) QTAILQRawEntry; > > #define QTAILQ_RAW_FOREACH(elm, head, entry) \ > for ((elm) = ((struct QTAILQRawHead *)head)->tqh_first) \ > (elm); \ > (elm) = \ > (elm) = ((QTAILQRawEntry *)((char *) (elm) + (entry)))->tqh_next > > and then I think elm gets declared as a struct QTAILQDummy. > But it does avoid those FIRST_OFFSET/LAST_OFFSET/NEXT_OFFSET/PREV_OFFSET calculations. Another possibility is a macro like #define field_at_offset(base, offset, type) \ ((type) (((char *) (base)) + (offset))) so that you can do *field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET) = NULL; *field_at_offset(void ***, elm, (entry) + QTAILQ_PREV_OFFSET) = *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET); **field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = (elm); *field_at_offset(void ***, head, QTAILQ_LAST_OFFSET) = field_at_offset(void **, elm, (entry) + QTAILQ_NEXT_OFFSET); or something like that (note that I've always used the same type for next and last, by the way). Paolo