workqueue: add 'flush_delayed_work()' to run and wait for delayed work
[safe/jmp/linux-2.6] / include / linux / workqueue.h
index 7f28c32..cf24c20 100644 (file)
@@ -41,6 +41,11 @@ struct delayed_work {
        struct timer_list timer;
 };
 
+static inline struct delayed_work *to_delayed_work(struct work_struct *work)
+{
+       return container_of(work, struct delayed_work, work);
+}
+
 struct execute_work {
        struct work_struct work;
 };
@@ -89,7 +94,7 @@ struct execute_work {
 /*
  * initialize all of a work item in one go
  *
- * NOTE! No point in using "atomic_long_set()": useing a direct
+ * NOTE! No point in using "atomic_long_set()": using a direct
  * assignment of the work data initializer allows the compiler
  * to generate better code.
  */
@@ -118,12 +123,24 @@ struct execute_work {
                init_timer(&(_work)->timer);                    \
        } while (0)
 
+#define INIT_DELAYED_WORK_ON_STACK(_work, _func)               \
+       do {                                                    \
+               INIT_WORK(&(_work)->work, (_func));             \
+               init_timer_on_stack(&(_work)->timer);           \
+       } while (0)
+
 #define INIT_DELAYED_WORK_DEFERRABLE(_work, _func)                     \
        do {                                                    \
                INIT_WORK(&(_work)->work, (_func));             \
                init_timer_deferrable(&(_work)->timer);         \
        } while (0)
 
+#define INIT_DELAYED_WORK_ON_STACK(_work, _func)               \
+       do {                                                    \
+               INIT_WORK(&(_work)->work, (_func));             \
+               init_timer_on_stack(&(_work)->timer);           \
+       } while (0)
+
 /**
  * work_pending - Find out whether a work item is currently pending
  * @work: The work item in question
@@ -149,11 +166,11 @@ struct execute_work {
 
 extern struct workqueue_struct *
 __create_workqueue_key(const char *name, int singlethread,
-                      int freezeable, struct lock_class_key *key,
+                      int freezeable, int rt, struct lock_class_key *key,
                       const char *lock_name);
 
 #ifdef CONFIG_LOCKDEP
-#define __create_workqueue(name, singlethread, freezeable)     \
+#define __create_workqueue(name, singlethread, freezeable, rt) \
 ({                                                             \
        static struct lock_class_key __key;                     \
        const char *__lock_name;                                \
@@ -164,32 +181,37 @@ __create_workqueue_key(const char *name, int singlethread,
                __lock_name = #name;                            \
                                                                \
        __create_workqueue_key((name), (singlethread),          \
-                              (freezeable), &__key,            \
+                              (freezeable), (rt), &__key,      \
                               __lock_name);                    \
 })
 #else
-#define __create_workqueue(name, singlethread, freezeable)     \
-       __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL)
+#define __create_workqueue(name, singlethread, freezeable, rt) \
+       __create_workqueue_key((name), (singlethread), (freezeable), (rt), \
+                              NULL, NULL)
 #endif
 
-#define create_workqueue(name) __create_workqueue((name), 0, 0)
-#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1)
-#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
+#define create_workqueue(name) __create_workqueue((name), 0, 0, 0)
+#define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1)
+#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0)
+#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0)
 
 extern void destroy_workqueue(struct workqueue_struct *wq);
 
-extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
-extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq,
-                       struct delayed_work *work, unsigned long delay));
+extern int queue_work(struct workqueue_struct *wq, struct work_struct *work);
+extern int queue_work_on(int cpu, struct workqueue_struct *wq,
+                       struct work_struct *work);
+extern int queue_delayed_work(struct workqueue_struct *wq,
+                       struct delayed_work *work, unsigned long delay);
 extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
                        struct delayed_work *work, unsigned long delay);
 
-extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq));
+extern void flush_workqueue(struct workqueue_struct *wq);
 extern void flush_scheduled_work(void);
+extern void flush_delayed_work(struct delayed_work *work);
 
-extern int FASTCALL(schedule_work(struct work_struct *work));
-extern int FASTCALL(schedule_delayed_work(struct delayed_work *work,
-                                       unsigned long delay));
+extern int schedule_work(struct work_struct *work);
+extern int schedule_work_on(int cpu, struct work_struct *work);
+extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay);
 extern int schedule_delayed_work_on(int cpu, struct delayed_work *work,
                                        unsigned long delay);
 extern int schedule_on_each_cpu(work_func_t func);
@@ -199,6 +221,8 @@ extern int keventd_up(void);
 extern void init_workqueues(void);
 int execute_in_process_context(work_func_t fn, struct execute_work *);
 
+extern int flush_work(struct work_struct *work);
+
 extern int cancel_work_sync(struct work_struct *work);
 
 /*
@@ -217,6 +241,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
        return ret;
 }
 
+/*
+ * Like above, but uses del_timer() instead of del_timer_sync(). This means,
+ * if it returns 0 the timer function may be running and the queueing is in
+ * progress.
+ */
+static inline int __cancel_delayed_work(struct delayed_work *work)
+{
+       int ret;
+
+       ret = del_timer(&work->timer);
+       if (ret)
+               work_clear_pending(&work->work);
+       return ret;
+}
+
 extern int cancel_delayed_work_sync(struct delayed_work *work);
 
 /* Obsolete. use cancel_delayed_work_sync() */
@@ -234,4 +273,12 @@ void cancel_rearming_delayed_work(struct delayed_work *work)
        cancel_delayed_work_sync(work);
 }
 
+#ifndef CONFIG_SMP
+static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg)
+{
+       return fn(arg);
+}
+#else
+long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg);
+#endif /* CONFIG_SMP */
 #endif