subr_taskqueue.c (85521) | subr_taskqueue.c (85560) |
---|---|
1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * | 1/*- 2 * Copyright (c) 2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/kern/subr_taskqueue.c 85521 2001-10-26 06:32:21Z jhb $ | 26 * $FreeBSD: head/sys/kern/subr_taskqueue.c 85560 2001-10-26 18:46:48Z jhb $ |
27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> | 27 */ 28 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/bus.h> |
32#include <sys/interrupt.h> |
|
32#include <sys/kernel.h> 33#include <sys/lock.h> | 33#include <sys/kernel.h> 34#include <sys/lock.h> |
34#include <sys/interrupt.h> | |
35#include <sys/malloc.h> 36#include <sys/mutex.h> 37#include <sys/taskqueue.h> 38 39static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); 40 41static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; 42 --- 17 unchanged lines hidden (view full) --- 60{ 61 62 mtx_init(&taskqueue_queues_mutex, "taskqueue list", MTX_DEF); 63 STAILQ_INIT(&taskqueue_queues); 64} 65SYSINIT(taskqueue_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_taskqueue_list, 66 NULL); 67 | 35#include <sys/malloc.h> 36#include <sys/mutex.h> 37#include <sys/taskqueue.h> 38 39static MALLOC_DEFINE(M_TASKQUEUE, "taskqueue", "Task Queues"); 40 41static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; 42 --- 17 unchanged lines hidden (view full) --- 60{ 61 62 mtx_init(&taskqueue_queues_mutex, "taskqueue list", MTX_DEF); 63 STAILQ_INIT(&taskqueue_queues); 64} 65SYSINIT(taskqueue_list, SI_SUB_INTRINSIC, SI_ORDER_ANY, init_taskqueue_list, 66 NULL); 67 |
68void 69task_init(struct task *task, int priority, task_fn_t *func, void *context) 70{ 71 72 KASSERT(task != NULL, ("task == NULL")); 73 74 mtx_init(&task->ta_mutex, "task", MTX_DEF); 75 mtx_lock(&task->ta_mutex); 76 task->ta_pending = 0; 77 task->ta_priority = priority; 78 task->ta_func = func; 79 task->ta_context = context; 80 mtx_unlock(&task->ta_mutex); 81} 82 83void 84task_destroy(struct task *task) 85{ 86 87 mtx_destroy(&task->ta_mutex); 88} 89 | |
90struct taskqueue * 91taskqueue_create(const char *name, int mflags, 92 taskqueue_enqueue_fn enqueue, void *context) 93{ 94 struct taskqueue *queue; 95 96 queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags | M_ZERO); 97 if (!queue) --- 53 unchanged lines hidden (view full) --- 151} 152 153int 154taskqueue_enqueue(struct taskqueue *queue, struct task *task) 155{ 156 struct task *ins; 157 struct task *prev; 158 | 68struct taskqueue * 69taskqueue_create(const char *name, int mflags, 70 taskqueue_enqueue_fn enqueue, void *context) 71{ 72 struct taskqueue *queue; 73 74 queue = malloc(sizeof(struct taskqueue), M_TASKQUEUE, mflags | M_ZERO); 75 if (!queue) --- 53 unchanged lines hidden (view full) --- 129} 130 131int 132taskqueue_enqueue(struct taskqueue *queue, struct task *task) 133{ 134 struct task *ins; 135 struct task *prev; 136 |
137 mtx_lock(&queue->tq_mutex); 138 |
|
159 /* 160 * Don't allow new tasks on a queue which is being freed. 161 */ | 139 /* 140 * Don't allow new tasks on a queue which is being freed. 141 */ |
162 mtx_lock(&queue->tq_mutex); | |
163 if (queue->tq_draining) { 164 mtx_unlock(&queue->tq_mutex); 165 return EPIPE; 166 } 167 168 /* 169 * Count multiple enqueues. 170 */ | 142 if (queue->tq_draining) { 143 mtx_unlock(&queue->tq_mutex); 144 return EPIPE; 145 } 146 147 /* 148 * Count multiple enqueues. 149 */ |
171 mtx_lock(&task->ta_mutex); | |
172 if (task->ta_pending) { 173 task->ta_pending++; | 150 if (task->ta_pending) { 151 task->ta_pending++; |
174 mtx_unlock(&task->ta_mutex); | |
175 mtx_unlock(&queue->tq_mutex); 176 return 0; 177 } 178 179 /* 180 * Optimise the case when all tasks have the same priority. 181 */ 182 prev = STAILQ_LAST(&queue->tq_queue, task, ta_link); --- 8 unchanged lines hidden (view full) --- 191 192 if (prev) 193 STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); 194 else 195 STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); 196 } 197 198 task->ta_pending = 1; | 152 mtx_unlock(&queue->tq_mutex); 153 return 0; 154 } 155 156 /* 157 * Optimise the case when all tasks have the same priority. 158 */ 159 prev = STAILQ_LAST(&queue->tq_queue, task, ta_link); --- 8 unchanged lines hidden (view full) --- 168 169 if (prev) 170 STAILQ_INSERT_AFTER(&queue->tq_queue, prev, task, ta_link); 171 else 172 STAILQ_INSERT_HEAD(&queue->tq_queue, task, ta_link); 173 } 174 175 task->ta_pending = 1; |
199 mtx_unlock(&task->ta_mutex); 200 | |
201 if (queue->tq_enqueue) 202 queue->tq_enqueue(queue->tq_context); | 176 if (queue->tq_enqueue) 177 queue->tq_enqueue(queue->tq_context); |
178 |
|
203 mtx_unlock(&queue->tq_mutex); | 179 mtx_unlock(&queue->tq_mutex); |
180 |
|
204 return 0; 205} 206 207void 208taskqueue_run(struct taskqueue *queue) 209{ 210 struct task *task; | 181 return 0; 182} 183 184void 185taskqueue_run(struct taskqueue *queue) 186{ 187 struct task *task; |
211 task_fn_t *saved_func; 212 void *arg; | |
213 int pending; 214 215 mtx_lock(&queue->tq_mutex); 216 while (STAILQ_FIRST(&queue->tq_queue)) { 217 /* 218 * Carefully remove the first task from the queue and 219 * zero its pending count. 220 */ 221 task = STAILQ_FIRST(&queue->tq_queue); | 188 int pending; 189 190 mtx_lock(&queue->tq_mutex); 191 while (STAILQ_FIRST(&queue->tq_queue)) { 192 /* 193 * Carefully remove the first task from the queue and 194 * zero its pending count. 195 */ 196 task = STAILQ_FIRST(&queue->tq_queue); |
222 mtx_lock(&task->ta_mutex); | |
223 STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); | 197 STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); |
224 mtx_unlock(&queue->tq_mutex); | |
225 pending = task->ta_pending; 226 task->ta_pending = 0; | 198 pending = task->ta_pending; 199 task->ta_pending = 0; |
227 saved_func = task->ta_func; 228 arg = task->ta_context; 229 mtx_unlock(&task->ta_mutex); | 200 mtx_unlock(&queue->tq_mutex); |
230 | 201 |
231 saved_func(arg, pending); | 202 task->ta_func(task->ta_context, pending); |
232 233 mtx_lock(&queue->tq_mutex); 234 } 235 mtx_unlock(&queue->tq_mutex); 236} 237 238static void 239taskqueue_swi_enqueue(void *context) --- 13 unchanged lines hidden --- | 203 204 mtx_lock(&queue->tq_mutex); 205 } 206 mtx_unlock(&queue->tq_mutex); 207} 208 209static void 210taskqueue_swi_enqueue(void *context) --- 13 unchanged lines hidden --- |