Home | History | Annotate | Download | only in Support
      1 //===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
      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 implements the ManagedStatic class and llvm_shutdown().
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Support/ManagedStatic.h"
     15 #include "llvm/Config/config.h"
     16 #include "llvm/Support/Atomic.h"
     17 #include <cassert>
     18 using namespace llvm;
     19 
     20 static const ManagedStaticBase *StaticList = 0;
     21 
     22 void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
     23                                               void (*Deleter)(void*)) const {
     24   if (llvm_is_multithreaded()) {
     25     llvm_acquire_global_lock();
     26 
     27     if (Ptr == 0) {
     28       void* tmp = Creator ? Creator() : 0;
     29 
     30       TsanHappensBefore(this);
     31       sys::MemoryFence();
     32 
     33       // This write is racy against the first read in the ManagedStatic
     34       // accessors. The race is benign because it does a second read after a
     35       // memory fence, at which point it isn't possible to get a partial value.
     36       TsanIgnoreWritesBegin();
     37       Ptr = tmp;
     38       TsanIgnoreWritesEnd();
     39       DeleterFn = Deleter;
     40 
     41       // Add to list of managed statics.
     42       Next = StaticList;
     43       StaticList = this;
     44     }
     45 
     46     llvm_release_global_lock();
     47   } else {
     48     assert(Ptr == 0 && DeleterFn == 0 && Next == 0 &&
     49            "Partially initialized ManagedStatic!?");
     50     Ptr = Creator ? Creator() : 0;
     51     DeleterFn = Deleter;
     52 
     53     // Add to list of managed statics.
     54     Next = StaticList;
     55     StaticList = this;
     56   }
     57 }
     58 
     59 void ManagedStaticBase::destroy() const {
     60   assert(DeleterFn && "ManagedStatic not initialized correctly!");
     61   assert(StaticList == this &&
     62          "Not destroyed in reverse order of construction?");
     63   // Unlink from list.
     64   StaticList = Next;
     65   Next = 0;
     66 
     67   // Destroy memory.
     68   DeleterFn(Ptr);
     69 
     70   // Cleanup.
     71   Ptr = 0;
     72   DeleterFn = 0;
     73 }
     74 
     75 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
     76 void llvm::llvm_shutdown() {
     77   while (StaticList)
     78     StaticList->destroy();
     79 
     80   if (llvm_is_multithreaded()) llvm_stop_multithreaded();
     81 }
     82