mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-28 02:11:43 +00:00
[wpiutil] Remove unused ManagedStatic class (#4358)
We migrated to magic statics for lazy construction like the following:
```cpp
class Singleton {
static Singleton& GetSingleton() {
static Singleton instance;
return instance;
}
};
```
This commit is contained in:
@@ -60,7 +60,6 @@ def run_global_replacements(wpiutil_llvm_files):
|
||||
|
||||
# Replace llvm_unreachable() with wpi_unreachable()
|
||||
content = content.replace("llvm_unreachable", "wpi_unreachable")
|
||||
content = content.replace("llvm_shutdown", "wpi_shutdown")
|
||||
|
||||
content = content.replace("llvm_is_multithreaded()", "1")
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
|
||||
//
|
||||
// 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 implements the ManagedStatic class and wpi_shutdown().
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "wpi/ManagedStatic.h"
|
||||
#include "wpi/mutex.h"
|
||||
#include <cassert>
|
||||
#include <mutex>
|
||||
using namespace wpi;
|
||||
|
||||
static const ManagedStaticBase *StaticList = nullptr;
|
||||
|
||||
static wpi::mutex *getManagedStaticMutex() {
|
||||
static wpi::mutex m;
|
||||
return &m;
|
||||
}
|
||||
|
||||
void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
|
||||
void (*Deleter)(void*)) const {
|
||||
assert(Creator);
|
||||
if (1) {
|
||||
std::scoped_lock Lock(*getManagedStaticMutex());
|
||||
|
||||
if (!Ptr.load(std::memory_order_relaxed)) {
|
||||
void *Tmp = Creator();
|
||||
|
||||
Ptr.store(Tmp, std::memory_order_release);
|
||||
DeleterFn = Deleter;
|
||||
|
||||
// Add to list of managed statics.
|
||||
Next = StaticList;
|
||||
StaticList = this;
|
||||
}
|
||||
} else {
|
||||
assert(!Ptr && !DeleterFn && !Next &&
|
||||
"Partially initialized ManagedStatic!?");
|
||||
Ptr = Creator();
|
||||
DeleterFn = Deleter;
|
||||
|
||||
// Add to list of managed statics.
|
||||
Next = StaticList;
|
||||
StaticList = this;
|
||||
}
|
||||
}
|
||||
|
||||
void ManagedStaticBase::destroy() const {
|
||||
assert(DeleterFn && "ManagedStatic not initialized correctly!");
|
||||
assert(StaticList == this &&
|
||||
"Not destroyed in reverse order of construction?");
|
||||
// Unlink from list.
|
||||
StaticList = Next;
|
||||
Next = nullptr;
|
||||
|
||||
// Destroy memory.
|
||||
DeleterFn(Ptr);
|
||||
|
||||
// Cleanup.
|
||||
Ptr = nullptr;
|
||||
DeleterFn = nullptr;
|
||||
}
|
||||
|
||||
/// wpi_shutdown - Deallocate and destroy all ManagedStatic variables.
|
||||
/// IMPORTANT: it's only safe to call wpi_shutdown() in single thread,
|
||||
/// without any other threads executing LLVM APIs.
|
||||
/// wpi_shutdown() should be the last use of LLVM APIs.
|
||||
void wpi::wpi_shutdown() {
|
||||
while (StaticList)
|
||||
StaticList->destroy();
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
//===-- 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 wpi_shutdown() function.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef WPIUTIL_WPI_MANAGEDSTATIC_H
|
||||
#define WPIUTIL_WPI_MANAGEDSTATIC_H
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
/// 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; }
|
||||
};
|
||||
|
||||
// ManagedStatic must be initialized to zero, and it must *not* have a dynamic
|
||||
// initializer because managed statics are often created while running other
|
||||
// dynamic initializers. In standard C++11, the best way to accomplish this is
|
||||
// with a constexpr default constructor. However, different versions of the
|
||||
// Visual C++ compiler have had bugs where, even though the constructor may be
|
||||
// constexpr, a dynamic initializer may be emitted depending on optimization
|
||||
// settings. For the affected versions of MSVC, use the old linker
|
||||
// initialization pattern of not providing a constructor and leaving the fields
|
||||
// uninitialized. See http://llvm.org/PR41367 for details.
|
||||
#if !defined(_MSC_VER) || (_MSC_VER >= 1925) || defined(__clang__)
|
||||
#define LLVM_USE_CONSTEXPR_CTOR
|
||||
#endif
|
||||
|
||||
/// ManagedStaticBase - Common base class for ManagedStatic instances.
|
||||
class ManagedStaticBase {
|
||||
protected:
|
||||
#ifdef LLVM_USE_CONSTEXPR_CTOR
|
||||
mutable std::atomic<void *> Ptr{};
|
||||
mutable void (*DeleterFn)(void *) = nullptr;
|
||||
mutable const ManagedStaticBase *Next = nullptr;
|
||||
#else
|
||||
// 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;
|
||||
#endif
|
||||
|
||||
void RegisterManagedStatic(void *(*creator)(), void (*deleter)(void*)) const;
|
||||
|
||||
public:
|
||||
#ifdef LLVM_USE_CONSTEXPR_CTOR
|
||||
constexpr ManagedStaticBase() = default;
|
||||
#endif
|
||||
|
||||
/// 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 wpi_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; }
|
||||
|
||||
// Extract the instance, leaving the ManagedStatic uninitialized. The
|
||||
// user is then responsible for the lifetime of the returned instance.
|
||||
C *claim() {
|
||||
return static_cast<C *>(Ptr.exchange(nullptr));
|
||||
}
|
||||
};
|
||||
|
||||
/// wpi_shutdown - Deallocate and destroy all ManagedStatic variables.
|
||||
void wpi_shutdown();
|
||||
|
||||
/// wpi_shutdown_obj - This is a simple helper class that calls
|
||||
/// wpi_shutdown() when it is destroyed.
|
||||
struct wpi_shutdown_obj {
|
||||
wpi_shutdown_obj() = default;
|
||||
~wpi_shutdown_obj() { wpi_shutdown(); }
|
||||
};
|
||||
|
||||
} // end namespace wpi
|
||||
|
||||
#endif // WPIUTIL_WPI_MANAGEDSTATIC_H
|
||||
@@ -1,58 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "wpi/ManagedStatic.h" // NOLINT(build/include_order)
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
static int refCount = 0;
|
||||
|
||||
struct StaticTestClass {
|
||||
StaticTestClass() { refCount++; }
|
||||
~StaticTestClass() { refCount--; }
|
||||
|
||||
void Func() {}
|
||||
};
|
||||
|
||||
namespace wpi {
|
||||
TEST(ManagedStaticTest, LazyDoesNotInitialize) {
|
||||
{
|
||||
refCount = 0;
|
||||
wpi::ManagedStatic<StaticTestClass> managedStatic;
|
||||
(void)managedStatic;
|
||||
ASSERT_EQ(refCount, 0);
|
||||
}
|
||||
ASSERT_EQ(refCount, 0);
|
||||
wpi_shutdown();
|
||||
}
|
||||
|
||||
TEST(ManagedStaticTest, LazyInitDoesntDestruct) {
|
||||
{
|
||||
refCount = 0;
|
||||
wpi::ManagedStatic<StaticTestClass> managedStatic;
|
||||
ASSERT_EQ(refCount, 0);
|
||||
managedStatic->Func();
|
||||
ASSERT_EQ(refCount, 1);
|
||||
}
|
||||
ASSERT_EQ(refCount, 1);
|
||||
wpi_shutdown();
|
||||
ASSERT_EQ(refCount, 0);
|
||||
}
|
||||
|
||||
TEST(ManagedStaticTest, EagerInit) {
|
||||
{
|
||||
refCount = 0;
|
||||
StaticTestClass* test = new StaticTestClass{};
|
||||
ASSERT_EQ(refCount, 1); // NOLINT
|
||||
wpi::ManagedStatic<StaticTestClass> managedStatic(
|
||||
test, [](void* val) { delete static_cast<StaticTestClass*>(val); });
|
||||
ASSERT_EQ(refCount, 1);
|
||||
managedStatic->Func();
|
||||
ASSERT_EQ(refCount, 1);
|
||||
}
|
||||
ASSERT_EQ(refCount, 1);
|
||||
wpi_shutdown();
|
||||
ASSERT_EQ(refCount, 0);
|
||||
}
|
||||
} // namespace wpi
|
||||
Reference in New Issue
Block a user