Home | History | Annotate | Download | only in Support
      1 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the ManagedStatic class and the llvm_shutdown() function.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_SUPPORT_MANAGEDSTATIC_H
     15 #define LLVM_SUPPORT_MANAGEDSTATIC_H
     16 
     17 #include "llvm/Support/Compiler.h"
     18 #include <atomic>
     19 #include <cstddef>
     20 
     21 namespace llvm {
     22 
     23 /// object_creator - Helper method for ManagedStatic.
     24 template<class C>
     25 LLVM_LIBRARY_VISIBILITY void* object_creator() {
     26   return new C();
     27 }
     28 
     29 /// object_deleter - Helper method for ManagedStatic.
     30 ///
     31 template <typename T> struct LLVM_LIBRARY_VISIBILITY object_deleter {
     32   static void call(void *Ptr) { delete (T *)Ptr; }
     33 };
     34 template <typename T, size_t N>
     35 struct LLVM_LIBRARY_VISIBILITY object_deleter<T[N]> {
     36   static void call(void *Ptr) { delete[](T *)Ptr; }
     37 };
     38 
     39 /// ManagedStaticBase - Common base class for ManagedStatic instances.
     40 class ManagedStaticBase {
     41 protected:
     42   // This should only be used as a static variable, which guarantees that this
     43   // will be zero initialized.
     44   mutable std::atomic<void *> Ptr;
     45   mutable void (*DeleterFn)(void*);
     46   mutable const ManagedStaticBase *Next;
     47 
     48   void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
     49 
     50 public:
     51   /// isConstructed - Return true if this object has not been created yet.
     52   bool isConstructed() const { return Ptr != nullptr; }
     53 
     54   void destroy() const;
     55 };
     56 
     57 /// ManagedStatic - This transparently changes the behavior of global statics to
     58 /// be lazily constructed on demand (good for reducing startup times of dynamic
     59 /// libraries that link in LLVM components) and for making destruction be
     60 /// explicit through the llvm_shutdown() function call.
     61 ///
     62 template<class C>
     63 class ManagedStatic : public ManagedStaticBase {
     64 public:
     65   // Accessors.
     66   C &operator*() {
     67     void *Tmp = Ptr.load(std::memory_order_acquire);
     68     if (!Tmp)
     69       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
     70 
     71     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
     72   }
     73 
     74   C *operator->() { return &**this; }
     75 
     76   const C &operator*() const {
     77     void *Tmp = Ptr.load(std::memory_order_acquire);
     78     if (!Tmp)
     79       RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
     80 
     81     return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
     82   }
     83 
     84   const C *operator->() const { return &**this; }
     85 };
     86 
     87 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
     88 void llvm_shutdown();
     89 
     90 /// llvm_shutdown_obj - This is a simple helper class that calls
     91 /// llvm_shutdown() when it is destroyed.
     92 struct llvm_shutdown_obj {
     93   llvm_shutdown_obj() = default;
     94   ~llvm_shutdown_obj() { llvm_shutdown(); }
     95 };
     96 
     97 } // end namespace llvm
     98 
     99 #endif // LLVM_SUPPORT_MANAGEDSTATIC_H
    100