Commit 49a83b77 authored by Doron Roberts-Kedes's avatar Doron Roberts-Kedes Committed by Facebook Github Bot

DeterministicSchedule: Deschedule parent threads while they wait to join child threads.

Summary:
Eliminate while loop behavior in DeterministicSchedule::join

Depends on D8789304

Reviewed By: djwatson

Differential Revision: D8840276

fbshipit-source-id: f0b0db60f7bec344d021a49cec408a2604d4a1c8
parent 566f0478
...@@ -226,6 +226,11 @@ void DeterministicSchedule::afterThreadCreate(sem_t* sem) { ...@@ -226,6 +226,11 @@ void DeterministicSchedule::afterThreadCreate(sem_t* sem) {
void DeterministicSchedule::beforeThreadExit() { void DeterministicSchedule::beforeThreadExit() {
assert(tls_sched == this); assert(tls_sched == this);
beforeSharedAccess(); beforeSharedAccess();
auto parent = joins_.find(std::this_thread::get_id());
if (parent != joins_.end()) {
reschedule(parent->second);
joins_.erase(parent);
}
sems_.erase(std::find(sems_.begin(), sems_.end(), tls_sem)); sems_.erase(std::find(sems_.begin(), sems_.end(), tls_sem));
active_.erase(std::this_thread::get_id()); active_.erase(std::this_thread::get_id());
if (sems_.size() > 0) { if (sems_.size() > 0) {
...@@ -242,16 +247,19 @@ void DeterministicSchedule::beforeThreadExit() { ...@@ -242,16 +247,19 @@ void DeterministicSchedule::beforeThreadExit() {
void DeterministicSchedule::join(std::thread& child) { void DeterministicSchedule::join(std::thread& child) {
auto sched = tls_sched; auto sched = tls_sched;
if (sched) { if (sched) {
bool done = false; beforeSharedAccess();
while (!done) { assert(sched->joins_.count(child.get_id()) == 0);
beforeSharedAccess(); if (sched->active_.count(child.get_id())) {
done = !sched->active_.count(child.get_id()); sem_t* sem = descheduleCurrentThread();
if (done) { sched->joins_.insert({child.get_id(), sem});
FOLLY_TEST_DSCHED_VLOG("joined " << std::hex << child.get_id());
}
afterSharedAccess(); afterSharedAccess();
// Wait to be scheduled by exiting child thread
beforeSharedAccess();
assert(!sched->active_.count(child.get_id()));
} }
afterSharedAccess();
} }
FOLLY_TEST_DSCHED_VLOG("joined " << std::hex << child.get_id());
child.join(); child.join();
} }
......
...@@ -199,6 +199,7 @@ class DeterministicSchedule : boost::noncopyable { ...@@ -199,6 +199,7 @@ class DeterministicSchedule : boost::noncopyable {
std::function<size_t(size_t)> scheduler_; std::function<size_t(size_t)> scheduler_;
std::vector<sem_t*> sems_; std::vector<sem_t*> sems_;
std::unordered_set<std::thread::id> active_; std::unordered_set<std::thread::id> active_;
std::unordered_map<std::thread::id, sem_t*> joins_;
unsigned nextThreadId_; unsigned nextThreadId_;
/* step_ keeps count of shared accesses that correspond to user /* step_ keeps count of shared accesses that correspond to user
* synchronization steps (atomic accesses for now). * synchronization steps (atomic accesses for now).
......
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