Fixes are available
October 2009 Update for XL C/C++ for Linux, V10.1
June 2011 Update for XL C/C++ for Linux, V10.1
XL C/C++ for Linux Fix Pack 8 (January 2014 Update) for 10.1
August 2010 Update for XL C/C++ for Linux, V10.1
January 2011 Update for XL C/C++ for Linux, V10.1
January 2012 Update for XL C/C++ for Linux, V10.1
July 2012 Update for XL C/C++ for Linux, V10.1
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
LI75153
Reported component name
XL C/C++ SLES10
Reported component ID
5724U8300
Reported release
A10
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt
Submitted date
2009-12-01
Closed date
2009-12-01
Last modified date
2009-12-01
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
XL C/C++ SLES10
Fixed component ID
5724U8300
Applicable component levels
RA10 PSN IZ57947
UP06/09/13
[{"Business Unit":{"code":"BU054","label":"Systems w\/TPS"},"Product":{"code":"SSJT9L","label":"XL C\/C++"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"A.1","Line of Business":{"code":"LOB08","label":"Cognitive Systems"}}]
Document Information
Modified date:
14 October 2021