feat add this_fiber
Some checks failed
linux-arm-gcc / linux-gcc-arm (Debug) (push) Failing after 16s
linux-arm-gcc / linux-gcc-arm (Release) (push) Failing after 14s
linux-arm-gcc / linux-gcc-armhf (Debug) (push) Failing after 13s
linux-arm-gcc / linux-gcc-armhf (Release) (push) Failing after 13s
linux-mips-gcc / linux-gcc-mipsel (Debug) (push) Failing after 16s
linux-mips-gcc / linux-gcc-mipsel (Release) (push) Failing after 16s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Failing after 20s
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Failing after 21s
linux-riscv64-gcc / linux-gcc-riscv64 (Release) (push) Failing after 19s
linux-riscv64-gcc / linux-gcc-riscv64 (Debug) (push) Failing after 37s
linux-x86-gcc / linux-gcc (Debug) (push) Failing after 15s
linux-x86-gcc / linux-gcc (Release) (push) Failing after 41s
android / build (push) Successful in 9m6s
linux-x64-gcc / linux-gcc (Debug) (push) Failing after 10m31s
linux-x64-gcc / linux-gcc (Release) (push) Failing after 15m46s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Debug) (push) Failing after 24s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Release) (push) Failing after 22s

This commit is contained in:
tqcq 2024-06-16 00:46:50 +08:00
parent 319647bd11
commit 424b8b5735
7 changed files with 99 additions and 10 deletions

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_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
# set(CMAKE_C_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_PREFIX "-Wl,--whole-archive")
set(WHOLE_ARCHIVE_SUFFIX "-Wl,--no-whole-archive") set(WHOLE_ARCHIVE_SUFFIX "-Wl,--no-whole-archive")
endif() endif()
@ -62,7 +62,9 @@ get_git_commit_hash(GIT_COMMIT_HASH)
get_git_commit_date(GIT_COMMIT_DATE) get_git_commit_date(GIT_COMMIT_DATE)
get_git_commit_subject(GIT_COMMIT_SUBJECT) 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}) include_directories(${THIRD_PARTY_INCLUDE_DIRS})
add_subdirectory("third_party/zlib") add_subdirectory("third_party/zlib")
add_subdirectory("third_party/fmt") add_subdirectory("third_party/fmt")
@ -74,7 +76,9 @@ add_subdirectory("third_party/glog")
add_subdirectory("third_party/context") add_subdirectory("third_party/context")
set(CURL_DISABLE_TESTS ON) 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 set(CURL_ENABLE_SSL
OFF OFF
CACHE BOOL "" FORCE) CACHE BOOL "" FORCE)
@ -260,8 +264,6 @@ if(TILE_BUILD_TESTS)
target_sources(${PROJECT_NAME}_test_all PRIVATE ${test_file}) target_sources(${PROJECT_NAME}_test_all PRIVATE ${test_file})
endmacro() 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(base_internal_meta_test "tile/base/internal/meta_test.cc")
# tile_add_test(net_internal_http_engine_test # tile_add_test(net_internal_http_engine_test
# "tile/net/internal/http_engine_test.cc") # "tile/net/internal/http_engine_test.cc")
@ -349,8 +351,6 @@ if(TILE_BUILD_BENCHMARKS)
target_sources(tile_bm_all PRIVATE ${benchmark_file}) target_sources(tile_bm_all PRIVATE ${benchmark_file})
endmacro() 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_casting_benchmark "tile/base/casting_benchmark.cc")
tile_add_bm(base_thread_mutex_benchmark "tile/base/thread/mutex_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") 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) { void FiberEntry(fcontext_transfer_t t) {
std::function<void()> *fn = static_cast<std::function<void()> *>(t.data); std::function<void()> *fn = static_cast<std::function<void()> *>(t.data);
TILE_CHECK_NE(t.data, nullptr); TILE_CHECK_NE(t.data, nullptr);
TILE_CHECK_NE(t.fctx, nullptr); TILE_CHECK_NE(t.fctx, nullptr);
Fiber *self = nullptr;
try { try {
// From Resume() // From Resume()
t = jump_fcontext(t.fctx, nullptr); t = jump_fcontext(t.fctx, nullptr);
auto self = reinterpret_cast<Fiber *>(t.data); self = reinterpret_cast<Fiber *>(t.data);
self->caller_->ctx_ = t.fctx; self->caller_->ctx_ = t.fctx;
(*fn)(); (*fn)();
} catch (const std::exception &e) { } catch (const std::exception &e) {
TILE_LOG_ERROR("Exception caught in fiber: {}", e.what()); TILE_LOG_ERROR("Exception caught in fiber: {}", e.what());
} }
self->state_ = FiberState::Terminated;
if (GetMasterFiber() != GetCurrentFiber()) { if (GetMasterFiber() != GetCurrentFiber()) {
GetMasterFiber()->Resume(); 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 { std::unique_ptr<Fiber> Fiber::Create(std::function<void()> proc) noexcept {
return std::unique_ptr<Fiber>(new Fiber(std::move(proc))); return std::unique_ptr<Fiber>(new Fiber(std::move(proc)));
// return make_unique<Fiber>(std::move(proc));
} }
Fiber::Fiber(std::function<void()> proc) Fiber::Fiber(std::function<void()> proc)

View File

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