Skip to content

Commit

Permalink
make cross-vcpu interrupt latency lower, by more frequent checking of…
Browse files Browse the repository at this point in the history
… standby queue. (alibaba#625)
  • Loading branch information
lihuiba authored Nov 25, 2024
1 parent 1941a4d commit 9712349
Showing 1 changed file with 17 additions and 18 deletions.
35 changes: 17 additions & 18 deletions thread/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ namespace photon
this->node = head;
}
thread* eject_whole_atomic() {
if (!node) return nullptr;
SCOPED_LOCK(lock);
auto p = node;
node = nullptr;
Expand Down Expand Up @@ -1071,24 +1072,26 @@ R"(
#endif
}
static uint32_t last_tsc = 0;
static inline void if_update_now(bool accurate = false) {
static inline bool if_update_now(bool accurate = false) {
#if defined(__x86_64__) && defined(__linux__) && defined(ENABLE_MIMIC_VDSO)
if (likely(__mimic_vdso_time_x86)) {
return photon::now = __mimic_vdso_time_x86.get_now(accurate);
}
#endif
if (likely(ts_updater.load(std::memory_order_relaxed))) {
return;
return true;
}
if (unlikely(accurate)) {
update_now();
return;
return true;
}
uint32_t tsc = _rdtsc();
if (unlikely(last_tsc != tsc)) {
last_tsc = tsc;
update_now();
return true;
}
return false;
}
NowTime __update_now() {
last_tsc = _rdtsc();
Expand Down Expand Up @@ -1141,10 +1144,10 @@ R"(
}
return count;
}

if_update_now();
while(!sleepq.empty())
{
if (sleepq.empty() || !if_update_now()) {
return count;
}
do {
auto th = sleepq.front();
if (th->ts_wakeup > now) break;
SCOPED_LOCK(th->lock);
Expand All @@ -1154,7 +1157,7 @@ R"(
AtomicRunQ().insert_tail(th);
count++;
}
}
} while(!sleepq.empty());
return count;
}

Expand Down Expand Up @@ -1781,18 +1784,16 @@ R"(
void reset_master_event_engine_default() {
CURRENT->get_vcpu()->reset_master_event_engine_default();
}
static void* idle_stub(void*)
{
static void* idler(void*) {
RunQ rq;
auto last_idle = now;
auto vcpu = rq.current->get_vcpu();
while (vcpu->state != states::DONE) {
while (!AtomicRunQ(rq).single()) {
while (resume_threads() > 0 || !AtomicRunQ(rq).single()) {
thread_yield();
if (unlikely(sat_sub(now, last_idle) >= 1000UL)) {
last_idle = now;
vcpu->master_event_engine->wait_and_fire_events(0);
resume_threads();
}
}
if (vcpu->state == states::DONE)
Expand All @@ -1802,12 +1803,10 @@ R"(
// fall in actual sleep
auto usec = 10 * 1024 * 1024; // max
auto& sleepq = vcpu->sleepq;
if (!sleepq.empty())
usec = min(usec,
sat_sub(sleepq.front()->ts_wakeup, now));
if (!sleepq.empty()) usec = min(usec,
sat_sub(sleepq.front()->ts_wakeup, now));
last_idle = now;
vcpu->master_event_engine->wait_and_fire_events(usec);
resume_threads();
}
return nullptr;
}
Expand Down Expand Up @@ -1899,7 +1898,7 @@ R"(
th->state = states::RUNNING;
th->init_main_thread_stack();
auto vcpu = new (ptr) vcpu_t;
vcpu->idle_worker = thread_create(&idle_stub, nullptr);
vcpu->idle_worker = thread_create(&idler, nullptr);
thread_enable_join(vcpu->idle_worker);
if_update_now(true);
return ++_n_vcpu;
Expand All @@ -1914,7 +1913,7 @@ R"(
auto vcpu = rq.current->get_vcpu();
wait_all(rq, vcpu);
assert(!AtomicRunQ(rq).single());
assert(vcpu->nthreads == 2); // idle_stub & current alive
assert(vcpu->nthreads == 2); // idler & current alive
vcpu->state = states::DONE; // instruct idle_worker to exit
thread_join(vcpu->idle_worker);
rq.current->state = states::DONE;
Expand Down

0 comments on commit 9712349

Please sign in to comment.