feat/support_fiber #2
@ -362,6 +362,8 @@ if(TILE_BUILD_BENCHMARKS)
|
||||
target_sources(tile_bm_all PRIVATE ${benchmark_file})
|
||||
endmacro()
|
||||
|
||||
tile_add_bm(fiber_detail_fiber_benchmark
|
||||
"tile/fiber/detail/fiber_benchmark.cc")
|
||||
tile_add_bm(base_casting_benchmark "tile/base/casting_benchmark.cc")
|
||||
tile_add_bm(base_thread_mutex_benchmark "tile/base/thread/mutex_benchmark.cc")
|
||||
tile_add_bm(base_encoding_benchmark "tile/base/encoding_benchmark.cc")
|
||||
|
@ -79,11 +79,13 @@ Fiber::~Fiber() {
|
||||
}
|
||||
|
||||
void Fiber::Resume() {
|
||||
TILE_CHECK_NE(ctx_->fctx, nullptr);
|
||||
auto caller = Current();
|
||||
TILE_CHECK_NE(caller, this, "Can't `Resume()` self");
|
||||
SetCurrent(this);
|
||||
// TILE_LOG_INFO("Resume before proc: {}", fmt::ptr(&proc_));
|
||||
ctx_->fctx = jump_fcontext(ctx_->fctx, nullptr).fctx;
|
||||
ctx_->fctx =
|
||||
jump_fcontext(internal::Exchange(ctx_->fctx, nullptr), nullptr).fctx;
|
||||
// TILE_LOG_INFO("Resume after proc: {}", fmt::ptr(&proc_));
|
||||
SetCurrent(caller);
|
||||
}
|
||||
|
37
tile/fiber/detail/fiber_benchmark.cc
Normal file
37
tile/fiber/detail/fiber_benchmark.cc
Normal file
@ -0,0 +1,37 @@
|
||||
#include "tile/fiber/detail/fiber.h"
|
||||
|
||||
#include "tile/base/random.h"
|
||||
#include "tile/base/string.h"
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace tile {
|
||||
namespace fiber {
|
||||
namespace detail {
|
||||
void Benchmark_FiberSwitch(benchmark::State &state) {
|
||||
std::unique_ptr<Fiber> master_fiber;
|
||||
|
||||
int switch_cnt = 0;
|
||||
master_fiber = Fiber::Create([&] {
|
||||
while (state.KeepRunning()) {
|
||||
std::unique_ptr<Fiber> worker_fiber1 =
|
||||
Fiber::Create([&] { ++switch_cnt; });
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
worker_fiber1->Resume();
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
end - start);
|
||||
state.SetIterationTime(elapsed.count());
|
||||
}
|
||||
});
|
||||
|
||||
master_fiber->Resume();
|
||||
state.counters["switch_cnt"] = switch_cnt;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace fiber
|
||||
} // namespace tile
|
||||
|
||||
BENCHMARK(tile::fiber::detail::Benchmark_FiberSwitch)->UseManualTime();
|
@ -7,30 +7,40 @@ namespace fiber {
|
||||
namespace detail {
|
||||
|
||||
TEST(Fiber, Base) {
|
||||
constexpr auto kMaxCnt = 5000000;
|
||||
constexpr auto kMaxCnt = 100 * 1000;
|
||||
int cnt = 0;
|
||||
int resume_cnt = 0;
|
||||
|
||||
// 0 -> master fiber
|
||||
// [1, 9] -> worker fibers
|
||||
std::unique_ptr<Fiber> master_fiber;
|
||||
|
||||
master_fiber = Fiber::Create([&] {
|
||||
TILE_LOG_INFO("master fiber");
|
||||
// ASSERT_EQ(cnt, 0);
|
||||
ASSERT_EQ(Fiber::MasterFiber(), master_fiber.get());
|
||||
ASSERT_EQ(Fiber::Current(), master_fiber.get());
|
||||
|
||||
ASSERT_EQ(cnt, 0);
|
||||
while (cnt < kMaxCnt) {
|
||||
std::unique_ptr<Fiber> worker_fiber = Fiber::Create([&] {
|
||||
ASSERT_EQ(Fiber::Current(), worker_fiber.get());
|
||||
++cnt;
|
||||
});
|
||||
|
||||
int old = cnt;
|
||||
worker_fiber->Resume();
|
||||
ASSERT_EQ(old + 1, cnt);
|
||||
ASSERT_EQ(Fiber::Current(), master_fiber.get());
|
||||
}
|
||||
|
||||
ASSERT_EQ(cnt, kMaxCnt);
|
||||
});
|
||||
|
||||
auto master_fiber = Fiber::Create();
|
||||
Fiber::SetMasterFiber(master_fiber.get());
|
||||
Fiber::SetCurrent(master_fiber.get());
|
||||
|
||||
while (cnt < kMaxCnt) {
|
||||
std::unique_ptr<Fiber> worker_fiber = Fiber::Create([&] {
|
||||
ASSERT_EQ(Fiber::Current(), worker_fiber.get());
|
||||
++cnt;
|
||||
});
|
||||
|
||||
int old = cnt;
|
||||
worker_fiber->Resume();
|
||||
++resume_cnt;
|
||||
ASSERT_EQ(old + 1, cnt);
|
||||
ASSERT_EQ(Fiber::Current(), Fiber::MasterFiber());
|
||||
}
|
||||
ASSERT_EQ(resume_cnt, kMaxCnt);
|
||||
// Fiber::SetCurrent(master_fiber.get());
|
||||
// master_fiber->Resume();
|
||||
master_fiber->Resume();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
Loading…
x
Reference in New Issue
Block a user