feat/support_fiber #2

Merged
tqcq merged 57 commits from feat/support_fiber into master 2024-06-21 10:33:52 +08:00
13 changed files with 27 additions and 281 deletions
Showing only changes of commit 0dce11b0dd - Show all commits

View File

@ -164,7 +164,6 @@ set(TILE_SRCS
# "tile/fiber/detail/os_fiber.cc" "tile/fiber/detail/posix_os_fiber.cc"
# "tile/fiber/detail/mutex.cc"
"tile/fiber/detail/ucontext.c"
"tile/fiber/scheduler.cc"
"tile/io/detail/eintr_safe.cc"
"tile/io/native/acceptor.cc"
"tile/io/descriptor.cc"

View File

@ -1,17 +1,7 @@
// Copyright 2021 The Marl Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS32_H
#define TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS32_H
#pragma once
#define TILE_REG_f20 0x00
#define TILE_REG_f22 0x08
#define TILE_REG_f24 0x10
@ -129,3 +119,5 @@ static_assert(offsetof(tile_ucontext_t, ra) == TILE_REG_ra,
#endif // __cplusplus
#endif // TILE_BUILD_ASM
#endif // TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS32_H

View File

@ -1,17 +1,7 @@
// Copyright 2020 The Marl Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS64_H
#define TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS64_H
#pragma once
#define TILE_REG_a0 0x00
#define TILE_REG_a1 0x08
#define TILE_REG_s0 0x10
@ -129,3 +119,5 @@ static_assert(offsetof(tile_ucontext_t, ra) == TILE_REG_ra,
#endif // __cplusplus
#endif // TILE_BUILD_ASM
#endif // TILE_FIBER_DETAIL_ASM_UCONTEXT_MIPS64_H

View File

@ -1,5 +1,5 @@
#ifndef TILE_FIBER_DETAIL_UCONTEXT_RISCV64_H
#define TILE_FIBER_DETAIL_UCONTEXT_RISCV64_H
#ifndef TILE_FIBER_DETAIL_ASM_UCONTEXT_RISCV64_H
#define TILE_FIBER_DETAIL_ASM_UCONTEXT_RISCV64_H
#pragma once
#define TILE_REG_a0 0x00
@ -138,4 +138,4 @@ static_assert(offsetof(tile_ucontext_t, ra) == TILE_REG_ra,
#endif // TILE_BUILD_ASM
#endif // TILE_FIBER_DETAIL_UCONTEXT_RISCV64_H
#endif // TILE_FIBER_DETAIL_ASM_UCONTEXT_RISCV64_H

View File

@ -1,17 +1,7 @@
// Copyright 2019 The Marl Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef TILE_FIBER_DETAIL_ASM_UCONTEXT_X64_H
#define TILE_FIBER_DETAIL_ASM_UCONTEXT_X64_H
#pragma once
#define TILE_REG_RBX 0x00
#define TILE_REG_RBP 0x08
#define TILE_REG_R12 0x10
@ -81,3 +71,5 @@ static_assert(offsetof(tile_ucontext_t, RIP) == TILE_REG_RIP,
#endif // __cplusplus
#endif // TILE_BUILD_ASM
#endif // TILE_FIBER_DETAIL_ASM_UCONTEXT_X64_H

View File

@ -1,3 +1,7 @@
#ifndef TILE_FIBER_DETAIL_ASM_UCONTEXT_X86_H
#define TILE_FIBER_DETAIL_ASM_UCONTEXT_X86_H
#pragma once
#define TILE_REG_EBX 0x00
#define TILE_REG_EBP 0x04
#define TILE_REG_ESI 0x08
@ -44,3 +48,5 @@ static_assert(offsetof(tile_ucontext_t, EIP) == TILE_REG_EIP,
#endif // __cplusplus
#endif // TILE_BUILD_ASM
#endif // TILE_FIBER_DETAIL_ASM_UCONTEXT_X86_H

View File

@ -9,6 +9,7 @@ namespace detail {
TEST(Fiber, Base) {
constexpr auto kMaxCnt = 5000000;
int cnt = 0;
int resume_cnt = 0;
// 0 -> master fiber
// [1, 9] -> worker fibers
@ -33,9 +34,11 @@ TEST(Fiber, Base) {
auto next_fiber = fibers[Random(1, 9)].get();
next_fiber->Resume();
++resume_cnt;
ASSERT_EQ(old + 1, cnt);
ASSERT_EQ(Fiber::Current(), Fiber::MasterFiber());
}
ASSERT_EQ(resume_cnt, kMaxCnt);
}
} // namespace detail

View File

@ -1,3 +0,0 @@
#include "tile/fiber/detail/scheduler.h"

View File

@ -1,45 +0,0 @@
#ifndef TILE_FIBER_DETAIL_SCHEDULER_H
#define TILE_FIBER_DETAIL_SCHEDULER_H
#pragma once
#include "tile/base/thread/event.h"
#include "tile/base/thread/spinlock.h"
#include "tile/fiber/fiber.h"
#include <array>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <unordered_map>
namespace tile {
namespace fiber {
namespace detail {
class Fiber;
class Scheduler {
public:
static Scheduler *Current() noexcept;
void Yield(OSFiber *self) noexcept;
void Halt(OSFiber *self) noexcept;
void SwitchTo(OSFiber *self, OSFiber *to) noexcept;
void Queue(std::function<void()> task);
private:
OSFiber *StartFiber(std::function<void()> task);
Scheduler();
~Scheduler();
private:
Spinlock fibers_lock_;
std::list<std::function<void()>> tasks_;
Event new_task_event_;
};
} // namespace detail
} // namespace fiber
} // namespace tile
#endif // TILE_FIBER_DETAIL_SCHEDULER_H

View File

@ -1,54 +0,0 @@
#include "tile/fiber/fiber.h"
#include "tile/base/internal/index_alloc.h"
#include "tile/fiber/detail/os_fiber.h"
#include "gflags/gflags.h"
DEFINE_int32(tile_fiber_stack_size, 1024 * 1024, "Fiber stack size");
namespace tile {
namespace fiber {
namespace {
Fiber::Id AllocFiberId() noexcept {
return internal::IndexAlloc::For<Fiber>()->Next();
}
void FreeFiberId(Fiber::Id id) noexcept {
internal::IndexAlloc::For<Fiber>()->Free(id);
}
} // namespace
Fiber::Fiber()
: id_(AllocFiberId()), exit_latch_(std::make_shared<Latch>(1)),
impl_(detail::os_fiber_registry.New("os_fiber")) {}
Fiber::Fiber(Fiber &&) noexcept = default;
Fiber &Fiber::operator=(Fiber &&) noexcept = default;
Fiber::~Fiber() = default;
Fiber::Id Fiber::GetId() const { return id_; }
void Fiber::WorkerProc() {
TILE_LOG_INFO("Only display log");
FreeFiberId(id_);
exit_latch_->CountDown();
}
void Fiber::SwitchTo(Fiber *to) {
TILE_CHECK(to);
impl_->SwitchTo(to->impl_.get());
}
} // namespace fiber
} // namespace tile
namespace tile {
constexpr PoolType PoolTraits<tile::fiber::Fiber>::kType;
constexpr std::size_t PoolTraits<tile::fiber::Fiber>::kLowWaterMark;
constexpr std::size_t PoolTraits<tile::fiber::Fiber>::kHighWaterMark;
constexpr std::chrono::nanoseconds PoolTraits<tile::fiber::Fiber>::kMaxIdle;
constexpr std::size_t PoolTraits<tile::fiber::Fiber>::kMinimumThreadCacheSize;
constexpr std::size_t PoolTraits<tile::fiber::Fiber>::kTransferBatchSize;
} // namespace tile

View File

@ -1,75 +0,0 @@
#ifndef TILE_FIBER_FIBER_H
#define TILE_FIBER_FIBER_H
#pragma once
#include "tile/base/internal/test_prod.h"
#include "tile/base/object_pool.h"
#include "tile/base/thread/latch.h"
#include "gflags/gflags_declare.h"
DECLARE_int32(tile_fiber_stack_size);
namespace tile {
namespace fiber {
namespace detail {
class OSFiber;
} // namespace detail
} // namespace fiber
} // namespace tile
namespace tile {
namespace fiber {
class Scheduler;
class Fiber {
public:
using Id = std::uint64_t;
using Task = std::function<void()>;
enum class FiberState {
Ready, // No task
// Running, // Process task
Waiting, // Blocked
Terminated, // Terminated
};
Fiber(Fiber &&) noexcept;
Fiber &operator=(Fiber &&) noexcept;
~Fiber();
Id GetId() const;
void Yield();
private:
friend class ::tile::fiber::Scheduler;
TILE_FRIEND_TEST(Fiber, Base);
Fiber();
Fiber(Fiber *main_fiber);
void WorkerProc();
void SwitchTo(Fiber *to);
private:
Id id_;
std::shared_ptr<Latch> exit_latch_;
std::unique_ptr<::tile::fiber::detail::OSFiber> impl_{nullptr};
};
} // namespace fiber
} // namespace tile
namespace tile {
template <> struct PoolTraits<::tile::fiber::Fiber> {
static constexpr auto kType = PoolType::MemoryNodeShared;
static constexpr std::size_t kLowWaterMark = 32768;
static constexpr std::size_t kHighWaterMark =
std::numeric_limits<std::size_t>::max();
static constexpr std::chrono::nanoseconds kMaxIdle = std::chrono::seconds(5);
static constexpr std::size_t kMinimumThreadCacheSize = 8192;
static constexpr std::size_t kTransferBatchSize = 1024;
};
} // namespace tile
#endif // TILE_FIBER_FIBER_H

View File

@ -1,22 +0,0 @@
#include "tile/fiber/scheduler.h"
#include "tile/fiber/fiber.h"
namespace tile {
namespace fiber {
namespace detail {
static thread_local Scheduler *current_scheduler = nullptr;
}
Scheduler *Scheduler::Current() noexcept { return detail::current_scheduler; }
Scheduler::Scheduler(Options options) : options_(std::move(options)) {
detail::current_scheduler = this;
// main_fiber_ = std::make_unique<Fiber>();
// fibers_.reserve(options_.affinity.size());
// for (auto i : options_.affinity) {
// fibers_.push_back(std::make_unique<Fiber>());
// }
}
} // namespace fiber
} // namespace tile

View File

@ -1,39 +0,0 @@
#ifndef TILE_FIBER_DETAIL_SCHEDULER_H
#define TILE_FIBER_DETAIL_SCHEDULER_H
#pragma once
#include "tile/base/align.h"
#include "tile/fiber/fiber.h"
#include <vector>
namespace tile {
namespace fiber {
class alignas(hardware_destructive_interference_size) Scheduler {
public:
struct Options {
std::vector<int> affinity;
std::size_t fiber_stack_size = 1024 * 1024;
};
Scheduler(Options options);
~Scheduler();
static Scheduler *Current() noexcept;
private:
void WorkerProc();
private:
Options options_;
std::unique_ptr<Fiber> main_fiber_;
std::vector<std::unique_ptr<Fiber>> fibers_;
};
} // namespace fiber
} // namespace tile
#endif // TILE_FIBER_DETAIL_SCHEDULER_H