diff options
| author | Ralf Luther <luther.ralf@gmail.com> | 2019-03-27 20:23:17 +0000 |
|---|---|---|
| committer | Gerrit Code Review <gerrit2@aicp-server-3> | 2019-03-27 20:23:17 +0000 |
| commit | 1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch) | |
| tree | 391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/include/llvm/Support/ManagedStatic.h | |
| parent | d1d48b140bafaa8a50107292f5fce95562575765 (diff) | |
| parent | 4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff) | |
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/include/llvm/Support/ManagedStatic.h')
| -rw-r--r-- | clang-r353983/include/llvm/Support/ManagedStatic.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/Support/ManagedStatic.h b/clang-r353983/include/llvm/Support/ManagedStatic.h new file mode 100644 index 00000000..441f24e0 --- /dev/null +++ b/clang-r353983/include/llvm/Support/ManagedStatic.h @@ -0,0 +1,96 @@ +//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the ManagedStatic class and the llvm_shutdown() function. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MANAGEDSTATIC_H +#define LLVM_SUPPORT_MANAGEDSTATIC_H + +#include <atomic> +#include <cstddef> + +namespace llvm { + +/// object_creator - Helper method for ManagedStatic. +template <class C> struct object_creator { + static void *call() { return new C(); } +}; + +/// object_deleter - Helper method for ManagedStatic. +/// +template <typename T> struct object_deleter { + static void call(void *Ptr) { delete (T *)Ptr; } +}; +template <typename T, size_t N> struct object_deleter<T[N]> { + static void call(void *Ptr) { delete[](T *)Ptr; } +}; + +/// ManagedStaticBase - Common base class for ManagedStatic instances. +class ManagedStaticBase { +protected: + // This should only be used as a static variable, which guarantees that this + // will be zero initialized. + mutable std::atomic<void *> Ptr; + mutable void (*DeleterFn)(void*); + mutable const ManagedStaticBase *Next; + + void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const; + +public: + /// isConstructed - Return true if this object has not been created yet. + bool isConstructed() const { return Ptr != nullptr; } + + void destroy() const; +}; + +/// ManagedStatic - This transparently changes the behavior of global statics to +/// be lazily constructed on demand (good for reducing startup times of dynamic +/// libraries that link in LLVM components) and for making destruction be +/// explicit through the llvm_shutdown() function call. +/// +template <class C, class Creator = object_creator<C>, + class Deleter = object_deleter<C>> +class ManagedStatic : public ManagedStaticBase { +public: + // Accessors. + C &operator*() { + void *Tmp = Ptr.load(std::memory_order_acquire); + if (!Tmp) + RegisterManagedStatic(Creator::call, Deleter::call); + + return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); + } + + C *operator->() { return &**this; } + + const C &operator*() const { + void *Tmp = Ptr.load(std::memory_order_acquire); + if (!Tmp) + RegisterManagedStatic(Creator::call, Deleter::call); + + return *static_cast<C *>(Ptr.load(std::memory_order_relaxed)); + } + + const C *operator->() const { return &**this; } +}; + +/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. +void llvm_shutdown(); + +/// llvm_shutdown_obj - This is a simple helper class that calls +/// llvm_shutdown() when it is destroyed. +struct llvm_shutdown_obj { + llvm_shutdown_obj() = default; + ~llvm_shutdown_obj() { llvm_shutdown(); } +}; + +} // end namespace llvm + +#endif // LLVM_SUPPORT_MANAGEDSTATIC_H |
