bool fiber_async_consensus::end_done_critical_section(size_t cpuid) { // if done flag is set, quit immediately if (done) { m.unlock(); critical[cpuid] = false; trying_to_sleep.dec(); return true; } /* Assertion: Since numactive is decremented only within a critical section, and is incremented only within the same critical section. Therefore numactive is a valid counter of the number of fibers outside of this critical section. */ --numactive; /* Assertion: If numactive is ever 0 at this point, the algorithm is done. WLOG, let the current fiber which just decremented numactive be fiber 0 Since there is only 1 active fiber (0), there must be no fibers performing insertions, and are no other fibers which are waking up. All fibers must therefore be sleeping. */ if (numactive == 0) { //logstream(LOG_INFO) << rmi.procid() << ": Termination Possible" << std::endl; if (hastoken) pass_the_token(); } sleeping[cpuid] = true; while(1) { // here we are protected by the mutex again. // woken up by someone else. leave the // terminator if (sleeping[cpuid] == false || done) { break; } // put myself to sleep // this here is basically cond[cpuid].wait(m); cond[cpuid] = fiber_control::get_tid(); ASSERT_NE(cond[cpuid], 0); fiber_control::deschedule_self(&m.m_mut); m.lock(); cond[cpuid] = 0; } m.unlock(); critical[cpuid] = false; trying_to_sleep.dec(); return done; }
void async_consensus::receive_the_token(token &tok) { mut.lock(); // save the token hastoken = true; cur_token = tok; // if I am waiting on done, pass the token. if ((threads_in_done == required_threads_in_done) && (cancelled == 0)) { pass_the_token(); } mut.unlock(); }
void fiber_async_consensus::receive_the_token(token &tok) { m.lock(); // save the token hastoken = true; cur_token = tok; // if I am waiting on done, pass the token. //logstream(LOG_INFO) << rmi.procid() << ": Token Received" << std::endl; if (numactive == 0) { pass_the_token(); } m.unlock(); }
bool async_consensus::end_done_critical_section(size_t cpuid) { // if done flag is set, quit immediately if (done) { m.unlock(); critical[cpuid] = false; trying_to_sleep.dec(); return true; } /* Assertion: Since numactive is decremented only within a critical section, and is incremented only within the same critical section. Therefore numactive is a valid counter of the number of threads outside of this critical section. */ --numactive; /* Assertion: If numactive is ever 0 at this point, the algorithm is done. WLOG, let the current thread which just decremented numactive be thread 0 Since there is only 1 active thread (0), there must be no threads performing insertions, and are no othe threads which are waking up. All threads must therefore be sleeping in cond.wait(). */ if (numactive == 0) { logstream(LOG_INFO) << rmi.procid() << ": Termination Possible" << std::endl; if (hastoken) pass_the_token(); } sleeping[cpuid] = true; while(1) { // here we are protected by the mutex again. // woken up by someone else. leave the // terminator if (sleeping[cpuid] == false || done) { break; } cond[cpuid].wait(m); } m.unlock(); critical[cpuid] = false; trying_to_sleep.dec(); return done; }
bool async_consensus::end_done_critical_section(bool done) { if (!done) { mut.unlock(); return false; } ++threads_in_done; // reset the cancelled flag if (threads_in_done == required_threads_in_done && cancelled == 0) { if (hastoken) pass_the_token(); } if (complete == false && cancelled == 0) cond.wait(mut); --threads_in_done; if (cancelled > 0) cancelled--; mut.unlock(); return complete; }