Fixes are available
April 2010 XL C/C++ Enterprise Edition V8.0 for AIX PTF
June 2011 XL C Enterprise Edition V8.0 for AIX PTF
June 2011 XL C/C++ Enterprise Edition V8.0 for AIX PTF
October 2009 XL C Enterprise Edition V8.0 for AIX PTF
October 2009 XL C/C++ Enterprise Edition V8.0 for AIX PTF
April 2010 XL C Enterprise Edition V8.0 for AIX PTF
APAR status
Closed as program error.
Error description
The compiler generated incorrect code which resulted in an incorrect comparison of an old vaule for the fetch_and_swap function call. This leads to a segmentation fault at runtime. Compile line: xlC_r -c main2.cpp -brtl -bdynamic -bexpall -g -qidirfirst -qstaticinline -qlanglvl=extended -D__MATH__ -qchars=signed -qtempinc -D_AIO_AIX_SOURCE -q64 -qwarn64 -DACE_TEMPLATES_REQUIRE_SOURCE -qflag=w:w -qfuncsect Testcase: $cat main2.cpp $ more main2.cpp #include <builtins.h> #include <cassert> #include <iostream> #include "ace/Task.h" class Spin { public: Spin() : data_(0), acqCount(0), relCount(0) { } int acquire(); int release(); bool isLock() const; public: volatile int data_; int acqCount; int relCount; }; int Spin::acquire() { while (true) { for (int i = 40000; i > 0; --i) { if (0 == data_ && 0 == __fetch_and_swap(&data_, 1)) { return 0; } } ACE_OS::thr_yield(); } return 0; } int Spin::release() { if (1 == data_) { int result = __fetch_and_swap(&data_, 0); assert(result == 1); return 0; } else { assert(false); } return 0; } bool Spin::isLock() const { return (0 != static_cast<int const volatile&>(data_)); } class MyTask : public ACE_Task_Base { public: virtual int svc(); }; Spin s_; int MyTask::svc() { for (int i = 0 ; i < 100000; ++i) { s_.acquire(); for (int j = 0; j < 100; j++) { } assert(s_.isLock()); for (int j = 0; j < 100; j++) { } s_.release(); } return 0; } int main(int argc, char *argv[]) { MyTask task; task.activate(THR_NEW_LWP | THR_JOINABLE, 20); task.wait(); std::cout << "Spin::lock = " << s_.data_ << std::endl; return 0; };
Local fix
1. Change all the spin lock variables to volatile and 2. Change the structure of the 'if' statement into two 'if's ie: From: if (0 == data_ && 0 == __fetch_and_swap(&data_, 1)) { return 0; } To: if (0 == data_) { int tmp = __fetch_and_swap(&data_, 1); if (0 == tmp) { return 0; } }
Problem summary
USER AFFECTED: Users of __fetch_and_swap without optimization PROBLEM DESCRIPTION: Incorrect code generated at noopt
Problem conclusion
The opt0 register allocator looks backwards from a compare/branch sequence to see if there is a store it can use to fill the delay. fetch_and_swap is marked as a store but it kills a condition register which the code assumed could not happen.
Temporary fix
Comments
APAR Information
APAR number
IZ57947
Reported component name
XLC C++ AIX
Reported component ID
5724M1200
Reported release
800
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt
Submitted date
2009-08-11
Closed date
2009-10-01
Last modified date
2009-10-14
APAR is sysrouted FROM one or more of the following:
APAR is sysrouted TO one or more of the following:
Fix information
Fixed component name
XLC AIX
Fixed component ID
5724M1100
Applicable component levels
[{"Line of Business":{"code":"LOB08","label":"Cognitive Systems"},"Business Unit":{"code":"BU054","label":"Systems w\/TPS"},"Product":{"code":"SSJT9L","label":"XL C\/C++"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"8.0"}]
Document Information
Modified date:
04 October 2021