Commit 481a93de authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Move DeterministicSchedule TLState to the source

Summary: [Folly] Move `DeterministicSchedule` helper alias `TLState` to the source, and outline all uses into the source.

Reviewed By: nbronson, luciang

Differential Revision: D23157071

fbshipit-source-id: 957576a61a796f46da781e02419a1229e681d4c1
parent 0b3d9d21
......@@ -26,6 +26,7 @@
#include <utility>
#include <folly/Random.h>
#include <folly/SingletonThreadLocal.h>
namespace folly {
namespace test {
......@@ -116,6 +117,30 @@ void ThreadSyncVar::acq_rel() {
order_.sync(threadInfo.acqRelOrder_);
}
namespace {
struct PerThreadState {
// delete the constructors and assignment operators for sanity
//
// but... we can't delete the move constructor and assignment operators
// because those are required before C++17 in the implementation of
// SingletonThreadLocal
PerThreadState(const PerThreadState&) = delete;
PerThreadState& operator=(const PerThreadState&) = delete;
PerThreadState(PerThreadState&&) = default;
PerThreadState& operator=(PerThreadState&&) = default;
PerThreadState() = default;
Sem* sem{nullptr};
DeterministicSchedule* sched{nullptr};
bool exiting{false};
DSchedThreadId threadId{};
AuxAct aux_act{};
};
using TLState = SingletonThreadLocal<PerThreadState>;
} // namespace
DeterministicSchedule::DeterministicSchedule(
std::function<size_t(size_t)> scheduler)
: scheduler_(std::move(scheduler)), nextThreadId_(0), step_(0) {
......@@ -200,6 +225,27 @@ struct UniformSubset {
}
};
bool DeterministicSchedule::isCurrentThreadExiting() {
auto& tls = TLState::get();
return tls.exiting;
}
bool DeterministicSchedule::isActive() {
auto& tls = TLState::get();
return tls.sched != nullptr;
}
DSchedThreadId DeterministicSchedule::getThreadId() {
auto& tls = TLState::get();
assert(tls.sched != nullptr);
return tls.threadId;
}
DeterministicSchedule* DeterministicSchedule::getCurrentSchedule() {
auto& tls = TLState::get();
return tls.sched;
}
std::function<size_t(size_t)>
DeterministicSchedule::uniformSubset(uint64_t seed, size_t n, size_t m) {
auto gen = std::make_shared<UniformSubset>(seed, n, m);
......
......@@ -29,7 +29,6 @@
#include <vector>
#include <folly/ScopeGuard.h>
#include <folly/SingletonThreadLocal.h>
#include <folly/concurrency/CacheLocality.h>
#include <folly/detail/Futex.h>
#include <folly/synchronization/detail/AtomicUtils.h>
......@@ -199,8 +198,7 @@ class DeterministicSchedule {
static inline std::thread thread(Func&& func, Args&&... args) {
// TODO: maybe future versions of gcc will allow forwarding to thread
atomic_thread_fence(std::memory_order_seq_cst);
auto& tls = TLState::get();
auto sched = tls.sched;
auto sched = getCurrentSchedule();
auto sem = sched ? sched->beforeThreadCreate() : nullptr;
auto child = std::thread(
[=](Args... a) {
......@@ -278,49 +276,22 @@ class DeterministicSchedule {
/** Returns true if the current thread has already completed
* the thread function, for example if the thread is executing
* thread local destructors. */
static bool isCurrentThreadExiting() {
auto& tls = TLState::get();
return tls.exiting;
}
static bool isCurrentThreadExiting();
/** Add sem back into sems_ */
static void reschedule(Sem* sem);
static bool isActive() {
auto& tls = TLState::get();
return tls.sched != nullptr;
}
static bool isActive();
static DSchedThreadId getThreadId() {
auto& tls = TLState::get();
assert(tls.sched != nullptr);
return tls.threadId;
}
static DSchedThreadId getThreadId();
static ThreadInfo& getCurrentThreadInfo();
static void atomic_thread_fence(std::memory_order mo);
private:
struct PerThreadState {
// delete the constructors and assignment operators for sanity
//
// but... we can't delete the move constructor and assignment operators
// because those are required before C++17 in the implementation of
// SingletonThreadLocal
PerThreadState(const PerThreadState&) = delete;
PerThreadState& operator=(const PerThreadState&) = delete;
PerThreadState(PerThreadState&&) = default;
PerThreadState& operator=(PerThreadState&&) = default;
PerThreadState() = default;
Sem* sem{nullptr};
DeterministicSchedule* sched{nullptr};
bool exiting{false};
DSchedThreadId threadId{};
AuxAct aux_act{};
};
using TLState = SingletonThreadLocal<PerThreadState>;
static DeterministicSchedule* getCurrentSchedule();
static AuxChk aux_chk;
std::function<size_t(size_t)> scheduler_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment