feat/support_fiber #6

Merged
tqcq merged 52 commits from feat/support_fiber into master 2024-08-11 13:03:04 +08:00
4 changed files with 249 additions and 18 deletions
Showing only changes of commit 52a4e711b5 - Show all commits

View 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

View 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

View File

@ -11,27 +11,29 @@ namespace tile {
namespace testing {
namespace {
int StartBenchmark(int argc, char **argv) {
::benchmark::Initialize(&argc, argv);
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
return 1;
}
::benchmark::RunSpecifiedBenchmarks();
::benchmark::Shutdown();
return 0;
int
StartBenchmark(int argc, char **argv)
{
::benchmark::Initialize(&argc, argv);
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
::benchmark::RunSpecifiedBenchmarks();
::benchmark::Shutdown();
return 0;
}
} // namespace
}// namespace
int InitAndRunAllBenchmarks(int *argc, char **argv) {
int
InitAndRunAllBenchmarks(int *argc, char **argv)
{
if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
FLAGS_logtostderr = true;
}
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
// FLAGS_logtostderr = true;
// }
return Start(*argc, argv, StartBenchmark, true);
return Start(*argc, argv, StartBenchmark, true);
}
} // namespace testing
} // namespace tile
}// namespace testing
}// namespace tile
TILE_BENCHMARK_MAIN

View File

@ -4,19 +4,46 @@
#pragma once
// 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/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/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/random.h"
#include "tile/base/ref_ptr.h"
#include "tile/base/slice.h"
#include "tile/base/status.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
#include "tile/init/override_flag.h"
#include "sigslot/signal.h"
// Tile Init
#include "tile/init.h"
#endif // _TILE_TILE_H
#endif// _TILE_TILE_H