------- Comment #7 from jakub at gcc dot gnu dot org  2007-05-08 19:08 -------
This really is not specific to OpenMP, I believe the following is valid
threaded program:
#define _XOPEN_SOURCE 600
#include <pthread.h>
#include <stdlib.h>

int v;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
pthread_barrier_t b;

void
foo (int x, int y)
{
  int i;
  for (i = 0; i < 100; i++)
    {
      if (i > x)
        v = y;
    }
}

void *
tf (void *arg)
{
  pthread_barrier_wait (&b);
  if (arg == NULL)
    {
      pthread_mutex_lock (&m);
      if (v != 0)
        abort ();
      foo (50, 10);
      pthread_mutex_unlock (&m);
      pthread_barrier_wait (&b);
      foo (120, 30);
    }
  else
    {
      foo (100, 20);
      pthread_barrier_wait (&b);
      pthread_mutex_lock (&m);
      if (v != 10)
        abort ();
      foo (80, 40);
      if (v != 40)
        abort ();
      pthread_mutex_unlock (&m);
    }
  return NULL;
}

int
main (void)
{
  pthread_t th[2];
  pthread_barrier_init (&b, NULL, 2);
  if (pthread_create (&th[0], NULL, tf, NULL)
      || pthread_create (&th[1], NULL, tf, (void *) 1L))
    return 1;
  pthread_join (th[0], NULL);
  pthread_join (th[1], NULL);
  return 0;
}

and at -O0 works just fine and has no races in it, it is quite easy to show
the shared variable is only ever read or written inside of the critical
section.
But loop IM creates a race even when there is none in the code originally, if I
compile this with -O2 (both 4.1.x and trunk) it will abort after a couple of
attempts.

That's why I think we should have a generic option that disables optimizations
which are safe only in sequential programs (and -fopenmp would imply that
option).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31862

Reply via email to