From owner-freebsd-current Thu Apr 10 16:08:17 1997 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.5/8.8.5) id QAA07142 for current-outgoing; Thu, 10 Apr 1997 16:08:17 -0700 (PDT) Received: from phaeton.artisoft.com (phaeton.Artisoft.COM [198.17.250.50]) by freefall.freebsd.org (8.8.5/8.8.5) with SMTP id QAA07135 for ; Thu, 10 Apr 1997 16:08:11 -0700 (PDT) Received: (from terry@localhost) by phaeton.artisoft.com (8.6.11/8.6.9) id PAA10021 for current@freebsd.org; Thu, 10 Apr 1997 15:48:44 -0700 From: Terry Lambert Message-Id: <199704102248.PAA10021@phaeton.artisoft.com> Subject: WHY? ...non-use of TAILQ macros... To: current@freebsd.org Date: Thu, 10 Apr 1997 15:48:44 -0700 (MST) X-Mailer: ELM [version 2.4 PL24] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-current@freebsd.org X-Loop: FreeBSD.org Precedence: bulk On the theory that the TAILQ_xxx macros were being avoided and the queue elemments themselves directly refernce for No Good Reason(tm), I just compiled the following: ----------------------------------------------------------------------------- #include struct node { int element; int filler; int what; }; struct node bob = { 1, 2, 3 }; main() { int j; j = bob.what; /* 111*/ printf( "j = %d\n", j); j = (&bob)->what; /* 222*/ printf( "j = %d\n", j); } ----------------------------------------------------------------------------- And got: ----------------------------------------------------------------------------- .file "try.c" gcc2_compiled.: ___gnu_compiled_c: .globl _bob .data .align 2 .type _bob,@object .size _bob,12 _bob: .long 1 .long 2 .long 3 .text LC0: .ascii "j = %d\12\0" .align 2 .globl _main .type _main,@function _main: pushl %ebp movl %esp,%ebp subl $4,%esp call ___main movl _bob+8,%eax ; 1 movl %eax,-4(%ebp) ; 1 movl -4(%ebp),%eax ; 1 pushl %eax ; 1 pushl $LC0 ; 1 call _printf ; 1 addl $8,%esp ; 1 movl _bob+8,%eax ; 2 movl %eax,-4(%ebp) ; 2 movl -4(%ebp),%eax ; 2 pushl %eax ; 2 pushl $LC0 ; 2 call _printf ; 2 addl $8,%esp ; 2 L5: leave ret Lfe1: .size _main,Lfe1-_main ----------------------------------------------------------------------------- ... in other words, the references: (x).y and (x)->y Don't somehow generate different code. I'm wondering why the following aren't written using the macros (macro versions are shown one line below): ----------------------------------------------------------------------------- kern_lockf.c: while (ltmp = overlap->lf_blkhd.tqh_first) { while (ltmp = TAILQ_FIRST(&overlap->lf_blkhd)) { kern_lockf.c: while (wakelock = listhead->lf_blkhd.tqh_first) { while (wakelock = TAILQ_FIRST(&listhead->lf_blkhd)) { kern_lockf.c: if (lock->lf_blkhd.tqh_first) if (!TAILQ_EMPTY(&lock->lf_blkhd)) kern_lockf.c: printf(" block 0x%x\n", lock->lf_blkhd.tqh_first); printf(" block 0x%x\n", TAILQ_FIRST(&lock->lf_blkhd)); kern_lockf.c: for (blk = lf->lf_blkhd.tqh_first; blk; for (blk = TAILQ_FIRST(&lf->lf_blkhd); blk; kern_lockf.c: if (blk->lf_blkhd.tqh_first) if (!TAILQ_EMPTY(&blk->lf_blkhd)) kern_synch.c: for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) { for (p = TAILQ_FIRST(qp); p != NULL; p = TAILQ_NEXT(p, p_procq)) { kern_synch.c: for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) { for (p = TAILQ_FIRST(qp); p != NULL; p = TAILQ_NEXT(p, p_procq)) { uipc_socket.c: if (so->so_comp.tqh_first == NULL) if (TAILQ_EMPTY(&so->so_comp)) uipc_socket.c: for (sp = so->so_incomp.tqh_first; sp != NULL; sp = sonext) { for (sp = TAILQ_FIRST(&so->so_incomp); sp != NULL; sp = sonext) { uipc_socket.c: for (sp = so->so_comp.tqh_first; sp != NULL; sp = sonext) { for (sp = TAILQ_FIRST(&so->so_comp); sp != NULL; sp = sonext) { uipc_syscalls.c: if ((head->so_state & SS_NBIO) && head->so_comp.tqh_first == NULL) { if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->so_comp)) { uipc_syscalls.c: while (head->so_comp.tqh_first == NULL && head->so_error == 0) { while (TAILQ_EMPTY(&head->so_comp) && head->so_error == 0) { uipc_syscalls.c: so = head->so_comp.tqh_first; so = TAILQ_FIRST(&head->so_comp); vfs_cache.c: ((ncp = nclruhead.tqh_first) == NULL || ((ncp = TAILQ_FIRST(&nclruhead)) == NULL || vfs_cache.c: } else if (ncp = nclruhead.tqh_first) { } else if (ncp = TAILQ_FIRST(&nclruhead)) { vfs_subr.c: vnode_free_list.tqh_first == NULL) { TAILQ_EMPTY(&vnode_free_list)) { vfs_subr.c: for (vp = vnode_free_list.tqh_first; for (vp = TAILQ_FIRST(&vnode_free_list); vfs_subr.c: vnode_free_list.tqh_first != vp) { TAILQ_FIRST(&vnode_free_list) != vp) { ----------------------------------------------------------------------------- It seems to me that queue structure contents should only ever be referenced or mainipulated in the context of queue structure reference macros... One would also think that there would be: #define TAILQ_ENUM(elm,head,field) \ for( elm = (head)->tqh_first; elm != NULL; elm = (elm)->field.tqe_next) In queue.h to change: kern_synch.c: for (p = qp->tqh_first; p != NULL; p = p->p_procq.tqe_next) { Into: TAILQ_ENUM(p, qp, p_procq) { Regards, Terry Lambert terry@lambert.org --- Any opinions in this posting are my own and not those of my present or previous employers.