FOLLY_TLS sem_t* DeterministicSchedule::tls_sem;
FOLLY_TLS DeterministicSchedule* DeterministicSchedule::tls_sched;
FOLLY_TLS unsigned DeterministicSchedule::tls_threadId;
+FOLLY_TLS std::function<void(uint64_t, bool)>* DeterministicSchedule::tls_aux;
// access is protected by futexLock
static std::unordered_map<detail::Futex<DeterministicAtomic>*,
DeterministicSchedule::DeterministicSchedule(
const std::function<int(int)>& scheduler)
- : scheduler_(scheduler), nextThreadId_(1) {
+ : scheduler_(scheduler), nextThreadId_(1), step_(0) {
assert(tls_sem == nullptr);
assert(tls_sched == nullptr);
+ assert(tls_aux == nullptr);
tls_sem = new sem_t;
sem_init(tls_sem, 0, 1);
if (!sched) {
return;
}
+ sem_post(sched->sems_[sched->scheduler_(sched->sems_.size())]);
+}
+void DeterministicSchedule::afterSharedAccess(bool success) {
+ auto sched = tls_sched;
+ if (!sched) {
+ return;
+ }
+ sched->callAux(success);
sem_post(sched->sems_[sched->scheduler_(sched->sems_.size())]);
}
return 0;
}
+void DeterministicSchedule::setAux(std::function<void(uint64_t, bool)>& aux) {
+ tls_aux = &aux;
+}
+
sem_t* DeterministicSchedule::beforeThreadCreate() {
sem_t* s = new sem_t;
sem_init(s, 0, 0);
child.join();
}
+void DeterministicSchedule::callAux(bool success) {
+ ++step_;
+ auto aux = tls_aux;
+ if (!aux) {
+ return;
+ }
+ (*aux)(step_, success);
+ tls_aux = nullptr;
+}
+
void DeterministicSchedule::post(sem_t* sem) {
beforeSharedAccess();
sem_post(sem);