fix benchmark error
This commit is contained in:
parent
9bd627ea6c
commit
52a4e711b5
54
tile/base/thread/thread_local.h
Normal file
54
tile/base/thread/thread_local.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef TILE_BASE_THREAD_THREAD_LOCAL_H
|
||||||
|
#define TILE_BASE_THREAD_THREAD_LOCAL_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tile/base/internal/meta.h"
|
||||||
|
#include "tile/base/thread/mutex.h"
|
||||||
|
#include "tile/base/thread/scoped_lock.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace tile {
|
||||||
|
template<typename T>
|
||||||
|
class ThreadLocal {
|
||||||
|
public:
|
||||||
|
ThreadLocal() : ThreadLocal([]() {}) {};
|
||||||
|
|
||||||
|
template<typename F, enable_if_t<eggs::is_invocable_r<std::unique_ptr<T>, F>::value> * = nullptr>
|
||||||
|
explicit ThreadLocal(F &&creator) : creator_(std::forward<F>(creator))
|
||||||
|
{}
|
||||||
|
|
||||||
|
T *Get() const {}
|
||||||
|
|
||||||
|
T *operator->() const { return Get(); }
|
||||||
|
|
||||||
|
T &operator*() const { return *Get(); }
|
||||||
|
|
||||||
|
T *Leak() noexcept
|
||||||
|
{
|
||||||
|
ScopedLock _(init_lock_);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset(std::unique_ptr<T> ptr = nullptr) noexcept { ScopedLock _(init_lock_); }
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void ForEach(F &&f) const
|
||||||
|
{
|
||||||
|
ScopedLock _(init_lock_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThreadLocal(const ThreadLocal &) = delete;
|
||||||
|
ThreadLocal &operator=(const ThreadLocal &) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static thread_local T val_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable Mutex init_lock_;
|
||||||
|
std::function<std::unique_ptr<T>()> creator_;
|
||||||
|
};
|
||||||
|
}// namespace tile
|
||||||
|
|
||||||
|
#endif// TILE_BASE_THREAD_THREAD_LOCAL_H
|
148
tile/base/thread/thread_local/object_array.h
Normal file
148
tile/base/thread/thread_local/object_array.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
#ifndef TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H
|
||||||
|
#define TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "tile/base/align.h"
|
||||||
|
#include "tile/base/logging.h"
|
||||||
|
#include "tile/base/thread/mutex.h"
|
||||||
|
#include "tile/base/thread/scoped_lock.h"
|
||||||
|
|
||||||
|
namespace tile {
|
||||||
|
namespace tls {
|
||||||
|
namespace detail {
|
||||||
|
template<typename T>
|
||||||
|
struct Entry {
|
||||||
|
std::aligned_storage<sizeof(T), alignof(T)> storage;
|
||||||
|
static_assert(sizeof(T) == sizeof(storage), "");
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ObjectArrayCache {
|
||||||
|
std::size_t limit{};
|
||||||
|
T *objects{};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ObjectArray;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class LazyInitObjectArray {
|
||||||
|
struct EntryDeleter {
|
||||||
|
void operator()(Entry<T> *ptr) noexcept { operator delete(ptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using AlignedArray = std::unique_ptr<Entry<T>[], EntryDeleter>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LazyInitObjectArray() = default;
|
||||||
|
|
||||||
|
~LazyInitObjectArray()
|
||||||
|
{
|
||||||
|
for (int i = 0; i != initialized_.size(); ++i) {
|
||||||
|
if (initialized_[i]) { reinterpret_cast<T *>(&objects_[i])->~T(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LazyInitObjectArray(LazyInitObjectArray &&) = default;
|
||||||
|
LazyInitObjectArray &operator=(LazyInitObjectArray &&) = default;
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void InitializeAt(std::size_t index, F &&f)
|
||||||
|
{
|
||||||
|
TILE_CHECK_LT(index, initialized_.size());
|
||||||
|
TILE_CHECK(!initialized_[index]);
|
||||||
|
|
||||||
|
initialized_[index] = true;
|
||||||
|
std::forward<F>(f)(&objects_[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyAt(std::size_t index)
|
||||||
|
{
|
||||||
|
TILE_CHECK_LT(index, initialized_.size());
|
||||||
|
TILE_CHECK(initialized_[index]);
|
||||||
|
|
||||||
|
initialized_[index] = false;
|
||||||
|
reinterpret_cast<T *>(&objects_[index])->~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInitializedAt(std::size_t index) const noexcept
|
||||||
|
{
|
||||||
|
TILE_CHECK_LT(index, initialized_.size());
|
||||||
|
return initialized_[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
T *GetAt(std::size_t index) noexcept
|
||||||
|
{
|
||||||
|
TILE_CHECK_LT(index, initialized_.size());
|
||||||
|
TILE_CHECK(initialized_[index]);
|
||||||
|
return reinterpret_cast<T *>(&objects_[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
T *GetObjectsMaybeUninitialized() noexcept
|
||||||
|
{
|
||||||
|
static_assert(sizeof(T) == sizeof(Entry<T>), "");
|
||||||
|
return reinterpret_cast<T *>(objects_.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const noexcept { return initialized_.size(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
AlignedArray objects_;
|
||||||
|
std::vector<bool> initialized_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class ObjectArrayRegistry {
|
||||||
|
public:
|
||||||
|
static ObjectArrayRegistry *Instance()
|
||||||
|
{
|
||||||
|
static NeverDestroyedSingleton<ObjectArrayRegistry> instance;
|
||||||
|
return instance.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register(ObjectArray<T> *array)
|
||||||
|
{
|
||||||
|
ScopedLock _(lock_);
|
||||||
|
TILE_DCHECK(std::find(arrays_.begin(), arrays_.end(), array) == arrays_.end());
|
||||||
|
arrays_.push_back(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Deregister(ObjectArray<T> *array)
|
||||||
|
{
|
||||||
|
ScopedLock _(lock_);
|
||||||
|
auto iter = std::find(arrays_.begin(), arrays_.end(), array);
|
||||||
|
TILE_CHECK(iter != arrays_.end());
|
||||||
|
arrays_.erase(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void ForEachLocked(std::size_t index, F &&f)
|
||||||
|
{
|
||||||
|
ScopedLock _(lock_);
|
||||||
|
for (auto &&e : arrays_) {
|
||||||
|
ScopedLock _(e->lock);
|
||||||
|
if (index < e->objects.size()) { f(e); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex lock_;
|
||||||
|
std::vector<ObjectArray<T> *> arrays_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct ObjectArray {
|
||||||
|
Mutex lock;
|
||||||
|
LazyInitObjectArray<T> objects_;
|
||||||
|
|
||||||
|
ObjectArray() { ObjectArrayRegistry<T>::Instance()->Register(this); }
|
||||||
|
|
||||||
|
~ObjectArray() { ObjectArrayRegistry<T>::Instance()->Deregister(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace detail
|
||||||
|
}// namespace tls
|
||||||
|
}// namespace tile
|
||||||
|
|
||||||
|
#endif// TILE_BASE_THREAD_THREAD_LOCAL_OBJECT_ARRAY_H
|
@ -11,27 +11,29 @@ namespace tile {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int StartBenchmark(int argc, char **argv) {
|
int
|
||||||
::benchmark::Initialize(&argc, argv);
|
StartBenchmark(int argc, char **argv)
|
||||||
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
|
{
|
||||||
return 1;
|
::benchmark::Initialize(&argc, argv);
|
||||||
}
|
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
|
||||||
::benchmark::RunSpecifiedBenchmarks();
|
::benchmark::RunSpecifiedBenchmarks();
|
||||||
::benchmark::Shutdown();
|
::benchmark::Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
}// namespace
|
||||||
|
|
||||||
int InitAndRunAllBenchmarks(int *argc, char **argv) {
|
int
|
||||||
|
InitAndRunAllBenchmarks(int *argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
||||||
FLAGS_logtostderr = true;
|
// FLAGS_logtostderr = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return Start(*argc, argv, StartBenchmark, true);
|
return Start(*argc, argv, StartBenchmark, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace testing
|
}// namespace testing
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
TILE_BENCHMARK_MAIN
|
TILE_BENCHMARK_MAIN
|
||||||
|
31
tile/tile.h
31
tile/tile.h
@ -4,19 +4,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// base module
|
// base module
|
||||||
#include "tile/base/defered.h"
|
#include "tile/base/align.h"
|
||||||
|
#include "tile/base/buffer.h"
|
||||||
|
#include "tile/base/casting.h"
|
||||||
|
#include "tile/base/chrono.h"
|
||||||
|
#include "tile/base/compression.h"
|
||||||
|
#include "tile/base/data.h"
|
||||||
|
#include "tile/base/deferred.h"
|
||||||
|
#include "tile/base/demangle.h"
|
||||||
|
#include "tile/base/dependency_registry.h"
|
||||||
#include "tile/base/down_cast.h"
|
#include "tile/base/down_cast.h"
|
||||||
#include "tile/base/encoding.h"
|
#include "tile/base/encoding.h"
|
||||||
|
#include "tile/base/enum.h"
|
||||||
|
#include "tile/base/erased_ptr.h"
|
||||||
|
#include "tile/base/exposed_var.h"
|
||||||
|
#include "tile/base/future.h"
|
||||||
|
#include "tile/base/handle.h"
|
||||||
|
#include "tile/base/id_alloc.h"
|
||||||
|
#include "tile/base/likely.h"
|
||||||
#include "tile/base/logging.h"
|
#include "tile/base/logging.h"
|
||||||
|
#include "tile/base/make_unique.h"
|
||||||
|
#include "tile/base/maybe_owning.h"
|
||||||
|
#include "tile/base/never_destroyed.h"
|
||||||
|
#include "tile/base/object_pool.h"
|
||||||
|
#include "tile/base/option.h"
|
||||||
#include "tile/base/optional.h"
|
#include "tile/base/optional.h"
|
||||||
#include "tile/base/random.h"
|
#include "tile/base/random.h"
|
||||||
|
#include "tile/base/ref_ptr.h"
|
||||||
#include "tile/base/slice.h"
|
#include "tile/base/slice.h"
|
||||||
|
#include "tile/base/status.h"
|
||||||
#include "tile/base/string.h"
|
#include "tile/base/string.h"
|
||||||
|
#include "tile/base/type_index.h"
|
||||||
|
#include "tile/base/variant.h"
|
||||||
|
#include "tile/base/write_mostly.h"
|
||||||
|
|
||||||
// init module
|
// init module
|
||||||
#include "tile/init/override_flag.h"
|
#include "tile/init/override_flag.h"
|
||||||
|
|
||||||
|
#include "sigslot/signal.h"
|
||||||
|
|
||||||
// Tile Init
|
// Tile Init
|
||||||
#include "tile/init.h"
|
#include "tile/init.h"
|
||||||
|
|
||||||
#endif // _TILE_TILE_H
|
#endif// _TILE_TILE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user