void mainloop(void) { extern int game_is_being_shut_down; struct task *current_task; struct timeval tv; double task_start; #ifdef SUPER_SNOOP read_snoop_file(); #endif (void) printf("Setting up ipc.\n"); (void)fflush(stdout); prepare_ipc(); (void) signal(SIGFPE, sigfpe_handler); while (!game_is_being_shut_down) { while (task_head.next == &task_head) { set_current_time(); deliver_signals(); call_out(&tv); if (task_head.next != &task_head) tv.tv_sec = tv.tv_usec = 0; nd_select(&tv); check_for_slow_shut_down(); } set_current_time(); current_task = task_head.next; remove_task(current_task); runtask(current_task); task_start = current_time; set_current_time(); update_runq_av((num_tasks + 1.0) * (current_time - task_start)); /* process callouts and IO */ deliver_signals(); if (task_head.next != &task_head || current_task->next == current_task) { tv.tv_sec = tv.tv_usec = 0; call_out(NULL); } else call_out(&tv); if (task_head.next != &task_head || current_task->next == current_task) tv.tv_sec = tv.tv_usec = 0; nd_select(&tv); check_for_slow_shut_down(); if (current_task->next == current_task) append_task(current_task); /* reschedule the task */ else free(current_task); } shutdowngame(); }
struct task * create_task(void (*f)(void *), void *arg) { struct task *new_task; new_task = xalloc(sizeof(struct task)); new_task->fkn = f; new_task->arg = arg; append_task(new_task); return new_task; }
void reschedule_task(struct task *t) { if (!t) return; if (t->next == t) return; /* It's the currently running task, it will be rescheduled when it is finnished */ if (t->next == 0) { t->prev = t->next = t; /* it's the currrently running task. Mark it for rescheduling */ return; } /* Move the task to the tail */ remove_task(t); append_task(t); }
void scheduler_append(volatile TaskDescriptor *td) { ASSERT(td->state == READY, "Can only append ready tasks"); append_task(td); }