static void threaded_worker(void *userdata) { (void)userdata; for (;;) { retro_task_t *task = NULL; if (!worker_continue) break; /* should we keep running until all tasks finished? */ slock_lock(running_lock); /* Get first task to run */ task = tasks_running.front; if (task == NULL) { scond_wait(worker_cond, running_lock); slock_unlock(running_lock); continue; } slock_unlock(running_lock); task->handler(task); slock_lock(running_lock); task_queue_remove(&tasks_running, task); slock_unlock(running_lock); /* Update queue */ if (!task->finished) { /* Re-add task to running queue */ retro_task_threaded_push_running(task); } else { /* Add task to finished queue */ slock_lock(finished_lock); task_queue_put(&tasks_finished, task); slock_unlock(finished_lock); } #if 0 retro_sleep(10); #endif } slock_unlock(running_lock); }
/* Basic operations on tasks */ static task_env *activate(task_env *t) { if (t) { MAY_DBG(FN; STRLIT("activating task "); PTREXP(t); STREXP(t->name); NDBG(t->heap_pos, d); NDBG(t->time, f); ); assert(ash_nazg_gimbatul.type == type_hash("task_env")); if (t->heap_pos) task_queue_remove(&task_time_q, t->heap_pos); link_into(&t->l, &tasks); t->time = 0.0; t->heap_pos = 0; assert(ash_nazg_gimbatul.type == type_hash("task_env")); }