- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# include/workqueue.h

Go to the documentation of this file.

    00001
    00045 #ifndef WORKQUEUE_H_INCLUDED
    00046 #define WORKQUEUE_H_INCLUDED
    00047
    00048 #include <types.h>
    00049 #include <slist.h>
    00050 #include <util.h>
    00051 #include <interrupt.h>
    00052
    00054 typedef void (*workqueue_callback_t)(void *data);
    00055
    00057 struct workqueue_item
    00058 {
    00059         workqueue_callback_t callback;
    00060         void *data;
    00061         struct slist_node node;
    00062 };
    00063
    00065 struct workqueue
    00066 {
    00067         struct slist list;
    00068 };
    00069
    00070
    00071 #ifdef __cplusplus
    00072 extern "C" {
    00073 #endif
    00074
    00075
    00081 static inline void workqueue_init(struct workqueue *queue)
    00082 {
    00083         /* Sanity check on parameters. */
    00084         assert(queue);
    00085
    00086         /* Initialize to an empty state, ready for data. */
    00087         slist_init(&queue->list);
    00088 }
    00089
    00102 static inline void workqueue_init_item(
    00103                 struct workqueue_item *item,
    00104                 workqueue_callback_t callback,
    00105                 void *data)
    00106 {
    00107         /* Flag the item as ready for use by clearing next pointer */
    00108         item->node.next = NULL;
    00109
    00110         item->callback = callback;
    00111         item->data = data;
    00112 }
    00113
    00122 static inline bool workqueue_is_empty(struct workqueue *queue)
    00123 {
    00124         /* Sanity check on parameters. */
    00125         assert(queue);
    00126
    00127         return slist_is_empty(&queue->list);
    00128 }
    00129
    00135 static inline bool workqueue_item_is_queued(struct workqueue_item *item)
    00136 {
    00137         return item->node.next != NULL;
    00138 }
    00139
    00155 static inline void workqueue_add_item(
    00156                 struct workqueue *queue,
    00157                 struct workqueue_item *item)
    00158 {
    00159         unsigned long iflags;
    00160
    00161         /* Sanity check on parameters. */
    00162         assert(queue);
    00163         assert(item);
    00164         /* We will run this later, so check that it is valid */
    00165         assert(item->callback);
    00166         /* If the next pointer is set, the item is in use */
    00167         assert(item->node.next == NULL);
    00168
    00169         iflags = cpu_irq_save();
    00170         slist_insert_tail(&queue->list, &item->node);
    00171         cpu_irq_restore(iflags);
    00172 }
    00173
    00191 static inline void workqueue_add_item_safe(
    00192                 struct workqueue *queue,
    00193                 struct workqueue_item *item)
    00194 {
    00195         unsigned long iflags;
    00196
    00197         /* Sanity check on parameters. */
    00198         assert(queue);
    00199         assert(item);
    00200         /* We will run this later, so check that it is valid */
    00201         assert(item->callback);
    00202
    00203         iflags = cpu_irq_save();
    00204         if (!workqueue_item_is_queued(item))
    00205                 slist_insert_tail(&queue->list, &item->node);
    00206         cpu_irq_restore(iflags);
    00207 }
    00208
    00220 static inline struct workqueue_item *workqueue_remove_item(
    00221                 struct workqueue *queue)
    00222 {
    00223         struct workqueue_item *item;
    00224         unsigned long iflags;
    00225
    00226         /* Sanity check on parameters. */
    00227         assert(queue);
    00228
    00229         iflags = cpu_irq_save();
    00230         if (!workqueue_is_empty(queue)) {
    00231                 item = slist_pop_head(&queue->list, struct workqueue_item, node);
    00232                 /* Flag the item as ready for use by clearing next pointer */
    00233                 item->node.next = NULL;
    00234         } else {
    00235                 item = NULL;
    00236         }
    00237         cpu_irq_restore(iflags);
    00238
    00239         return item;
    00240 }
    00241
    00251 inline static void workqueue_move_item(
    00252                 struct workqueue *source,
    00253                 struct workqueue *dest)
    00254 {
    00255         /* Sanity check on parameters. */
    00256         assert(source);
    00257         assert(dest);
    00258
    00259         /* Move work between queues. */
    00260         workqueue_add_item(dest, workqueue_remove_item(source));
    00261 }
    00262
    00269 inline static void *workqueue_get_data(struct workqueue_item *item)
    00270 {
    00271         assert(item);
    00272
    00273         return item->data;
    00274 }
    00275
    00276
    00287 inline static void workqueue_do_one_item(struct workqueue *queue)
    00288 {
    00289         struct workqueue_item *item;
    00290
    00291         /* Sanity check on parameters. */
    00292         assert(queue);
    00293
    00294         /* Get work and dispatch */
    00295         item = workqueue_remove_item(queue);
    00296         if (item)
    00297                 item->callback(workqueue_get_data(item));
    00298 }
    00299
    00300
    00301 #ifdef __cplusplus
    00302 } /* extern "C" */
    00303 #endif
    00304
    00305
    00306 #endif /* WORKQUEUE_H_INCLUDED */