feat/support_fiber #2

Merged
tqcq merged 57 commits from feat/support_fiber into master 2024-06-21 10:33:52 +08:00
7 changed files with 99 additions and 10 deletions
Showing only changes of commit 424b8b5735 - Show all commits

View File

@ -43,7 +43,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
# set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
set(STATIC_BINARY_FLAGS "-static-libgcc -static-libstdc++")
set(STATIC_BINARY_FLAGS "-static-libgcc -static-libstdc++")
set(WHOLE_ARCHIVE_PREFIX "-Wl,--whole-archive")
set(WHOLE_ARCHIVE_SUFFIX "-Wl,--no-whole-archive")
endif()
@ -62,7 +62,9 @@ get_git_commit_hash(GIT_COMMIT_HASH)
get_git_commit_date(GIT_COMMIT_DATE)
get_git_commit_subject(GIT_COMMIT_SUBJECT)
set(THIRD_PARTY_INCLUDE_DIRS "third_party/json" "third_party/inja" "third_party/sigslot" "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include")
set(THIRD_PARTY_INCLUDE_DIRS
"third_party/json" "third_party/inja" "third_party/sigslot"
"${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include")
include_directories(${THIRD_PARTY_INCLUDE_DIRS})
add_subdirectory("third_party/zlib")
add_subdirectory("third_party/fmt")
@ -74,7 +76,9 @@ add_subdirectory("third_party/glog")
add_subdirectory("third_party/context")
set(CURL_DISABLE_TESTS ON)
set(CURL_CA_PATH "none" CACHE STRING "" FORCE)
set(CURL_CA_PATH
"none"
CACHE STRING "" FORCE)
set(CURL_ENABLE_SSL
OFF
CACHE BOOL "" FORCE)
@ -260,8 +264,6 @@ if(TILE_BUILD_TESTS)
target_sources(${PROJECT_NAME}_test_all PRIVATE ${test_file})
endmacro()
tile_add_test(fiber_detail_fiber_test "tile/fiber/detail/fiber_test.cc")
tile_add_test(base_internal_meta_test "tile/base/internal/meta_test.cc")
# tile_add_test(net_internal_http_engine_test
# "tile/net/internal/http_engine_test.cc")
@ -349,8 +351,6 @@ 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")

View File

@ -24,21 +24,22 @@ struct alignas(hardware_destructive_interference_size) Fiber::FiberContext {
};
void FiberEntry(fcontext_transfer_t t) {
std::function<void()> *fn = static_cast<std::function<void()> *>(t.data);
TILE_CHECK_NE(t.data, nullptr);
TILE_CHECK_NE(t.fctx, nullptr);
Fiber *self = nullptr;
try {
// From Resume()
t = jump_fcontext(t.fctx, nullptr);
auto self = reinterpret_cast<Fiber *>(t.data);
self = reinterpret_cast<Fiber *>(t.data);
self->caller_->ctx_ = t.fctx;
(*fn)();
} catch (const std::exception &e) {
TILE_LOG_ERROR("Exception caught in fiber: {}", e.what());
}
self->state_ = FiberState::Terminated;
if (GetMasterFiber() != GetCurrentFiber()) {
GetMasterFiber()->Resume();
@ -66,7 +67,6 @@ void SetUpMasterFiber(Fiber *fiber) noexcept { tls_master_fiber = fiber; }
std::unique_ptr<Fiber> Fiber::Create(std::function<void()> proc) noexcept {
return std::unique_ptr<Fiber>(new Fiber(std::move(proc)));
// return make_unique<Fiber>(std::move(proc));
}
Fiber::Fiber(std::function<void()> proc)

View File

@ -27,8 +27,12 @@ enum class FiberState {
Terminated,
};
class Scheduler;
class alignas(hardware_destructive_interference_size) Fiber {
public:
using Id = std::uint64_t;
static std::unique_ptr<Fiber>
Create(std::function<void()> proc = nullptr) noexcept;
@ -43,6 +47,8 @@ public:
void ResumeOn(std::function<void()> &&cb) noexcept;
void Yield();
Scheduler *scheduler() const { return scheduler_; }
private:
TILE_FRIEND_TEST(Fiber, Base);
friend Scheduler;
@ -59,6 +65,7 @@ private:
FiberState state_{FiberState::Runnable};
void *ctx_{nullptr};
Fiber *caller_{nullptr};
Scheduler *scheduler_{nullptr};
};
Fiber *GetCurrentFiber() noexcept;
Fiber *GetMasterFiber() noexcept;

View File

@ -0,0 +1,28 @@
#include "tile/fiber/detail/scheduler.h"
namespace tile {
namespace fiber {
namespace detail {
static thread_local Scheduler *current_scheduler = nullptr;
void Scheduler::SwitchTo(Fiber *self, Fiber *to) {
TILE_CHECK_EQ(self, GetCurrentFiber());
TILE_CHECK(to->state_ == FiberState::Runnable,
"Fiber `to` is not in Runnable.");
TILE_CHECK_NE(self, to, "Switch to yourself result in U.B.");
to->Resume();
TILE_CHECK_EQ(self, GetCurrentFiber());
}
void Scheduler::Yield(Fiber *self) {
auto master = GetMasterFiber();
master->state_ = FiberState::Runnable;
SwitchTo(self, master);
}
} // namespace detail
} // namespace fiber
} // namespace tile

View File

@ -11,6 +11,8 @@ namespace detail {
class Scheduler {
public:
static Scheduler *Current() noexcept;
void SwitchTo(Fiber *self, Fiber *to);
void Yield(Fiber *self);
};

23
tile/fiber/this_fiber.cc Normal file
View File

@ -0,0 +1,23 @@
#include "tile/fiber/this_fiber.h"
namespace tile {
namespace this_fiber {
void Yield() {
auto self = fiber::detail::GetCurrentFiber();
TILE_CHECK(self, "Yield() should be called in a fiber.");
self->scheduler()->Yield(self);
}
void SleepUntil(std::chrono::steady_clock::time_point expires_at) {}
void SleepFor(std::chrono::nanoseconds expires_in) {
SleepUntil(ReadSteadyClock() + expires_in);
}
Fiber::Id GetId() {
auto self = fiber::detail::GetCurrentFiber();
TILE_CHECK(self, "GetId() should be called in a fiber.");
}
} // namespace this_fiber
} // namespace tile

29
tile/fiber/this_fiber.h Normal file
View File

@ -0,0 +1,29 @@
#include "tile/fiber/detail/fiber.h"
#include "tile/fiber/detail/scheduler.h"
#include "tile/base/chrono.h"
namespace tile {
namespace this_fiber {
using Fiber = fiber::detail::Fiber;
void Yield();
void SleepUntil(std::chrono::steady_clock::time_point expires_at);
void SleepFor(std::chrono::nanoseconds expires_in);
template <typename Clock, typename Duration>
void SleepFor(std::chrono::time_point<Clock, Duration> expires_at) {
SleepUntil(ReadSteadyClock() + (expires_at - Clock::now()));
}
template <typename Rep, typename Period>
void SleepFor(std::chrono::duration<Rep, Period> expires_in) {
return SleepFor(static_cast<std::chrono::nanoseconds>(expires_in));
}
Fiber::Id GetId();
} // namespace this_fiber
} // namespace tile