Programming Languages on Power

Power Programming Languages

IBM Power, including the AIX, IBM i, and Linux operating systems, support a wide range of programming languages, catering to both traditional enterprise applications and modern development needs.


#Power


#Servers
#Programminglanguages
 View Only
  • 1.  Thread-safe initialization of local static variables

    Posted 01/24/19 11:25 AM

    Originally posted by: pwaehnert


    Is there an unobtrusive way to ensure that local static variables are thread-safely initialized?

    Example:

    void func() {
        static test t;
        // ...
    }
    

    If I call this function from two threads the constructor of test will be called only once from one of the threads and the other thread waits until the construction is finished and of coursed then uses the same object.

    GCC, clang and the current Visual C++ support this thread-safe initialization or have at least a flag to activate this behavior. This also due to the fact that C++11 requires this feature.


    #C/C++andFortran
    #Ask-Question-Here--General-Compiler-Q-and-A


  • 2.  Re: Thread-safe initialization of local static variables

    Posted 01/24/19 12:09 PM

    Originally posted by: xlbowler


    I'm not sure I understand the question.  You want to validate that the initialization is thread-safe because you don't trust the compiler?  I would inspect the assembly but I expect you already know that.  If the variable can't be constant initialized then you would expect to see a dependency on __cxa_guard_acquire, __cxa_guard_release and __cxa_guard_abort.  If it is constant initialized then you'd have to inspect deeper.  Short answer: I can't think of an easy way to script it.

     

    As you pointed out, -std=c++11 requires it.  It's on by default in every compiler that I'm aware of in C++11 mode.  There is -fno-threadsafe-statics to disable it.  You could specify -fthreadsafe-statics.


    #Ask-Question-Here--General-Compiler-Q-and-A
    #C/C++andFortran


  • 3.  Re: Thread-safe initialization of local static variables

    Posted 01/25/19 03:16 AM

    Originally posted by: pwaehnert


    Sorry for being too unspecific! We're currently using XL C++. As I had already observed, the resulting object code from the function func of my first post above does not contain any locking functionality to ensure a single construction of t.

    Example:

       100000af4:   3b e2 ff 10     addi    r31,r2,-240                    # Via the TOC, load the pointer to the memory location where the object t resides
    
       100000af8:   f8 61 00 b0     std     r3,176(r1)
    
       100000afc:   3b c2 01 40     addi    r30,r2,320                     # Via the TOC, load the pointer to the flag which indicates whether the object t
       100000b00:   e8 7e 00 02     lwa     r3,0(r30)                      # is already constructed
    
       100000b04:   2c 03 00 00     cmpwi   r3,0                           # Compare value of flag
       100000b08:   40 82 00 24     bne     100000b2c <.worker__FPv+0x4c>  # If flag wasn't zero, the object t is already constructed, then jump to 0x100000b2c
    
       100000b0c:   63 e3 00 00     ori     r3,r31,0                       # Otherwise construct the object t
       100000b10:   4b ff fc f1     bl      100000800 <.__ct__4TestFv>     #
    
       100000b14:   38 62 ff e8     addi    r3,r2,-24                      # Register the destructor of the object t as an exit handler
       100000b18:   4b ff fb a1     bl      1000006b8 <.atexit>            #
    
       100000b1c:   e8 41 00 28     ld      r2,40(r1)
    
       100000b20:   63 c4 00 00     ori     r4,r30,0                       # Set the flag to 1 in order to indicate a complete construction
       100000b24:   38 60 00 01     li      r3,1                           #
       100000b28:   90 64 00 00     stw     r3,0(r4)                       #
    
       100000b2c:   38 60 00 00     li      r3,0
    

    There's clearly a race condition: If the first thread is between 0x100000b0c and 0x100000b24, the flag isn't set yet but the construction is in progress. If in the meantime the other threads passes 0x100000b04 it won't wait until the first thread finishes the construction. Instead it will construct the object at the same memory location too.

    My question is: Is there a compiler flag for XL C++ such that the compiler generates thread-safe object initialization code for local static variables? I'm asking because other compilers usually offer something like this.

    Edit: Actually, xlclang++ uses those __cxa_guard_*() primitives and thus ensures a thread-safe initialization for local static variables. But I'm afraid, for now we're stuck with the XL C++ compiler...


    #Ask-Question-Here--General-Compiler-Q-and-A
    #C/C++andFortran


  • 4.  Re: Thread-safe initialization of local static variables

    Posted 01/25/19 09:41 AM

    Originally posted by: xlbowler


    As you've noted, xlclang++ has threadsafe-statics on by default (-fno-threadsafe-statics to explicitly disable it.)  Are you on AIX?  Unfortunately xlC for AIX does not ensure thread safety of static locals (nor does it offer full C++11 conformance.)  It's something we fixed alongside the move to incorporating Clang and libc++ on AIX. 


    #Ask-Question-Here--General-Compiler-Q-and-A
    #C/C++andFortran