[LLVMdev] RFC: Atomics.h

Chris Lattner clattner at apple.com
Sun May 17 12:32:11 PDT 2009

On May 16, 2009, at 10:01 PM, Owen Anderson wrote:

> OK, I've enhanced Atomic.h by pulling in a bunch of implementations  
> from libatomic_ops, and others that I could figure out on my own.
> PATCHES IF IT DOESN'T WORK!  Similarly, if you think the  
> implementation could be improved for your platform, send me a patch.
> I know that Sparc doesn't work currently (no CAS implementation  
> yet), and I'm a little unsure about the ARM version, so it'd be  
> great if gurus for those platforms could look at them.

Owen, I would really rather that you didn't take this path.  Threading  
support in LLVM should always be optional: it should be possible to  
use LLVM on systems where we don't have support for threading  
operations.  Indeed, some systems don't support threads!

Given that, I think it makes sense to start  out the atomics  
operations very simple: just make them work for compilers that support  
GCC 4.2's atomics.  Since things will be changing quickly initially,  
this makes it easy to prototype and build things out, and this also  
avoids pulling in an external library with a (compatible but)  
different license.

In practice, I think a huge chunk of the community will be served when  
LLVM supports GCC 4.2 atomics + a windows implementation.  I don't see  
a reason to make things any more complex than that.  Since llvm-gcc  
supports atomics, someone doing development on a supported  
architecture can just build llvm-gcc single threaded, which provides  
them with a compiler that supports atomics on their platform.

> Our problems are actually deeper than that, because we need to  
> interact well with static constructors.  This means that we can't  
> use a mutex with a non-constant initializer, or else we can't depend  
> on it being properly initialized before the ManagedStatic is  
> accessed.  While this would be possible with pthread mutexes, I know  
> of no good way to do it for Windows CRITICAL_SECTION's.

Actually, global static constructors are evil and should be  
eliminated.  No static constructors should do anything non-trivial,  
and it is essential that ManagedStatic *not have a constructor*.  That  
is its entire design point.  However, ManagedStatic should  
theoretically pretty simple with double checked locking.  The  
observation is that llvm_shutdown() can only be called on one thread,  
but that lazily initialization of data structures can happen from  
multiple threads.  This means that the "get" operation should look  
something like this (an suitably fenced version of):

   if (Ptr == 0) {
      if (Ptr == 0)

Also, I see no reason why the lock needs to be per-object.  Just use a  
heavy weight global "pthreads" lock in the .cpp file.

When you get back to hacking on ManagedStatic, please define this in  
one method, not duplicated in ->, *, etc.


More information about the llvm-dev mailing list