00001 00038 #include <interrupt.h> 00039 #include <types.h> 00040 #include <workqueue.h> 00041 00047 struct workqueue main_workqueue; 00048 00069 bool workqueue_add_task(struct workqueue *queue, struct workqueue_task *task) 00070 { 00071 irqflags_t iflags; 00072 bool was_queued = false; 00073 00074 /* Sanity check on parameters. */ 00075 assert(queue); 00076 00077 /* 00078 * Allowing callers to pass a NULL task will eliminate a few 00079 * tests elsewhere and thus reduce the code size. 00080 */ 00081 if (!task) 00082 return false; 00083 00084 /* We will run this later, so check that it is valid */ 00085 assert(task->worker); 00086 00087 iflags = cpu_irq_save(); 00088 if (!workqueue_task_is_queued(task)) { 00089 slist_insert_tail(&queue->task_list, &task->node); 00090 was_queued = true; 00091 } 00092 cpu_irq_restore(iflags); 00093 00094 return was_queued; 00095 } 00096 00111 bool nested_workqueue_add_task(struct nested_workqueue *nwq, 00112 struct workqueue_task *task) 00113 { 00114 irqflags_t iflags; 00115 bool was_queued; 00116 00117 iflags = cpu_irq_save(); 00118 if (nwq->current) { 00119 was_queued = workqueue_add_task(&nwq->wq, task); 00120 } else { 00121 nwq->current = task; 00122 was_queued = workqueue_add_task(&main_workqueue, task); 00123 } 00124 cpu_irq_restore(iflags); 00125 00126 return was_queued; 00127 } 00128 00139 void nested_workqueue_next_task(struct nested_workqueue *nwq) 00140 { 00141 struct workqueue_task *task; 00142 irqflags_t iflags; 00143 00144 iflags = cpu_irq_save(); 00145 task = workqueue_pop_task(&nwq->wq); 00146 if (task) 00147 workqueue_add_task(&main_workqueue, task); 00148 nwq->current = task; 00149 cpu_irq_restore(iflags); 00150 } 00151
1.6.3