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

            Bug ID: 60790
           Summary: libatomic convenience library selects IFUNC
                    implementation before obtaining cpu info.
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: go
          Assignee: ian at airs dot com
          Reporter: gary at intrepid dot com
                CC: nenad at intrepid dot com, PHHargrove at lbl dot gov,
                    rth at gcc dot gnu.org

Created attachment 32569
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32569&action=edit
libatomic cpuinfo patch

We ran into this issue recently while implementing atomic memory support for
GNU UPC.  We followed an approach similar to libgo -- we included
libatomic_convenience.a into libgupc.a.  This lets libgupc access GCC's
__atomic support without requiring the user to link explicitly with libatomic.

While debugging the UPC AMO library on a modern X86-64 platform, we noticed
that the locked implementation of compare-exchange-16 was being used in spite
of the fact of that the CPU supports the CMPX16 operation directly.

We determined that the IFUNC selector function was being called before the
constructor function in init.c had run.  Thus the libat_feat1_ecx variable was
zero.  Because the feature bit wasn't set, the selector function chose the CAS
function which requires explicit locks.  Interestingly,
__atomic_is_lock_free(16, NULL) returns true, as expected on this platform
because it is called after the init_cpuid() constructor is called.

One way to fix this issue is to re-work the logic that queries the CPU feature
register value, so that it explicitly initializes the value if it is zero.  The
assumption here is that __get_cpuid() will always return a non-zero value in
the ECX feature register.  A patch that implements this approach is attached.

Reply via email to