11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * workqueue.h --- work queue handling for Linux. 31da177e4SLinus Torvalds */ 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds #ifndef _LINUX_WORKQUEUE_H 61da177e4SLinus Torvalds #define _LINUX_WORKQUEUE_H 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #include <linux/timer.h> 91da177e4SLinus Torvalds #include <linux/linkage.h> 101da177e4SLinus Torvalds #include <linux/bitops.h> 11a08727baSLinus Torvalds #include <asm/atomic.h> 121da177e4SLinus Torvalds 131da177e4SLinus Torvalds struct workqueue_struct; 141da177e4SLinus Torvalds 1565f27f38SDavid Howells struct work_struct; 1665f27f38SDavid Howells typedef void (*work_func_t)(struct work_struct *work); 176bb49e59SDavid Howells 18a08727baSLinus Torvalds /* 19a08727baSLinus Torvalds * The first word is the work queue pointer and the flags rolled into 20a08727baSLinus Torvalds * one 21a08727baSLinus Torvalds */ 22a08727baSLinus Torvalds #define work_data_bits(work) ((unsigned long *)(&(work)->data)) 23a08727baSLinus Torvalds 241da177e4SLinus Torvalds struct work_struct { 25a08727baSLinus Torvalds atomic_long_t data; 26365970a1SDavid Howells #define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ 2765f27f38SDavid Howells #define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */ 28365970a1SDavid Howells #define WORK_STRUCT_FLAG_MASK (3UL) 29365970a1SDavid Howells #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) 301da177e4SLinus Torvalds struct list_head entry; 316bb49e59SDavid Howells work_func_t func; 3252bad64dSDavid Howells }; 3352bad64dSDavid Howells 34a08727baSLinus Torvalds #define WORK_DATA_INIT(autorelease) \ 35a08727baSLinus Torvalds ATOMIC_LONG_INIT((autorelease) << WORK_STRUCT_NOAUTOREL) 36a08727baSLinus Torvalds 3752bad64dSDavid Howells struct delayed_work { 3852bad64dSDavid Howells struct work_struct work; 391da177e4SLinus Torvalds struct timer_list timer; 401da177e4SLinus Torvalds }; 411da177e4SLinus Torvalds 421fa44ecaSJames Bottomley struct execute_work { 431fa44ecaSJames Bottomley struct work_struct work; 441fa44ecaSJames Bottomley }; 451fa44ecaSJames Bottomley 4665f27f38SDavid Howells #define __WORK_INITIALIZER(n, f) { \ 47a08727baSLinus Torvalds .data = WORK_DATA_INIT(0), \ 481da177e4SLinus Torvalds .entry = { &(n).entry, &(n).entry }, \ 491da177e4SLinus Torvalds .func = (f), \ 5052bad64dSDavid Howells } 5152bad64dSDavid Howells 5265f27f38SDavid Howells #define __WORK_INITIALIZER_NAR(n, f) { \ 53a08727baSLinus Torvalds .data = WORK_DATA_INIT(1), \ 5465f27f38SDavid Howells .entry = { &(n).entry, &(n).entry }, \ 5565f27f38SDavid Howells .func = (f), \ 5665f27f38SDavid Howells } 5765f27f38SDavid Howells 5865f27f38SDavid Howells #define __DELAYED_WORK_INITIALIZER(n, f) { \ 5965f27f38SDavid Howells .work = __WORK_INITIALIZER((n).work, (f)), \ 601da177e4SLinus Torvalds .timer = TIMER_INITIALIZER(NULL, 0, 0), \ 611da177e4SLinus Torvalds } 621da177e4SLinus Torvalds 6365f27f38SDavid Howells #define __DELAYED_WORK_INITIALIZER_NAR(n, f) { \ 6465f27f38SDavid Howells .work = __WORK_INITIALIZER_NAR((n).work, (f)), \ 6565f27f38SDavid Howells .timer = TIMER_INITIALIZER(NULL, 0, 0), \ 6665f27f38SDavid Howells } 671da177e4SLinus Torvalds 6865f27f38SDavid Howells #define DECLARE_WORK(n, f) \ 6965f27f38SDavid Howells struct work_struct n = __WORK_INITIALIZER(n, f) 7065f27f38SDavid Howells 7165f27f38SDavid Howells #define DECLARE_WORK_NAR(n, f) \ 7265f27f38SDavid Howells struct work_struct n = __WORK_INITIALIZER_NAR(n, f) 7365f27f38SDavid Howells 7465f27f38SDavid Howells #define DECLARE_DELAYED_WORK(n, f) \ 7565f27f38SDavid Howells struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f) 7665f27f38SDavid Howells 7765f27f38SDavid Howells #define DECLARE_DELAYED_WORK_NAR(n, f) \ 7865f27f38SDavid Howells struct dwork_struct n = __DELAYED_WORK_INITIALIZER_NAR(n, f) 7952bad64dSDavid Howells 801da177e4SLinus Torvalds /* 8165f27f38SDavid Howells * initialize a work item's function pointer 821da177e4SLinus Torvalds */ 8365f27f38SDavid Howells #define PREPARE_WORK(_work, _func) \ 841da177e4SLinus Torvalds do { \ 8552bad64dSDavid Howells (_work)->func = (_func); \ 861da177e4SLinus Torvalds } while (0) 871da177e4SLinus Torvalds 8865f27f38SDavid Howells #define PREPARE_DELAYED_WORK(_work, _func) \ 8965f27f38SDavid Howells PREPARE_WORK(&(_work)->work, (_func)) 9052bad64dSDavid Howells 911da177e4SLinus Torvalds /* 9252bad64dSDavid Howells * initialize all of a work item in one go 93a08727baSLinus Torvalds * 94a08727baSLinus Torvalds * NOTE! No point in using "atomic_long_set()": useing a direct 95a08727baSLinus Torvalds * assignment of the work data initializer allows the compiler 96a08727baSLinus Torvalds * to generate better code. 971da177e4SLinus Torvalds */ 9865f27f38SDavid Howells #define INIT_WORK(_work, _func) \ 991da177e4SLinus Torvalds do { \ 100a08727baSLinus Torvalds (_work)->data = (atomic_long_t) WORK_DATA_INIT(0); \ 10165f27f38SDavid Howells INIT_LIST_HEAD(&(_work)->entry); \ 10265f27f38SDavid Howells PREPARE_WORK((_work), (_func)); \ 10352bad64dSDavid Howells } while (0) 10452bad64dSDavid Howells 10565f27f38SDavid Howells #define INIT_WORK_NAR(_work, _func) \ 10652bad64dSDavid Howells do { \ 107a08727baSLinus Torvalds (_work)->data = (atomic_long_t) WORK_DATA_INIT(1); \ 10865f27f38SDavid Howells INIT_LIST_HEAD(&(_work)->entry); \ 10965f27f38SDavid Howells PREPARE_WORK((_work), (_func)); \ 11065f27f38SDavid Howells } while (0) 11165f27f38SDavid Howells 11265f27f38SDavid Howells #define INIT_DELAYED_WORK(_work, _func) \ 11365f27f38SDavid Howells do { \ 11465f27f38SDavid Howells INIT_WORK(&(_work)->work, (_func)); \ 11565f27f38SDavid Howells init_timer(&(_work)->timer); \ 11665f27f38SDavid Howells } while (0) 11765f27f38SDavid Howells 11865f27f38SDavid Howells #define INIT_DELAYED_WORK_NAR(_work, _func) \ 11965f27f38SDavid Howells do { \ 12065f27f38SDavid Howells INIT_WORK_NAR(&(_work)->work, (_func)); \ 1211da177e4SLinus Torvalds init_timer(&(_work)->timer); \ 1221da177e4SLinus Torvalds } while (0) 1231da177e4SLinus Torvalds 124365970a1SDavid Howells /** 125365970a1SDavid Howells * work_pending - Find out whether a work item is currently pending 126365970a1SDavid Howells * @work: The work item in question 127365970a1SDavid Howells */ 128365970a1SDavid Howells #define work_pending(work) \ 129a08727baSLinus Torvalds test_bit(WORK_STRUCT_PENDING, work_data_bits(work)) 130365970a1SDavid Howells 131365970a1SDavid Howells /** 132365970a1SDavid Howells * delayed_work_pending - Find out whether a delayable work item is currently 133365970a1SDavid Howells * pending 134365970a1SDavid Howells * @work: The work item in question 135365970a1SDavid Howells */ 1360221872aSLinus Torvalds #define delayed_work_pending(w) \ 1370221872aSLinus Torvalds work_pending(&(w)->work) 138365970a1SDavid Howells 13965f27f38SDavid Howells /** 14065f27f38SDavid Howells * work_release - Release a work item under execution 14165f27f38SDavid Howells * @work: The work item to release 14265f27f38SDavid Howells * 14365f27f38SDavid Howells * This is used to release a work item that has been initialised with automatic 14465f27f38SDavid Howells * release mode disabled (WORK_STRUCT_NOAUTOREL is set). This gives the work 14565f27f38SDavid Howells * function the opportunity to grab auxiliary data from the container of the 14665f27f38SDavid Howells * work_struct before clearing the pending bit as the work_struct may be 14765f27f38SDavid Howells * subject to deallocation the moment the pending bit is cleared. 14865f27f38SDavid Howells * 14965f27f38SDavid Howells * In such a case, this should be called in the work function after it has 15065f27f38SDavid Howells * fetched any data it may require from the containter of the work_struct. 15165f27f38SDavid Howells * After this function has been called, the work_struct may be scheduled for 15265f27f38SDavid Howells * further execution or it may be deallocated unless other precautions are 15365f27f38SDavid Howells * taken. 15465f27f38SDavid Howells * 15565f27f38SDavid Howells * This should also be used to release a delayed work item. 15665f27f38SDavid Howells */ 15765f27f38SDavid Howells #define work_release(work) \ 158a08727baSLinus Torvalds clear_bit(WORK_STRUCT_PENDING, work_data_bits(work)) 15965f27f38SDavid Howells 16052bad64dSDavid Howells 1611da177e4SLinus Torvalds extern struct workqueue_struct *__create_workqueue(const char *name, 162341a5958SRafael J. Wysocki int singlethread, 163341a5958SRafael J. Wysocki int freezeable); 164341a5958SRafael J. Wysocki #define create_workqueue(name) __create_workqueue((name), 0, 0) 165341a5958SRafael J. Wysocki #define create_freezeable_workqueue(name) __create_workqueue((name), 0, 1) 166341a5958SRafael J. Wysocki #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds extern void destroy_workqueue(struct workqueue_struct *wq); 1691da177e4SLinus Torvalds 1701da177e4SLinus Torvalds extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); 17152bad64dSDavid Howells extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay)); 1727a6bc1cdSVenkatesh Pallipadi extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, 17352bad64dSDavid Howells struct delayed_work *work, unsigned long delay); 1741da177e4SLinus Torvalds extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds extern int FASTCALL(schedule_work(struct work_struct *work)); 17768380b58SLinus Torvalds extern int FASTCALL(run_scheduled_work(struct work_struct *work)); 17852bad64dSDavid Howells extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); 1791da177e4SLinus Torvalds 18052bad64dSDavid Howells extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); 18165f27f38SDavid Howells extern int schedule_on_each_cpu(work_func_t func); 1821da177e4SLinus Torvalds extern void flush_scheduled_work(void); 1831da177e4SLinus Torvalds extern int current_is_keventd(void); 1841da177e4SLinus Torvalds extern int keventd_up(void); 1851da177e4SLinus Torvalds 1861da177e4SLinus Torvalds extern void init_workqueues(void); 18752bad64dSDavid Howells void cancel_rearming_delayed_work(struct delayed_work *work); 18881ddef77SJames Bottomley void cancel_rearming_delayed_workqueue(struct workqueue_struct *, 18952bad64dSDavid Howells struct delayed_work *); 19065f27f38SDavid Howells int execute_in_process_context(work_func_t fn, struct execute_work *); 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /* 1931da177e4SLinus Torvalds * Kill off a pending schedule_delayed_work(). Note that the work callback 1941da177e4SLinus Torvalds * function may still be running on return from cancel_delayed_work(). Run 1951da177e4SLinus Torvalds * flush_scheduled_work() to wait on it. 1961da177e4SLinus Torvalds */ 19752bad64dSDavid Howells static inline int cancel_delayed_work(struct delayed_work *work) 1981da177e4SLinus Torvalds { 1991da177e4SLinus Torvalds int ret; 2001da177e4SLinus Torvalds 2011da177e4SLinus Torvalds ret = del_timer_sync(&work->timer); 2021da177e4SLinus Torvalds if (ret) 203a08727baSLinus Torvalds work_release(&work->work); 2041da177e4SLinus Torvalds return ret; 2051da177e4SLinus Torvalds } 2061da177e4SLinus Torvalds 2071da177e4SLinus Torvalds #endif 208