IBM Support

LI75113: INCORRECT COMPARE BEFORE __FETCH_AND_SWAP

Subscribe

You can track all active APARs for this component.

 

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

    LI75113

  • Reported component name

    XL C/C++ RHEL52

  • Reported component ID

    5724U8310

  • 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:

    IZ57947

  • APAR is sysrouted TO one or more of the following:

Fix information

  • Fixed component name

    XL C/C++ RHEL52

  • Fixed component ID

    5724U8310

Applicable component levels

[{"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