8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 #include <sys/taskq_impl.h>
31
32 #include <sys/class.h>
33 #include <sys/debug.h>
34 #include <sys/ksynch.h>
35 #include <sys/kmem.h>
36 #include <sys/time.h>
37 #include <sys/systm.h>
38 #include <sys/sysmacros.h>
39 #include <sys/unistd.h>
40
41 /* avoid <unistd.h> */
42 extern long sysconf(int);
43
44 /* avoiding <thread.h> */
45 typedef unsigned int thread_t;
46 typedef unsigned int thread_key_t;
47
191 /*
192 * Enqueue the task to the underlying queue.
193 */
194 mutex_enter(&tq->tq_lock);
195
196 if (flags & TQ_FRONT) {
197 t->tqent_next = tq->tq_task.tqent_next;
198 t->tqent_prev = &tq->tq_task;
199 } else {
200 t->tqent_next = &tq->tq_task;
201 t->tqent_prev = tq->tq_task.tqent_prev;
202 }
203 t->tqent_next->tqent_prev = t;
204 t->tqent_prev->tqent_next = t;
205 t->tqent_func = func;
206 t->tqent_arg = arg;
207 cv_signal(&tq->tq_dispatch_cv);
208 mutex_exit(&tq->tq_lock);
209 }
210
211 void
212 taskq_wait(taskq_t *tq)
213 {
214 mutex_enter(&tq->tq_lock);
215 while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
216 cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
217 mutex_exit(&tq->tq_lock);
218 }
219
220 static void *
221 taskq_thread(void *arg)
222 {
223 taskq_t *tq = arg;
224 taskq_ent_t *t;
225 boolean_t prealloc;
226
227 mutex_enter(&tq->tq_lock);
228 while (tq->tq_flags & TASKQ_ACTIVE) {
229 if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
230 if (--tq->tq_active == 0)
|
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 * Copyright (c) 2017, Joyent, Inc.
29 */
30
31 #include <sys/taskq_impl.h>
32
33 #include <sys/class.h>
34 #include <sys/debug.h>
35 #include <sys/ksynch.h>
36 #include <sys/kmem.h>
37 #include <sys/time.h>
38 #include <sys/systm.h>
39 #include <sys/sysmacros.h>
40 #include <sys/unistd.h>
41
42 /* avoid <unistd.h> */
43 extern long sysconf(int);
44
45 /* avoiding <thread.h> */
46 typedef unsigned int thread_t;
47 typedef unsigned int thread_key_t;
48
192 /*
193 * Enqueue the task to the underlying queue.
194 */
195 mutex_enter(&tq->tq_lock);
196
197 if (flags & TQ_FRONT) {
198 t->tqent_next = tq->tq_task.tqent_next;
199 t->tqent_prev = &tq->tq_task;
200 } else {
201 t->tqent_next = &tq->tq_task;
202 t->tqent_prev = tq->tq_task.tqent_prev;
203 }
204 t->tqent_next->tqent_prev = t;
205 t->tqent_prev->tqent_next = t;
206 t->tqent_func = func;
207 t->tqent_arg = arg;
208 cv_signal(&tq->tq_dispatch_cv);
209 mutex_exit(&tq->tq_lock);
210 }
211
212 boolean_t
213 taskq_empty(taskq_t *tq)
214 {
215 boolean_t rv;
216
217 mutex_enter(&tq->tq_lock);
218 rv = (tq->tq_task.tqent_next == &tq->tq_task) && (tq->tq_active == 0);
219 mutex_exit(&tq->tq_lock);
220
221 return (rv);
222 }
223
224 void
225 taskq_wait(taskq_t *tq)
226 {
227 mutex_enter(&tq->tq_lock);
228 while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
229 cv_wait(&tq->tq_wait_cv, &tq->tq_lock);
230 mutex_exit(&tq->tq_lock);
231 }
232
233 static void *
234 taskq_thread(void *arg)
235 {
236 taskq_t *tq = arg;
237 taskq_ent_t *t;
238 boolean_t prealloc;
239
240 mutex_enter(&tq->tq_lock);
241 while (tq->tq_flags & TASKQ_ACTIVE) {
242 if ((t = tq->tq_task.tqent_next) == &tq->tq_task) {
243 if (--tq->tq_active == 0)
|