remove td::this_thread::yield function. usleep_for(1) used instead
This commit is contained in:
parent
b8bd39dc6f
commit
7ddc3099f6
@ -51,7 +51,7 @@ class Backoff {
|
||||
if (cnt < 50) {
|
||||
return true;
|
||||
} else {
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
return cnt < 500;
|
||||
}
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ Status NetQueryDispatcher::wait_dc_init(DcId dc_id, bool force) {
|
||||
return Status::Error("Closing");
|
||||
}
|
||||
#if !TD_THREAD_UNSUPPORTED
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/type_traits.h"
|
||||
|
||||
@ -20,6 +21,15 @@ template <class T>
|
||||
class AtomicRead {
|
||||
public:
|
||||
void read(T &dest) const {
|
||||
int it = 0;
|
||||
const int wait_each_it = 4;
|
||||
auto wait = [&]() {
|
||||
it++;
|
||||
if (it % wait_each_it == 0) {
|
||||
usleep_for(1);
|
||||
}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
static_assert(TD_IS_TRIVIALLY_COPYABLE(T), "T must be trivially copyable");
|
||||
auto version_before = version.load();
|
||||
@ -30,7 +40,7 @@ class AtomicRead {
|
||||
break;
|
||||
}
|
||||
}
|
||||
td::this_thread::yield();
|
||||
wait();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/HazardPointers.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/ScopeGuard.h"
|
||||
|
||||
@ -305,7 +306,7 @@ class MpmcQueueOld {
|
||||
if (try_pop(value, thread_id)) {
|
||||
return value;
|
||||
}
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,7 +430,7 @@ class MpmcQueue {
|
||||
if (try_pop(value, thread_id)) {
|
||||
return value;
|
||||
}
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -29,16 +30,17 @@ class MpmcEagerWaiter {
|
||||
slot.yields = 0;
|
||||
slot.worker_id = worker_id;
|
||||
}
|
||||
|
||||
void wait(Slot &slot) {
|
||||
if (slot.yields < RoundsTillSleepy) {
|
||||
td::this_thread::yield();
|
||||
yield();
|
||||
slot.yields++;
|
||||
} else if (slot.yields == RoundsTillSleepy) {
|
||||
auto state = state_.load(std::memory_order_relaxed);
|
||||
if (!State::has_worker(state)) {
|
||||
auto new_state = State::with_worker(state, slot.worker_id);
|
||||
if (state_.compare_exchange_strong(state, new_state, std::memory_order_acq_rel)) {
|
||||
td::this_thread::yield();
|
||||
yield();
|
||||
slot.yields++;
|
||||
return;
|
||||
}
|
||||
@ -47,12 +49,12 @@ class MpmcEagerWaiter {
|
||||
return;
|
||||
}
|
||||
}
|
||||
td::this_thread::yield();
|
||||
yield();
|
||||
slot.yields = 0;
|
||||
} else if (slot.yields < RoundsTillAsleep) {
|
||||
auto state = state_.load(std::memory_order_acquire);
|
||||
if (State::still_sleepy(state, slot.worker_id)) {
|
||||
td::this_thread::yield();
|
||||
yield();
|
||||
slot.yields++;
|
||||
return;
|
||||
}
|
||||
@ -121,6 +123,10 @@ class MpmcEagerWaiter {
|
||||
condition_variable_.notify_all();
|
||||
}
|
||||
}
|
||||
static void yield() {
|
||||
// whatever, this is better than sched_yield
|
||||
usleep_for(1);
|
||||
}
|
||||
};
|
||||
|
||||
class MpmcSleepyWaiter {
|
||||
@ -208,7 +214,7 @@ class MpmcSleepyWaiter {
|
||||
}
|
||||
if (slot.state_ == Slot::Search) {
|
||||
if (slot.yield_cnt++ < 10 && false) {
|
||||
td::this_thread::yield();
|
||||
// TODO some sleep backoff is possible
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
|
||||
#include <atomic>
|
||||
@ -30,7 +31,7 @@ class SpinLock {
|
||||
//TODO pause
|
||||
return true;
|
||||
} else {
|
||||
td::this_thread::yield();
|
||||
usleep_for(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -88,9 +88,6 @@ int ThreadPthread::do_pthread_create(pthread_t *thread, const pthread_attr_t *at
|
||||
}
|
||||
|
||||
namespace this_thread_pthread {
|
||||
void yield() {
|
||||
sched_yield();
|
||||
}
|
||||
ThreadPthread::id get_id() {
|
||||
return pthread_self();
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ class ThreadPthread {
|
||||
};
|
||||
|
||||
namespace this_thread_pthread {
|
||||
void yield();
|
||||
ThreadPthread::id get_id();
|
||||
} // namespace this_thread_pthread
|
||||
} // namespace detail
|
||||
|
@ -70,7 +70,9 @@ class ThreadStl {
|
||||
return std::forward<T>(v);
|
||||
}
|
||||
};
|
||||
namespace this_thread_stl = std::this_thread;
|
||||
namespace this_thread_stl {
|
||||
using std::this_thread::get_id;
|
||||
} // namespace this_thread_stl
|
||||
} // namespace detail
|
||||
} // namespace td
|
||||
|
||||
|
@ -32,7 +32,7 @@ class Backoff {
|
||||
if (cnt < 1) { // 50
|
||||
return true;
|
||||
} else {
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
return cnt < 3; // 500
|
||||
}
|
||||
}
|
||||
@ -47,7 +47,7 @@ class InfBackoff {
|
||||
if (cnt < 50) {
|
||||
return true;
|
||||
} else {
|
||||
td::this_thread::yield();
|
||||
td::usleep_for(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,14 @@
|
||||
#include "td/utils/Context.h"
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/port/sleep.h"
|
||||
#include "td/utils/port/thread.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
@ -126,12 +128,12 @@ class RegisterTest {
|
||||
}
|
||||
};
|
||||
|
||||
class Stage {
|
||||
class StageWait {
|
||||
public:
|
||||
void wait(uint64 need) {
|
||||
value_.fetch_add(1, std::memory_order_release);
|
||||
while (value_.load(std::memory_order_acquire) < need) {
|
||||
td::this_thread::yield();
|
||||
usleep_for(1);
|
||||
}
|
||||
};
|
||||
|
||||
@ -139,6 +141,26 @@ class Stage {
|
||||
std::atomic<uint64> value_{0};
|
||||
};
|
||||
|
||||
class StageMutex {
|
||||
public:
|
||||
void wait(uint64 need) {
|
||||
std::unique_lock<std::mutex> lock{mutex_};
|
||||
value_++;
|
||||
if (value_ == need) {
|
||||
cond_.notify_all();
|
||||
return;
|
||||
}
|
||||
cond_.wait(lock, [&] { return value_ >= need; });
|
||||
};
|
||||
|
||||
private:
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cond_;
|
||||
uint64 value_{0};
|
||||
};
|
||||
|
||||
using Stage = StageMutex;
|
||||
|
||||
string rand_string(int from, int to, size_t len);
|
||||
|
||||
vector<string> rand_split(Slice str);
|
||||
|
Loading…
x
Reference in New Issue
Block a user