00001 00038 #ifndef WORKQUEUE_H_INCLUDED 00039 #define WORKQUEUE_H_INCLUDED 00040 00041 #include <types.h> 00042 #include <slist.h> 00043 #include <util.h> 00044 #include <interrupt.h> 00045 00057 struct workqueue_task; 00058 00063 typedef void (*workqueue_func_t)(struct workqueue_task *task); 00064 00072 struct workqueue_task { 00073 workqueue_func_t worker; 00074 struct slist_node node; 00075 }; 00076 00083 struct workqueue 00084 { 00085 struct slist task_list; 00086 }; 00087 00088 00089 #ifdef __cplusplus 00090 extern "C" { 00091 #endif 00092 00102 extern struct workqueue main_workqueue; 00103 00109 static inline void workqueue_init(struct workqueue *queue) 00110 { 00111 /* Sanity check on parameters. */ 00112 assert(queue); 00113 00114 /* Initialize to an empty state, ready for data. */ 00115 slist_init(&queue->task_list); 00116 } 00117 00127 static inline void workqueue_task_set_work_func(struct workqueue_task *task, 00128 workqueue_func_t worker_func) 00129 { 00130 task->worker = worker_func; 00131 } 00132 00144 static inline void workqueue_task_init(struct workqueue_task *task, 00145 workqueue_func_t worker_func) 00146 { 00147 /* Flag the item as ready for use by clearing next pointer */ 00148 task->node.next = NULL; 00149 00150 workqueue_task_set_work_func(task, worker_func); 00151 } 00152 00161 static inline bool workqueue_is_empty(struct workqueue *queue) 00162 { 00163 /* Sanity check on parameters. */ 00164 assert(queue); 00165 00166 return slist_is_empty(&queue->task_list); 00167 } 00168 00175 static inline bool workqueue_task_is_queued(struct workqueue_task *task) 00176 { 00177 return task->node.next != NULL; 00178 } 00179 00180 extern bool workqueue_add_task(struct workqueue *queue, 00181 struct workqueue_task *task); 00182 00198 static inline struct workqueue_task *workqueue_pop_task( 00199 struct workqueue *queue) 00200 { 00201 struct workqueue_task *task = NULL; 00202 00203 /* Sanity check on parameters. */ 00204 assert(queue); 00205 00206 assert(!cpu_irq_is_enabled()); 00207 00208 if (!workqueue_is_empty(queue)) { 00209 task = slist_pop_head(&queue->task_list, 00210 struct workqueue_task, node); 00211 /* Flag the item as ready for use by clearing next pointer */ 00212 task->node.next = NULL; 00213 } 00214 00215 return task; 00216 } 00217 00222 static inline void workqueue_run_task(struct workqueue_task *task) 00223 { 00224 task->worker(task); 00225 } 00226 00236 00243 struct nested_workqueue { 00245 struct workqueue wq; 00247 struct workqueue_task *current; 00248 }; 00249 00255 static inline void nested_workqueue_init(struct nested_workqueue *wq) 00256 { 00257 wq->current = NULL; 00258 workqueue_init(&wq->wq); 00259 } 00260 00261 extern bool nested_workqueue_add_task(struct nested_workqueue *wq, 00262 struct workqueue_task *task); 00263 extern void nested_workqueue_next_task(struct nested_workqueue *wq); 00264 00266 00267 #ifdef __cplusplus 00268 } /* extern "C" */ 00269 #endif 00270 00272 00273 #endif /* WORKQUEUE_H_INCLUDED */
1.6.3