diff --git a/CMakeLists.txt b/CMakeLists.txt index 3988497..94f27d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ if (NOT tile_VERSION_BUILD) endif() project( tile - VERSION ${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}.${tile_VERSION_BUILD} + VERSION "${tile_VERSION_MAJOR}.${tile_VERSION_MINOR}.${tile_VERSION_PATCH}" LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 11) @@ -210,9 +210,9 @@ set(TILE_SRCS "tile/rpc/protocol/http/buffer_io.cc" "tile/rpc/protocol/message.cc" # "tile/rpc/server.cc" - "tile/util/config.cc" - "tile/util/ini_file_config.cc" - "tile/util/layered_config.cc" + "tile/base/config/config.cc" + "tile/base/config/ini_file_config.cc" + "tile/base/config/layered_config.cc" ) if((NOT TILE_HAVE_GETIFADDRS) OR (NOT TILE_HAVE_FREEIFADDRS)) @@ -295,82 +295,30 @@ if(TILE_BUILD_TESTS) add_test(NAME ${test_name} COMMAND ${test_name}) endmacro() - tile_add_test(io_util_rate_limiter_test "tile/io/util/rate_limiter_test.cc") - tile_add_test(base_exposed_var_test "tile/base/exposed_var_test.cc") - tile_add_test(base_byte_order_test "tile/base/byte_order_test.cc") - # tile_add_test(fiber_detail_scheduler_test "tile/fiber/detail/scheduler_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") - tile_add_test(net_internal_http_task_test - "tile/net/internal/http_task_test.cc") - tile_add_test(net_http_http_client_test "tile/net/http/http_client_test.cc") - tile_add_test(net_http_http_request_test "tile/net/http/http_reqeust_test.cc") - tile_add_test(net_http_http_response_test - "tile/net/http/http_response_test.cc") - tile_add_test(base_compression_util_test "tile/base/compression/util_test.cc") - tile_add_test(rpc_protocol_http_buffer_io_test - "tile/rpc/protocol/http/buffer_io_test.cc") +function(add_test_group prefix group_name) + file(GLOB_RECURSE TEST_FILES "${prefix}/**/*_test.cc") + foreach(SRC_FILE ${TEST_FILES}) + if(IS_DIRECTORY ${SRC_FILE}) + continue() + endif() + # convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}") + file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}") + string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}") + # if group_name is not empty, add suffix _ + if (NOT group_name STREQUAL "") + set(TEST_NAME "${group_name}_${TEST_NAME}") + endif() + + tile_add_test(${TEST_NAME} ${SRC_FILE}) + endforeach() +endfunction(add_test_group) - tile_add_test(base_compression_test "tile/base/compression_test.cc") - tile_add_test(base_casting_test "tile/base/casting_test.cc") - tile_add_test(base_future_future_test "tile/base/future/future_test.cc") - tile_add_test(base_future_boxed_test "tile/base/future/boxed_test.cc") - tile_add_test(base_option_option_service_test - "tile/base/option/option_service_test.cc") - tile_add_test(base_ref_ptr_test "tile/base/ref_ptr_test.cc") - tile_add_test(base_object_pool_disabled_test - "tile/base/object_pool/disabled_test.cc") - tile_add_test(base_object_pool_types_test - "tile/base/object_pool/types_test.cc") - tile_add_test(base_string_test "tile/base/string_test.cc") - tile_add_test(base_deferred_test "tile/base/deferred_test.cc") - tile_add_test(base_internal_singly_linked_list_test - "tile/base/internal/singly_linked_list_test.cc") - tile_add_test(base_internal_move_on_copy_test - "tile/base/internal/move_on_copy_test.cc") - tile_add_test(base_internal_thread_pool_test - "tile/base/internal/thread_pool_test.cc") - tile_add_test(base_internal_format_test "tile/base/internal/format_test.cc") - tile_add_test(base_internal_background_task_host_test - "tile/base/internal/background_task_host_test.cc") - tile_add_test(base_down_cast_test "tile/base/down_cast_test.cc") - tile_add_test(base_encoding_hex_test "tile/base/encoding/hex_test.cc") - tile_add_test(base_encoding_percent_test "tile/base/encoding/percent_test.cc") - tile_add_test(base_encoding_base64_test "tile/base/encoding/base64_test.cc") - tile_add_test(base_internal_case_insensitive_hash_map_test - "tile/base/internal/case_insensitive_hash_map_test.cc") - tile_add_test(net_http_http_headers_test "tile/net/http/http_headers_test.cc") - tile_add_test(base_demangle_test "tile/base/demangle_test.cc") - tile_add_test(base_option_json_parser_test - "tile/base/option/json_parser_test.cc") - tile_add_test(base_option_key_test "tile/base/option/key_test.cc") - tile_add_test(base_dependency_registry_test - "tile/base/dependency_registry_test.cc") - tile_add_test(base_maybe_owning_test "tile/base/maybe_owning_test.cc") - tile_add_test(base_status_test "tile/base/status_test.cc") - tile_add_test(base_net_endpoint_test "tile/base/net/endpoint_test.cc") - tile_add_test(base_handle_test "tile/base/handle_test.cc") - tile_add_test(base_thread_scoped_lock_test - "tile/base/thread/scoped_lock_test.cc") - tile_add_test(base_thread_spinlock_test "tile/base/thread/spinlock_test.cc") - tile_add_test(base_thread_unique_lock_test - "tile/base/thread/unique_lock_test.cc") - tile_add_test(base_thread_cond_var_test "tile/base/thread/cond_var_test.cc") - tile_add_test(base_thread_latch_test "tile/base/thread/latch_test.cc") - # tile_add_test(fiber_ucontext_test "tile/fiber/ucontext_test.cc") - - tile_add_test(init_on_init_test "tile/init/on_init_test.cc") - tile_add_test(base_buffer_test "tile/base/buffer_test.cc") - tile_add_test(base_object_pool_thread_local_test - "tile/base/object_pool/thread_local_test.cc") - tile_add_test(base_internal_logging_test "tile/base/internal/logging_test.cc") - tile_add_test(base_chrono_test "tile/base/chrono_test.cc") - tile_add_test(init_override_flag_test "tile/init/override_flag_test.cc") + add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/base base) + add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/init init) + add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/io io) + add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/net net) + add_test_group(${CMAKE_CURRENT_SOURCE_DIR}/tile/rpc rpc) tile_add_custom_test("custom_http_client_test" "tests/http_client_test.cc") - # tile_add_test(base_internal_time_keeper_test - # "tile/base/internal/time_keeper_test.cc") - tile_add_test(tile_util_ini_file_config_test "tile/util/ini_file_config_test.cc") endif(TILE_BUILD_TESTS) if(TILE_BUILD_BENCHMARKS) diff --git a/tile/util/config.cc b/tile/base/config/config.cc similarity index 99% rename from tile/util/config.cc rename to tile/base/config/config.cc index ddd3178..e56cf21 100644 --- a/tile/util/config.cc +++ b/tile/base/config/config.cc @@ -1,4 +1,4 @@ -#include "tile/util/config.h" +#include "tile/base/config/config.h" #include "tile/base/thread/unique_lock.h" namespace tile { diff --git a/tile/util/config.h b/tile/base/config/config.h similarity index 97% rename from tile/util/config.h rename to tile/base/config/config.h index 3c68673..32e3204 100644 --- a/tile/util/config.h +++ b/tile/base/config/config.h @@ -1,8 +1,7 @@ -#ifndef TILE_UTIL_CONFIG_H -#define TILE_UTIL_CONFIG_H +#ifndef TILE_BASE_CONFIG_CONFIG_H +#define TILE_BASE_CONFIG_CONFIG_H #pragma once - #include "tile/base/optional.h" #include "tile/base/ref_ptr.h" #include "tile/base/slice.h" @@ -125,4 +124,4 @@ private: } // namespace util } // namespace tile -#endif // TILE_UTIL_CONFIG_H +#endif // TILE_BASE_CONFIG_CONFIG_H diff --git a/tile/base/config/configurable.h b/tile/base/config/configurable.h new file mode 100644 index 0000000..6896afd --- /dev/null +++ b/tile/base/config/configurable.h @@ -0,0 +1,19 @@ +#ifndef TILE_BASE_CONFIG_CONFIGURABLE_H +#define TILE_BASE_CONFIG_CONFIGURABLE_H + +#pragma once +#include "tile/base/string.h" + +namespace tile { +namespace util { +class Configurable { + Configurable(); + virtual ~Configurable() = default; + virtual void SetProperty(const Slice &name, const Slice &value) = 0; + virtual std::string GetProperty(const Slice &name) const = 0; +}; + +} // namespace util +} // namespace tile + +#endif // TILE_BASE_CONFIG_CONFIGURABLE_H diff --git a/tile/util/ini_file_config.cc b/tile/base/config/ini_file_config.cc similarity index 98% rename from tile/util/ini_file_config.cc rename to tile/base/config/ini_file_config.cc index 2223820..c3838c5 100644 --- a/tile/util/ini_file_config.cc +++ b/tile/base/config/ini_file_config.cc @@ -1,4 +1,4 @@ -#include "tile/util/ini_file_config.h" +#include "tile/base/config/ini_file_config.h" #include "tile/base/thread/scoped_lock.h" namespace tile { diff --git a/tile/util/ini_file_config.h b/tile/base/config/ini_file_config.h similarity index 84% rename from tile/util/ini_file_config.h rename to tile/base/config/ini_file_config.h index b672719..fe3e1a9 100644 --- a/tile/util/ini_file_config.h +++ b/tile/base/config/ini_file_config.h @@ -1,9 +1,9 @@ -#ifndef TILE_UTIL_INI_FILE_CONFIG_H -#define TILE_UTIL_INI_FILE_CONFIG_H +#ifndef TILE_BASE_CONFIG_INI_FILE_CONFIG_H +#define TILE_BASE_CONFIG_INI_FILE_CONFIG_H #pragma once -#include "tile/util/config.h" +#include "tile/base/config/config.h" #include namespace tile { @@ -37,4 +37,4 @@ private: } // namespace util } // namespace tile -#endif // TILE_UTIL_INI_FILE_CONFIG_H +#endif // TILE_BASE_CONFIG_INI_FILE_CONFIG_H diff --git a/tile/util/ini_file_config_test.cc b/tile/base/config/ini_file_config_test.cc similarity index 95% rename from tile/util/ini_file_config_test.cc rename to tile/base/config/ini_file_config_test.cc index b3b8600..e110933 100644 --- a/tile/util/ini_file_config_test.cc +++ b/tile/base/config/ini_file_config_test.cc @@ -1,4 +1,4 @@ -#include "tile/util/ini_file_config.h" +#include "tile/base/config/ini_file_config.h" #include "gtest/gtest.h" const char *kIniFileConfig = R"( diff --git a/tile/util/layered_config.cc b/tile/base/config/layered_config.cc similarity index 98% rename from tile/util/layered_config.cc rename to tile/base/config/layered_config.cc index 4ab3851..3b90173 100644 --- a/tile/util/layered_config.cc +++ b/tile/base/config/layered_config.cc @@ -1,4 +1,4 @@ -#include "tile/util/layered_config.h" +#include "tile/base/config/layered_config.h" namespace tile { namespace util { diff --git a/tile/util/layered_config.h b/tile/base/config/layered_config.h similarity index 89% rename from tile/util/layered_config.h rename to tile/base/config/layered_config.h index a23b60b..e481515 100644 --- a/tile/util/layered_config.h +++ b/tile/base/config/layered_config.h @@ -1,9 +1,9 @@ -#ifndef TILE_UTIL_LAYERD_CONFIG_H -#define TILE_UTIL_LAYERD_CONFIG_H +#ifndef TILE_BASE_CONFIG_LAYERED_CONFIG_H +#define TILE_BASE_CONFIG_LAYERED_CONFIG_H #pragma once -#include "tile/util/config.h" +#include "tile/base/config/config.h" #include namespace tile { @@ -54,4 +54,4 @@ private: } // namespace util } // namespace tile -#endif // TILE_UTIL_LAYERD_CONFIG_H +#endif // TILE_BASE_CONFIG_LAYERED_CONFIG_H diff --git a/tile/fiber/detail/fiber.cc b/tile/fiber/detail/fiber.cc deleted file mode 100644 index a250c99..0000000 --- a/tile/fiber/detail/fiber.cc +++ /dev/null @@ -1,178 +0,0 @@ -#include "tile/fiber/detail/fiber.h" - -#include "tile/base/align.h" -#include "tile/base/internal/index_alloc.h" -#include "tile/base/internal/move_on_copy.h" -#include "tile/base/logging.h" -#include "tile/base/make_unique.h" -#include "tile/base/object_pool.h" -#include "tile/base/string.h" - -#include "nova/context/fcontext.h" - -namespace tile { -namespace fiber { -namespace detail { - -std::string ToString(const FiberState &state) noexcept { - switch (state) { - case FiberState::Runnable: - return "Runnable"; - case FiberState::Running: - return "Running"; - case FiberState::Waiting: - return "Waiting"; - case FiberState::Terminated: - return "Terminated"; - default: - TILE_UNEXPECTED(""); - return "Unknown"; - } -} -std::ostream &operator<<(std::ostream &os, const FiberState &state) noexcept { - return os << ToString(state); -} - -static thread_local Fiber *tls_current_fiber = nullptr; -static thread_local Fiber *tls_master_fiber = nullptr; - -constexpr std::size_t kStackSize = 128 * 1024; // 128k -constexpr std::size_t kAlignSize = 16; - -struct alignas(hardware_destructive_interference_size) Fiber::FiberContext { - std::aligned_storage::type stack; - std::function proc; -}; - -void FiberEntry(fcontext_transfer_t t) { - std::function *fn = static_cast *>(t.data); - TILE_CHECK(t.data != nullptr); - TILE_CHECK(t.fctx != nullptr); - Fiber *self = nullptr; - - try { - // From Resume() - t = jump_fcontext(t.fctx, nullptr); - Fiber *caller = reinterpret_cast(t.data); - - self = GetCurrentFiber(); - if (caller) { - caller->ctx_ = t.fctx; - } else { - TILE_CHECK_EQ(self, GetMasterFiber()); - } - - (*fn)(); - } catch (const std::exception &e) { - TILE_LOG_ERROR("Exception caught in fiber: {}", e.what()); - } - self->state_ = FiberState::Terminated; - - if (GetMasterFiber() == self) { - // master fiber end - jump_fcontext(t.fctx, GetMasterFiber()); - } else { - TILE_CHECK(GetMasterFiber() != nullptr); - TILE_CHECK_NE(GetMasterFiber()->state(), FiberState::Terminated); - GetMasterFiber()->Resume(); - } -} - -fcontext_transfer_t FiberOnTop(fcontext_transfer_t t) {} - -fcontext_t CreateFiber(void *stack, std::size_t stack_size, - std::function *fn) { - void *stack_top = static_cast(stack) + stack_size; - const fcontext_t fctx = make_fcontext(stack_top, stack_size, FiberEntry); - TILE_CHECK(fctx != nullptr); - - return jump_fcontext(fctx, fn).fctx; -} - -Fiber *GetCurrentFiber() noexcept { return tls_current_fiber; } -void SetUpCurrentFiber(Fiber *fiber) noexcept { tls_current_fiber = fiber; } - -Fiber *GetMasterFiber() noexcept { return tls_master_fiber; } -void SetUpMasterFiber(Fiber *fiber) noexcept { tls_master_fiber = fiber; } - -std::unique_ptr Fiber::Create(std::function proc) noexcept { - return std::unique_ptr(new Fiber(std::move(proc))); -} - -Fiber::Fiber(std::function proc) - : id_(internal::IndexAlloc::For()->Next()), - data_(object_pool::Get().Leak()) { - TILE_CHECK(proc); - - data_->proc = std::move(proc); - ctx_ = CreateFiber(&data_->stack, kStackSize, &data_->proc); -} - -Fiber::~Fiber() { - if (data_) { - object_pool::Put(data_.release()); - } - internal::IndexAlloc::For()->Free(id_); -} - -void Fiber::Resume() { - auto caller = GetCurrentFiber(); - TILE_CHECK_NE(caller, this, "Calling `Resume()`, on self is undefined."); - - SetUpCurrentFiber(this); - - auto t = jump_fcontext(internal::Exchange(ctx_, nullptr), caller); - - if (auto from = reinterpret_cast(t.data)) { - from->ctx_ = t.fctx; - } - - SetUpCurrentFiber(caller); -} - -void Fiber::ResumeOn(std::function &&cb) noexcept { - auto caller = GetCurrentFiber(); - TILE_CHECK_NE(caller, this, "Calling `ResumeOn()`, on self is undefined."); - SetUpCurrentFiber(this); - auto t = ontop_fcontext(ctx_, this, FiberOnTop); - caller = reinterpret_cast(t.data); - SetUpCurrentFiber(caller); -} - -std::string ToString(const Fiber &fiber) noexcept { return ToString(&fiber); } -std::string ToString(const std::unique_ptr &fiber) noexcept { - return ToString(fiber.get()); -} -std::string ToString(Fiber const *const fiber) noexcept { - if (TILE_UNLIKELY(fiber == nullptr)) { - return "Fiber(nullptr)"; - } - return Format("Fiber({})[{}]", fiber->id(), fmt::ptr(fiber)); -} - -} // namespace detail -} // namespace fiber - -template <> struct PoolTraits { - static constexpr auto kType = PoolType::MemoryNodeShared; - static constexpr std::size_t kLowWaterMark = 128; - static constexpr std::size_t kHighWaterMark = - std::numeric_limits::max(); - static constexpr std::chrono::seconds kMaxIdle = std::chrono::seconds(10); - static constexpr std::size_t kMinimumThreadCacheSize = 64; - static constexpr std::size_t kTransferBatchSize = 16; -}; - -constexpr PoolType PoolTraits::kType; -constexpr std::size_t - PoolTraits::kLowWaterMark; -constexpr std::size_t - PoolTraits::kHighWaterMark; -constexpr std::chrono::seconds - PoolTraits::kMaxIdle; -constexpr std::size_t - PoolTraits::kMinimumThreadCacheSize; -constexpr std::size_t - PoolTraits::kTransferBatchSize; - -} // namespace tile diff --git a/tile/fiber/detail/fiber.h b/tile/fiber/detail/fiber.h deleted file mode 100644 index b775abb..0000000 --- a/tile/fiber/detail/fiber.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef TILE_FIBER_DETAIL_FIBER_H -#define TILE_FIBER_DETAIL_FIBER_H - -#pragma once - -#include "tile/base/align.h" -#include "tile/base/internal/test_prod.h" -#include "tile/base/object_pool.h" -#include "tile/base/ref_ptr.h" -#include - -struct tile_ucontext_t; -// struct fcontext_transfer; -typedef struct fcontext_transfer fcontext_transfer_t; - -namespace tile { -namespace fiber { -namespace detail { - -class Scheduler; - -enum class FiberState { - Runnable, - Running, - Waiting, - Terminated, -}; -std::string ToString(const FiberState &state) noexcept; -std::ostream &operator<<(std::ostream &os, const FiberState &state) noexcept; - -class Scheduler; - -class alignas(hardware_destructive_interference_size) Fiber { -public: - using Id = std::uint64_t; - - static std::unique_ptr - Create(std::function proc = nullptr) noexcept; - - ~Fiber(); - - Fiber(const Fiber &) = delete; - Fiber &operator=(const Fiber &) = delete; - Fiber(Fiber &&other) noexcept = default; - Fiber &operator=(Fiber &&other) noexcept = default; - - void Resume(); - void ResumeOn(std::function &&cb) noexcept; - void Yield(); - Id id() const noexcept { return id_; } - FiberState state() const noexcept { return state_; } - - Scheduler *scheduler() const { return scheduler_; } - -private: - TILE_FRIEND_TEST(Fiber, Base); - friend Scheduler; - struct FiberContext; - friend class ::tile::PoolTraits; - - friend void FiberEntry(fcontext_transfer_t); - friend fcontext_transfer_t FiberOnTop(fcontext_transfer_t); - - Fiber(std::function proc = nullptr); - -private: - Id id_; - - std::unique_ptr data_; - FiberState state_{FiberState::Runnable}; - - void *ctx_{nullptr}; - - // for scheduler - Scheduler *scheduler_{nullptr}; -}; -Fiber *GetCurrentFiber() noexcept; -Fiber *GetMasterFiber() noexcept; - -void SetUpCurrentFiber(Fiber *fiber) noexcept; -void SetUpMasterFiber(Fiber *fiber) noexcept; - -inline bool IsFiberContext() noexcept { return GetCurrentFiber() != nullptr; } - -std::string ToString(Fiber const *const fiber) noexcept; -std::string ToString(const std::unique_ptr &fiber) noexcept; -std::string ToString(const Fiber &fiber) noexcept; - -} // namespace detail -} // namespace fiber -} // namespace tile - -#endif // TILE_FIBER_DETAIL_FIBER_H diff --git a/tile/fiber/detail/fiber_benchmark.cc b/tile/fiber/detail/fiber_benchmark.cc deleted file mode 100644 index 659b22e..0000000 --- a/tile/fiber/detail/fiber_benchmark.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include "tile/base/chrono.h" -#include "tile/base/random.h" -#include "tile/fiber/detail/fiber.h" - -#include "benchmark/benchmark.h" -namespace tile { -namespace fiber { -namespace detail { - -void Benchmark_FiberSwitch(benchmark::State &state) { - constexpr int kFiberCount = 2 * 10000; - std::unique_ptr master; - std::unique_ptr worker[kFiberCount]; - - int cnt = 0; - - master = Fiber::Create([&]() { - while (state.KeepRunning()) { - ++cnt; - auto &w1 = worker[Random(kFiberCount - 1)]; - auto &w2 = worker[Random(kFiberCount - 1)]; - auto start = ReadSteadyClock(); - w1->Resume(); - w2->Resume(); - w1->Resume(); - w2->Resume(); - w1->Resume(); - w2->Resume(); - w1->Resume(); - w2->Resume(); - auto end = ReadSteadyClock(); - auto duration = std::chrono::duration_cast>( - end - start) / - 8; - state.SetIterationTime(duration.count()); - } - - cnt = -1; - for (int i = 0; i != kFiberCount; ++i) { - worker[i]->Resume(); - } - }); - - for (int i = 0; i != kFiberCount; ++i) { - worker[i] = Fiber::Create([&, i]() { - while (cnt != -1) { - master->Resume(); - master->Resume(); - master->Resume(); - master->Resume(); - } - }); - } - - SetUpMasterFiber(master.get()); - SetUpCurrentFiber(nullptr); - - master->Resume(); -} - -BENCHMARK(Benchmark_FiberSwitch)->UseManualTime(); -} // namespace detail -} // namespace fiber -} // namespace tile diff --git a/tile/fiber/detail/scheduler.cc b/tile/fiber/detail/scheduler.cc deleted file mode 100644 index 7d4c719..0000000 --- a/tile/fiber/detail/scheduler.cc +++ /dev/null @@ -1,44 +0,0 @@ -#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::Terminated, - "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(); - - TILE_CHECK(self, "self fiber is nullptr."); - TILE_CHECK(master, "Master fiber is not set."); - master->state_ = FiberState::Runnable; - self->state_ = FiberState::Running; - SwitchTo(self, master); -} - -void Scheduler::Halt(Fiber *self) { - TILE_CHECK_EQ(self, GetCurrentFiber(), "Fiber is not current fiber."); - TILE_CHECK(self->state() == FiberState::Running, "Fiber is not running."); - - auto master = GetMasterFiber(); - self->state_ = FiberState::Waiting; - - master->Resume(); - - TILE_CHECK_EQ(self, GetCurrentFiber()); -} - -} // namespace detail -} // namespace fiber -} // namespace tile diff --git a/tile/fiber/detail/scheduler.h b/tile/fiber/detail/scheduler.h deleted file mode 100644 index 594c695..0000000 --- a/tile/fiber/detail/scheduler.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef TILE_FIBER_DETAIL_SCHEDULER_H -#define TILE_FIBER_DETAIL_SCHEDULER_H - -#pragma once - -#include "tile/fiber/detail/fiber.h" - -namespace tile { -namespace fiber { -namespace detail { - -class Scheduler { -public: - static Scheduler *Current() noexcept; - - void SwitchTo(Fiber *self, Fiber *to); - void Yield(Fiber *self); - void Halt(Fiber *self); -}; -} // namespace detail -} // namespace fiber -} // namespace tile - -#endif // TILE_FIBER_DETAIL_SCHEDULER_H diff --git a/tile/fiber/detail/scheduler_test.cc b/tile/fiber/detail/scheduler_test.cc deleted file mode 100644 index 84a0a1f..0000000 --- a/tile/fiber/detail/scheduler_test.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include "tile/fiber/detail/scheduler.h" - -#include "tile/base/deferred.h" - -#include "tile/base/random.h" -#include "gtest/gtest.h" - -namespace tile { -namespace fiber { -namespace detail { - -TEST(Fiber, Resume) { - constexpr int kFiberCount = 1000; - constexpr int kSwitchCount = 1000 * 1000; - - std::unique_ptr master; - std::unique_ptr worker[kFiberCount]; - - int cnt = 0; - auto end_check = tile::Deferred([&]() { ASSERT_EQ(cnt, kSwitchCount); }); - - master = Fiber::Create([&]() { - while (cnt < kSwitchCount) { - ASSERT_EQ(GetCurrentFiber(), master.get()); - worker[Random(kFiberCount - 1)]->Resume(); - ASSERT_EQ(GetCurrentFiber(), master.get()); - } - - for (int i = 0; i != kFiberCount; ++i) { - worker[i]->Resume(); - } - }); - for (int i = 0; i != kFiberCount; ++i) { - worker[i] = Fiber::Create([&, i]() { - while (cnt < kSwitchCount) { - ++cnt; - ASSERT_EQ(GetCurrentFiber(), worker[i].get()); - master->Resume(); - ASSERT_EQ(GetCurrentFiber(), worker[i].get()); - } - }); - } - - SetUpMasterFiber(master.get()); - SetUpCurrentFiber(nullptr); - master->Resume(); - ASSERT_EQ(cnt, kSwitchCount); - for (int i = 0; i != kFiberCount; ++i) { - ASSERT_EQ(worker[i]->state(), FiberState::Terminated); - } -} - -} // namespace detail -} // namespace fiber -} // namespace tile diff --git a/tile/fiber/detail/waitable.cc b/tile/fiber/detail/waitable.cc deleted file mode 100644 index eba155e..0000000 --- a/tile/fiber/detail/waitable.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "tile/fiber/detail/waitable.h" -#include "tile/base/thread/scoped_lock.h" - -namespace tile { -namespace fiber { -namespace detail { -WaitList::WaitList() {} -WaitList::~WaitList() {} - -bool WaitList::AddWaiter(WaitListNode *node) { - ScopedLock _(lock_); - TILE_CHECK(node->waiter); - - waiters_.push_back(node); - return true; -} - -Fiber *WaitList::WakeOne() { - ScopedLock _(lock_); - while (true) { - if (waiters_.empty()) { - return nullptr; - } - - WaitListNode *waiter = waiters_.front(); - waiters_.pop_front(); - if (!waiter) { - return nullptr; - } - - if (waiter->satisfied.exchange(true, std::memory_order_relaxed)) { - continue; - ; - } - - return waiter->waiter; - } -} - -} // namespace detail -} // namespace fiber -} // namespace tile diff --git a/tile/fiber/detail/waitable.h b/tile/fiber/detail/waitable.h deleted file mode 100644 index 2bb04cd..0000000 --- a/tile/fiber/detail/waitable.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef TILE_FIBER_DETAIL_WAITABLE_H -#define TILE_FIBER_DETAIL_WAITABLE_H - -#pragma once - -#include "tile/base/internal/singly_linked_list.h" -#include "tile/base/thread/spinlock.h" - -#include - -namespace tile { -namespace fiber { -namespace detail { - -class Fiber; -class Scheduler; - -struct WaitListNode { - Fiber *waiter = nullptr; - tile::internal::SinglyLinkedListEntry chain; - std::atomic satisfied{false}; -}; - -class WaitList { -public: - WaitList(); - ~WaitList(); - - bool AddWaiter(WaitListNode *node); - // Remove the waiter from the list. - // return true if the waiter is removed, otherwise return nullptr. - Fiber *WakeOne(); - - WaitList(const WaitList &) = delete; - WaitList &operator=(const WaitList &) = delete; - -private: - Spinlock lock_; - std::list waiters_; - // tile::internal::SinglyLinkedList - // waiters_; -}; - -} // namespace detail -} // namespace fiber -} // namespace tile - -#endif // TILE_FIBER_DETAIL_WAITABLE_H diff --git a/tile/fiber/mutex.cc b/tile/fiber/mutex.cc deleted file mode 100644 index 9e0687e..0000000 --- a/tile/fiber/mutex.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "tile/fiber/mutex.h" -// #include "tile/base/thread/scoped_lock.h" -#include "tile/base/thread/unique_lock.h" -#include "tile/fiber/detail/os_fiber.h" - -namespace tile { -namespace fiber { -void Mutex::Lock() { - TILE_DCHECK(detail::IsFiberEnv()); - if (TILE_LIKELY(TryLock())) { - return; - } - LockSlow(); -} -bool Mutex::TryLock() { - TILE_DCHECK(detail::IsFiberEnv()); - std::uint32_t expected = 0; - return count_.compare_exchange_strong(expected, 1, std::memory_order_acquire); -} -void Mutex::Unlock() { - TILE_CHECK(detail::IsFiberEnv()); - auto was = count_.fetch_sub(1, std::memory_order_release); - if (was == 1) { - // lock success. - } else { - TILE_CHECK_GT(was, 1); - - UniqueLock splk(slow_path_lock_); - splk.Unlock(); - } -} -void Mutex::LockSlow() { - TILE_DCHECK(detail::IsFiberEnv()); - if (TryLock()) { - // lock success. - return; - } - - UniqueLock splk(slow_path_lock_); - if (count_.fetch_add(1, std::memory_order_acquire) == 0) { - // lock success. - return; - } - - auto current = detail::OSFiber::Current(); -} - -} // namespace fiber -} // namespace tile diff --git a/tile/fiber/this_fiber.cc b/tile/fiber/this_fiber.cc deleted file mode 100644 index 5cd3d72..0000000 --- a/tile/fiber/this_fiber.cc +++ /dev/null @@ -1,24 +0,0 @@ -#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."); - return self->id(); -} -} // namespace this_fiber -} // namespace tile diff --git a/tile/fiber/this_fiber.h b/tile/fiber/this_fiber.h deleted file mode 100644 index ba0c46a..0000000 --- a/tile/fiber/this_fiber.h +++ /dev/null @@ -1,29 +0,0 @@ -#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 -void SleepFor(std::chrono::time_point expires_at) { - SleepUntil(ReadSteadyClock() + (expires_at - Clock::now())); -} - -template -void SleepFor(std::chrono::duration expires_in) { - return SleepFor(static_cast(expires_in)); -} - -Fiber::Id GetId(); - -} // namespace this_fiber -} // namespace tile diff --git a/tile/fiber/ucontext_test.cc b/tile/fiber/ucontext_test.cc deleted file mode 100644 index 9d9b93a..0000000 --- a/tile/fiber/ucontext_test.cc +++ /dev/null @@ -1,54 +0,0 @@ -#define _XOPEN_SOURCE 600 -extern "C" { -#include -} -#include "tile/base/logging.h" -#include "gtest/gtest.h" - -static int call_id = 0; -char stack1[8192]; -char stack2[8192]; - -static void f1() { - EXPECT_EQ(call_id, 0); - call_id = 1; -} -static void f2() { - EXPECT_EQ(call_id, 1); - call_id = 2; -} - -// 0 -> main fiber -// 1 -> f1 -// 2 -> f2 -static ucontext_t ctx[3]; - -void SetCtx1() {} - -void SetCtx2() {} - -TEST(Ucontext, Ucontext) { - - memset(&ctx, 0, sizeof(ctx)); - getcontext(&ctx[0]); - for (int i = 0; i != 1000; ++i) { - - getcontext(&ctx[1]); - ctx[1].uc_stack.ss_sp = stack1; - ctx[1].uc_stack.ss_size = sizeof(stack1); - ctx[1].uc_link = &ctx[0]; - makecontext(&ctx[1], f1, 0); - - getcontext(&ctx[2]); - ctx[2].uc_stack.ss_sp = stack2; - ctx[2].uc_stack.ss_size = sizeof(stack2); - ctx[2].uc_link = &ctx[0]; - makecontext(&ctx[2], f2, 0); - - call_id = 0; - swapcontext(&ctx[0], &ctx[1]); - EXPECT_EQ(call_id, 1); - swapcontext(&ctx[0], &ctx[2]); - EXPECT_EQ(call_id, 2); - } -} diff --git a/tile/net/internal/http_engine_test.cc b/tile/net/internal/http_engine_test.cc index c6fe7dd..d3e34bb 100644 --- a/tile/net/internal/http_engine_test.cc +++ b/tile/net/internal/http_engine_test.cc @@ -75,6 +75,7 @@ public: void SetUp() override { site_url_ = "http://example.com/"; } std::string site_url_; }; + TEST_F(HttpEngineTest, Basic) { HttpTask t; t.SetMethod(HttpMethod::Get);