Missing load barrier at the compiler side for C++ local static objects?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

When I compile the following C++ code
==========================================
extern int f(void);

struct A {
  int x;
  A() { this->x = f(); }
};

int g(void)
{
  static A a;
  return a.x;
}
==========================================
with "g++ -fdump-tree-gimple" (with gcc 4.5.0) on x86-64, the generated
GIMPLE code is like this:

==========================================
int g() ()
{
  char * _ZGVZ1gvE1a.0;
  char D.2126;
  bool retval.1;
  int D.2130;
  bool D.2123;
  int D.2138;
  static struct A a;

  _ZGVZ1gvE1a.0 = (char *) &_ZGVZ1gvE1a;
  D.2126 = *_ZGVZ1gvE1a.0;
  if (D.2126 == 0) goto <D.2127>; else goto <D.2128>;
  <D.2127>:
  [__cxa_acquire etc. snipped]
  <D.2128>:
  <D.2137>:
  D.2138 = a.x;
  return D.2138;
}
==========================================
If I'm understanding correctly, to be thread-safe, double-checked
locking in general requires a load barrier between checking the guard
variable and accessing the object.  On x86-64 no CPU-level load barrier
is necessary, but shouldn't one be needed at the compiler level?

Here the guard variable *_ZGBZ1gvE1a.0 is not marked volatile, so can't
the compiler later move the load of a.x before the load of the guard
variable (and redo it if we go the D.2127 path)?  This would clearly be
unsafe, as another thread can do the construction after the first load
of a.x and before loading the guard variable, so the current thread
would see object "a" constructed but will be returning a stale
uninitialized copy of a.x.

Please CC me as I'm not subscribed.

r6144




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux