public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
From: kum <a.kumaresh@gmail.com>
To: PRC <panruochen@gmail.com>
Cc: gcc-help <gcc-help@gcc.gnu.org>
Subject: Re: confused at code generation for a empty loop
Date: Fri, 30 Nov 2007 10:13:00 -0000	[thread overview]
Message-ID: <302c6e640711300115u3e6f0k9b839cbc209b63c3@mail.gmail.com> (raw)
In-Reply-To: <200711301445245306580@gmail.com>

while you use
static int flag = 0;
gcc is free to read the flag only once (optimisation) in any loop. To
inform this to the compiler you have to make use of volatile type
modifier. This will force the compiler to load the flag every time it
tests it.

By the way using some synch object (like semaphore) you can do the
same job better.

-kum

On Nov 30, 2007 12:15 PM, PRC <panruochen@gmail.com> wrote:
> Here is my code:
> =================================================================================
> #include <pthread.h>
> #include <stdio.h>
> #define NUM_THREADS 1
> static int flag = 0;
> void *thread(void *threadid)
> {
>     int ret = rand();
>     printf("thread return %d!\n", ret);
>     sleep(10);
>     flag = 1;
>     return (void *)ret;
> }
>
> int main (int argc, char *argv[])
> {
>    pthread_t threads[NUM_THREADS];
>    int rc;
>    rc = pthread_create(&threads[0], NULL, thread, (void *)0);
>    if (rc){
>          printf("ERROR; return code from pthread_create() is %d\n", rc);
>          exit(-1);
>    }
>    while( flag == 0 ) ;
>    return 0;
> }
> =================================================================================
> gcc -O2 -g -lpthread a.c
> objdump -S a.out > a.S
>
>
> `cat a.S` shows:
> =================================================================================
>    if (rc){
>  80484d4:   85 c0                   test   %eax,%eax
>  80484d6:   75 15                   jne    80484ed <main+0x4d>
>  80484d8:   a1 68 97 04 08          mov    0x8049768,%eax
>  80484dd:   85 c0                   test   %eax,%eax
>  80484df:   90                      nop
>          printf("ERROR; return code from pthread_create() is %d\n", rc);
>          exit(-1);
>    }
>    while( flag == 0 ) ;
>  80484e0:   74 fe                   je     80484e0 <main+0x40>
> ================================================================================
> You can see the variable `flag` is read only once. If the value of `flag` is 0 at the first time,
> the program will trap into a dead loop and never exit. And gcc knows the value of `flag` could
> be modified in the routine `thread`.
>
>
> But if I modify the line "while( flag == 0 ) ;" to "while(flag == 0) printf("waiting..\n");"
> and recompile the source code, the output assembly code becomes:
> =================================================================================
> while( flag == 0 ) printf("waiting..\n");
>  8048510:   c7 04 24 74 86 04 08    movl   $0x8048674,(%esp)
>  8048517:   e8 90 fe ff ff          call   80483ac <puts@plt>
>  804851c:   a1 b8 97 04 08          mov    0x80497b8,%eax
>  8048521:   85 c0                   test   %eax,%eax
>  8048523:   74 eb                   je     8048510 <main+0x40>
> =================================================================================
> `flag` is read in each loop. Then when the value of `flag` is modified, the loop terminates.
>
> I wonder why gcc generates code for a empty loop like that. Is it a bug or for optimization in some case?
>
> My gcc is:
> Using built-in specs.
> Target: i386-redhat-linux
> Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
> Thread model: posix
> gcc version 4.1.1 20060525 (Red Hat 4.1.1-1)
>
>

  reply	other threads:[~2007-11-30  9:15 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-30  7:16 PRC
2007-11-30 10:13 ` kum [this message]
2007-11-30 10:51 ` Marco Manfredini
2007-11-30 14:49 ` Tim Prince
2007-11-30 18:37   ` Marco Manfredini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=302c6e640711300115u3e6f0k9b839cbc209b63c3@mail.gmail.com \
    --to=a.kumaresh@gmail.com \
    --cc=gcc-help@gcc.gnu.org \
    --cc=panruochen@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).