Skip to content

Commit

Permalink
BugFix: to avoid infinite loop in kNanosecondsPerUnit initialization …
Browse files Browse the repository at this point in the history
…in x86 arch (#97)

- use rdtsc instruction instead of __rdtsc function to get tsc in x86 arch
- support fiber primitive for ExitBarrier, to allow Fiber.Join in pthread context and fiber context
  • Loading branch information
hzlushiliang authored Dec 28, 2023
1 parent 8dcc565 commit 5361895
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 6 deletions.
1 change: 1 addition & 0 deletions trpc/coroutine/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class Fiber {
void Detach();

/// @brief Wait for the fiber to exit.
/// @note Can be run in both pthread context and fiber context.
void Join();

/// @brief Test if we can call `join()` on this object.
Expand Down
4 changes: 0 additions & 4 deletions trpc/runtime/threadmodel/fiber/detail/waitable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,10 @@ void ConditionVariable::notify_all() noexcept {
ExitBarrier::ExitBarrier() : count_(1) {}

std::unique_lock<Mutex> ExitBarrier::GrabLock() {
TRPC_DCHECK(IsFiberContextPresent());
return std::unique_lock(lock_);
}

void ExitBarrier::UnsafeCountDown(std::unique_lock<Mutex> lk) {
TRPC_DCHECK(IsFiberContextPresent());
TRPC_CHECK(lk.owns_lock() && lk.mutex() == &lock_);

// tsan reports a data race if we unlock the lock before notifying the
Expand All @@ -421,8 +419,6 @@ void ExitBarrier::UnsafeCountDown(std::unique_lock<Mutex> lk) {
}

void ExitBarrier::Wait() {
TRPC_DCHECK(IsFiberContextPresent());

std::unique_lock lk(lock_);
return cv_.wait(lk, [this] { return count_ == 0; });
}
Expand Down
2 changes: 1 addition & 1 deletion trpc/runtime/threadmodel/fiber/detail/waitable.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ class ExitBarrier : public object_pool::EnableLwSharedFromThis<ExitBarrier> {
// Count down the barrier's internal counter and wake up waiters.
void UnsafeCountDown(std::unique_lock<Mutex> lk);

// Won't block.
// Won't block, can be run in both pthread context and fiber context.
void Wait();

void Reset() { count_ = 1; }
Expand Down
7 changes: 6 additions & 1 deletion trpc/util/chrono/tsc.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ std::pair<std::chrono::steady_clock::time_point, std::uint64_t> ReadConsistentTi
/// use `std::steady_clock` instead. TSC is suitable for situations where
/// accuracy can be trade for speed.
#if defined(__x86_64__) || defined(__MACHINEX86_X64)
inline std::uint64_t ReadTsc() { return __rdtsc(); }
inline std::uint64_t ReadTsc() {
unsigned int lo = 0;
unsigned int hi = 0;
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return ((uint64_t)hi << 32) | lo;
}
#elif defined(__aarch64__)
inline std::uint64_t ReadTsc() {
// Sub-100MHz resolution (exactly 100MHz in our environment), not as accurate
Expand Down

0 comments on commit 5361895

Please sign in to comment.