[llvm-commits] [llvm] r71796 - /llvm/trunk/include/llvm/Support/ManagedStatic.h

Chris Lattner clattner at apple.com
Fri May 15 10:21:37 PDT 2009


On May 14, 2009, at 2:26 PM, Owen Anderson wrote:

> Author: resistor
> Date: Thu May 14 16:26:50 2009
> New Revision: 71796
>
> URL: http://llvm.org/viewvc/llvm-project?rev=71796&view=rev
> Log:
> Make ManagedStatic threadsafe by using atomic operations.

Owen, I don't think this is the right approach.  Why not just have one  
global cas_flag that all ManagedStatic's use instead of having one per  
ManagedStatic?

In the common case, the ManagedStatic is non-null.  This means it is  
initialized, so no atomic stuff needs to be done.  The only atomic  
stuff would have to be done if the ManagedStatic is null to make sure  
that it isn't initialized by more than one thread at a time.

-Chris

>
>
> Modified:
>    llvm/trunk/include/llvm/Support/ManagedStatic.h
>
> Modified: llvm/trunk/include/llvm/Support/ManagedStatic.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ManagedStatic.h?rev=71796&r1=71795&r2=71796&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/Support/ManagedStatic.h (original)
> +++ llvm/trunk/include/llvm/Support/ManagedStatic.h Thu May 14  
> 16:26:50 2009
> @@ -14,6 +14,8 @@
> #ifndef LLVM_SUPPORT_MANAGED_STATIC_H
> #define LLVM_SUPPORT_MANAGED_STATIC_H
>
> +#include "llvm/System/Atomic.h"
> +
> namespace llvm {
>
> /// object_deleter - Helper method for ManagedStatic.
> @@ -26,6 +28,8 @@
> /// ManagedStaticBase - Common base class for ManagedStatic instances.
> class ManagedStaticBase {
> protected:
> +  sys::cas_flag InitFlag;
> +
>   // This should only be used as a static variable, which guarantees  
> that this
>   // will be zero initialized.
>   mutable void *Ptr;
> @@ -51,19 +55,47 @@
>
>   // Accessors.
>   C &operator*() {
> -    if (!Ptr) LazyInit();
> +    sys::cas_flag OldFlag = sys::CompareAndSwap(&InitFlag, 1, 0);
> +    if (OldFlag == 0) {
> +      LazyInit();
> +      sys::MemoryFence();
> +      InitFlag = 2;
> +    } else if (OldFlag == 1)
> +      while (OldFlag == 1) ;
> +
>     return *static_cast<C*>(Ptr);
>   }
>   C *operator->() {
> -    if (!Ptr) LazyInit();
> +    sys::cas_flag OldFlag = sys::CompareAndSwap(&InitFlag, 1, 0);
> +    if (OldFlag == 0) {
> +      LazyInit();
> +      sys::MemoryFence();
> +      InitFlag = 2;
> +    } else if (OldFlag == 1)
> +      while (OldFlag == 1) ;
> +
>     return static_cast<C*>(Ptr);
>   }
>   const C &operator*() const {
> -    if (!Ptr) LazyInit();
> +    sys::cas_flag OldFlag = sys::CompareAndSwap(&InitFlag, 1, 0);
> +    if (OldFlag == 0) {
> +      LazyInit();
> +      sys::MemoryFence();
> +      InitFlag = 2;
> +    } else if (OldFlag == 1)
> +      while (OldFlag == 1) ;
> +
>     return *static_cast<C*>(Ptr);
>   }
>   const C *operator->() const {
> -    if (!Ptr) LazyInit();
> +    sys::cas_flag OldFlag = sys::CompareAndSwap(&InitFlag, 1, 0);
> +    if (OldFlag == 0) {
> +      LazyInit();
> +      sys::MemoryFence();
> +      InitFlag = 2;
> +    } else if (OldFlag == 1)
> +      while (OldFlag == 1) ;
> +
>     return static_cast<C*>(Ptr);
>   }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list