void VM::run_and_monitor() { for(;;) { if(interrupts.check_events) { interrupts.check_events = false; interrupts.enable_preempt = false; Thread* current = G(current_thread); // The current thread isn't asleep, so we're being preemptive if(current->alive() == Qtrue && current->sleep() != Qtrue) { // Order is important here. We poll so any threads // might get woken up if they need to be. events->poll(); // Only then do we reschedule the current thread if // we need to. queue_thread() puts the thread at the end // of the list for it's priority, so we shouldn't starve // anything this way. queue_thread(G(current_thread)); } while(!find_and_activate_thread()) { events->run_and_wait(); } interrupts.enable_preempt = interrupts.use_preempt; } collect_maybe(); G(current_task)->execute(); } }
void checkpoint(STATE) { metrics().machine.checkpoints++; if(thread_nexus_->stop_lock(this)) { metrics().machine.stops++; collect_maybe(state); thread_nexus_->unlock(); } }