/* * This file implements the Task Queue object and contains all the functions for * dealing with them. A Task Queue holds a reference to every Task it contains. * There is a single reference per task for the entire queue, and tasks do not * hold references to their neighbour, nor the queue its end. */ #include #include static void *task_queue_new(void); static void task_queue_delete(Object *); /* Task Queue object type */ ObjectType taskQueueType = { .new = task_queue_new, .delete = task_queue_delete, }; /* Create a new Task Queue */ static void * task_queue_new(void) { TaskQueue *queue = kmalloc(sizeof(TaskQueue)); } /* Destroy a Task Queue */ static void task_queue_delete(Object *obj) { TaskQueue *queue = (void *) obj; while (queue->start) put(pop_from_queue(queue)); kfree(queue); } /* Add a Task to a Task Queue */ void add_to_queue(TaskQueue *queue, Task *task) { lock(queue); if (!queue->start) queue->start = get(task); else queue->end->next = get(task); queue->end = task; task->next = NULL; unlock(queue); } /* Remove a Task from a Task Queue */ void remove_from_queue(TaskQueue *queue, Task *task) { lock(queue); /* Start of queue */ if (queue->start == task) { queue->start = task->next; goto found; } /* Search */ Task *prev; for (prev = queue->start; prev->next; prev = prev->next) if (prev->next == task) break; if (!prev->next) { unlock(queue); return; } prev->next = task->next; found: if (queue->end == task) queue->end = NULL; task->next = NULL; put(task); unlock(queue); } /* Remove the first Task from a Task Queue */ Task * pop_from_queue(TaskQueue *queue) { lock(queue); Task *head = get(queue->start); remove_from_queue(queue, queue->start); unlock(queue); return head; }