1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 26 * Copyright (c) 2012, Joyent, Inc. All rights reserved. 27 */ 28 29 #ifndef _SYS_TASKQ_H 30 #define _SYS_TASKQ_H 31 32 #include <pthread.h> 33 #include <stdint.h> 34 #include <sys/kmem.h> 35 #include <sys/thread.h> 36 #include <sys/mutex.h> 37 #include <sys/rwlock.h> 38 #include <sys/condvar.h> 39 40 /* 41 * Task queues 42 */ 43 44 #define TASKQ_NAMELEN 31 45 46 typedef uintptr_t taskqid_t; 47 typedef void (task_func_t)(void *); 48 49 typedef struct taskq_ent { 50 struct taskq_ent *tqent_next; 51 struct taskq_ent *tqent_prev; 52 task_func_t *tqent_func; 53 void *tqent_arg; 54 uintptr_t tqent_flags; 55 } taskq_ent_t; 56 57 typedef struct taskq { 58 char tq_name[TASKQ_NAMELEN + 1]; 59 kmutex_t tq_lock; 60 krwlock_t tq_threadlock; 61 kcondvar_t tq_dispatch_cv; 62 kcondvar_t tq_wait_cv; 63 kthread_t **tq_threadlist; 64 int tq_flags; 65 int tq_active; 66 int tq_nthreads; 67 int tq_nalloc; 68 int tq_minalloc; 69 int tq_maxalloc; 70 kcondvar_t tq_maxalloc_cv; 71 int tq_maxalloc_wait; 72 taskq_ent_t *tq_freelist; 73 taskq_ent_t tq_task; 74 } taskq_t; 75 76 #define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */ 77 78 #define TASKQ_PREPOPULATE 0x0001 79 #define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ 80 #define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ 81 #define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */ 82 #define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */ 83 84 #define TQ_SLEEP KM_SLEEP /* Can block for memory */ 85 #define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */ 86 #define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ 87 #define TQ_FRONT 0x08 /* Queue in front */ 88 89 #define TASKQID_INVALID ((taskqid_t)0) 90 91 extern taskq_t *_system_taskq(void); 92 extern taskq_t *_system_delay_taskq(void); 93 94 #define system_taskq _system_taskq() 95 #define system_delay_taskq _system_delay_taskq() 96 97 extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); 98 extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t, 99 kthread_t ***); 100 #define taskq_create_proc(a, b, c, d, e, p, f) \ 101 (taskq_create(a, b, c, d, e, f)) 102 #define taskq_create_sysdc(a, b, d, e, p, dc, f) \ 103 ((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f)) 104 extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); 105 extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t, 106 clock_t); 107 extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, 108 taskq_ent_t *); 109 extern int taskq_empty_ent(taskq_ent_t *); 110 extern void taskq_init_ent(taskq_ent_t *); 111 extern void taskq_destroy(taskq_t *); 112 extern void taskq_wait(taskq_t *); 113 extern void taskq_wait_id(taskq_t *, taskqid_t); 114 extern void taskq_wait_outstanding(taskq_t *, taskqid_t); 115 extern int taskq_member(taskq_t *, kthread_t *); 116 extern taskq_t *taskq_of_curthread(void); 117 extern int taskq_cancel_id(taskq_t *, taskqid_t, boolean_t); 118 extern void system_taskq_init(void); 119 extern void system_taskq_fini(void); 120 121 #endif /* _SYS_TASKQ_H */ 122