+/** Wake up all processes waiting for a Surf action to finish */
+static void SIMIX_wake_processes()
+{
+ unsigned int iter;
+ surf_model_t model;
+ surf_action_t action;
+
+ xbt_dynar_foreach(all_existing_models, iter, model) {
+ XBT_DEBUG("Handling process whose action failed");
+ while ((action = surf_model_extract_failed_action_set(model))) {
+ XBT_DEBUG(" Handling Action %p",action);
+ SIMIX_simcall_exit((smx_synchro_t) action->getData());
+ }
+ XBT_DEBUG("Handling process whose action terminated normally");
+ while ((action = surf_model_extract_done_action_set(model))) {
+ XBT_DEBUG(" Handling Action %p",action);
+ if (action->getData() == nullptr)
+ XBT_DEBUG("probably vcpu's action %p, skip", action);
+ else
+ SIMIX_simcall_exit((smx_synchro_t) action->getData());
+ }
+ }
+}
+
+/** Handle any pending timer */
+static bool SIMIX_execute_timers()
+{
+ bool result = false;
+ while (xbt_heap_size(simix_timers) > 0 && SIMIX_get_clock() >= SIMIX_timer_next()) {
+ result = true;
+ //FIXME: make the timers being real callbacks
+ // (i.e. provide dispatchers that read and expand the args)
+ smx_timer_t timer = (smx_timer_t) xbt_heap_pop(simix_timers);
+ try {
+ timer->callback();
+ }
+ catch(...) {
+ xbt_die("Exception throwed ouf of timer callback");
+ }
+ delete timer;
+ }
+ return result;
+}
+
+/** Execute all the tasks that are queued
+ *
+ * e.g. `.then()` callbacks of futures.
+ **/
+static bool SIMIX_execute_tasks()
+{
+ xbt_assert(simix_global->tasksTemp.empty());
+
+ if (simix_global->tasks.empty())
+ return false;
+
+ using std::swap;
+ do {
+ // We don't want the callbacks to modify the vector we are iterating over:
+ swap(simix_global->tasks, simix_global->tasksTemp);
+
+ // Execute all the queued tasks:
+ for (auto& task : simix_global->tasksTemp)
+ task();
+
+ simix_global->tasksTemp.clear();
+ } while (!simix_global->tasks.empty());
+
+ return true;
+}
+