]>
Commit | Line | Data |
---|---|---|
f1ca4da6 BB |
1 | #include <sys/linux-taskq.h> |
2 | ||
3 | /* | |
4 | * Task queue interface | |
5 | * | |
6 | * The taskq_work_wrapper functions are used to manage the work_structs | |
7 | * which must be submitted to linux. The shim layer allocates a wrapper | |
8 | * structure for all items which contains a pointer to itself as well as | |
9 | * the real work to be performed. When the work item run the generic | |
10 | * handle is called which calls the real work function and then using | |
11 | * the self pointer frees the work_struct. | |
12 | */ | |
13 | typedef struct taskq_work_wrapper { | |
14 | struct work_struct tww_work; | |
15 | task_func_t tww_func; | |
16 | void * tww_priv; | |
17 | } taskq_work_wrapper_t; | |
18 | ||
19 | static void | |
20 | taskq_work_handler(void *priv) | |
21 | { | |
22 | taskq_work_wrapper_t *tww = priv; | |
23 | ||
24 | BUG_ON(tww == NULL); | |
25 | BUG_ON(tww->tww_func == NULL); | |
26 | ||
27 | /* Call the real function and free the wrapper */ | |
28 | tww->tww_func(tww->tww_priv); | |
29 | kfree(tww); | |
30 | } | |
31 | ||
32 | /* XXX - All flags currently ignored */ | |
33 | taskqid_t | |
34 | __taskq_dispatch(taskq_t *tq, task_func_t func, void *priv, uint_t flags) | |
35 | { | |
36 | struct workqueue_struct *wq = tq; | |
37 | taskq_work_wrapper_t *tww; | |
38 | int rc; | |
39 | ||
40 | ||
41 | BUG_ON(in_interrupt()); | |
42 | BUG_ON(tq == NULL); | |
43 | BUG_ON(func == NULL); | |
44 | ||
45 | tww = (taskq_work_wrapper_t *)kmalloc(sizeof(*tww), GFP_KERNEL); | |
46 | if (!tww) | |
47 | return (taskqid_t)0; | |
48 | ||
49 | INIT_WORK(&(tww->tww_work), taskq_work_handler, tww); | |
50 | tww->tww_func = func; | |
51 | tww->tww_priv = priv; | |
52 | ||
53 | rc = queue_work(wq, &(tww->tww_work)); | |
54 | if (!rc) { | |
55 | kfree(tww); | |
56 | return (taskqid_t)0; | |
57 | } | |
58 | ||
59 | return (taskqid_t)wq; | |
60 | } | |
61 | ||
62 | /* XXX - Most args ignored until we decide if it's worth the effort | |
63 | * to emulate the solaris notion of dynamic thread pools. For | |
64 | * now we simply serialize everything through one thread which | |
65 | * may come back to bite us as a performance issue. | |
66 | * pri - Ignore priority | |
67 | * min - Ignored until this is a dynamic thread pool | |
68 | * max - Ignored until this is a dynamic thread pool | |
69 | * flags - Ignored until this is a dynamic thread_pool | |
70 | */ | |
71 | taskq_t * | |
72 | __taskq_create(const char *name, int nthreads, pri_t pri, | |
73 | int minalloc, int maxalloc, uint_t flags) | |
74 | { | |
75 | /* NOTE: Linux workqueue names are limited to 10 chars */ | |
76 | ||
77 | return create_singlethread_workqueue(name); | |
78 | } |