Skip to content

Commit 5361895

Browse files
authored
BugFix: to avoid infinite loop in kNanosecondsPerUnit initialization 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
1 parent 8dcc565 commit 5361895

File tree

4 files changed

+8
-6
lines changed

4 files changed

+8
-6
lines changed

trpc/coroutine/fiber.h

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ class Fiber {
122122
void Detach();
123123

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

127128
/// @brief Test if we can call `join()` on this object.

trpc/runtime/threadmodel/fiber/detail/waitable.cc

-4
Original file line numberDiff line numberDiff line change
@@ -401,12 +401,10 @@ void ConditionVariable::notify_all() noexcept {
401401
ExitBarrier::ExitBarrier() : count_(1) {}
402402

403403
std::unique_lock<Mutex> ExitBarrier::GrabLock() {
404-
TRPC_DCHECK(IsFiberContextPresent());
405404
return std::unique_lock(lock_);
406405
}
407406

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

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

423421
void ExitBarrier::Wait() {
424-
TRPC_DCHECK(IsFiberContextPresent());
425-
426422
std::unique_lock lk(lock_);
427423
return cv_.wait(lk, [this] { return count_ == 0; });
428424
}

trpc/runtime/threadmodel/fiber/detail/waitable.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class ExitBarrier : public object_pool::EnableLwSharedFromThis<ExitBarrier> {
248248
// Count down the barrier's internal counter and wake up waiters.
249249
void UnsafeCountDown(std::unique_lock<Mutex> lk);
250250

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

254254
void Reset() { count_ = 1; }

trpc/util/chrono/tsc.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ std::pair<std::chrono::steady_clock::time_point, std::uint64_t> ReadConsistentTi
5959
/// use `std::steady_clock` instead. TSC is suitable for situations where
6060
/// accuracy can be trade for speed.
6161
#if defined(__x86_64__) || defined(__MACHINEX86_X64)
62-
inline std::uint64_t ReadTsc() { return __rdtsc(); }
62+
inline std::uint64_t ReadTsc() {
63+
unsigned int lo = 0;
64+
unsigned int hi = 0;
65+
asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
66+
return ((uint64_t)hi << 32) | lo;
67+
}
6368
#elif defined(__aarch64__)
6469
inline std::uint64_t ReadTsc() {
6570
// Sub-100MHz resolution (exactly 100MHz in our environment), not as accurate

0 commit comments

Comments
 (0)