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/mutex.h> 35 #include <sys/rwlock.h> 36 #include <sys/condvar.h> 37 38 /* 39 * Task queues 40 */ 41 42 #define TASKQ_NAMELEN 31 43 44 typedef uintptr_t taskqid_t; 45 typedef void (task_func_t)(void *); 46 47 typedef struct taskq_ent { 48 struct taskq_ent *tqent_next; 49 struct taskq_ent *tqent_prev; 50 task_func_t *tqent_func; 51 void *tqent_arg; 52 uintptr_t tqent_flags; 53 } taskq_ent_t; 54 55 typedef struct taskq { 56 char tq_name[TASKQ_NAMELEN + 1]; 57 kmutex_t tq_lock; 58 krwlock_t tq_threadlock; 59 kcondvar_t tq_dispatch_cv; 60 kcondvar_t tq_wait_cv; 61 kthread_t **tq_threadlist; 62 int tq_flags; 63 int tq_active; 64 int tq_nthreads; 65 int tq_nalloc; 66 int tq_minalloc; 67 int tq_maxalloc; 68 kcondvar_t tq_maxalloc_cv; 69 int tq_maxalloc_wait; 70 taskq_ent_t *tq_freelist; 71 taskq_ent_t tq_task; 72 } taskq_t; 73 74 #define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */ 75 76 #define TASKQ_PREPOPULATE 0x0001 77 #define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */ 78 #define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */ 79 #define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */ 80 #define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */ 81 82 #define TQ_SLEEP KM_SLEEP /* Can block for memory */ 83 #define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */ 84 #define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */ 85 #define TQ_FRONT 0x08 /* Queue in front */ 86 87 #define TASKQID_INVALID ((taskqid_t)0) 88 89 extern taskq_t *_system_taskq(void); 90 extern taskq_t *_system_delay_taskq(void); 91 92 #define system_taskq _system_taskq() 93 #define system_delay_taskq _system_delay_taskq() 94 95 extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); 96 extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t, 97 kthread_t ***); 98 #define taskq_create_proc(a, b, c, d, e, p, f) \ 99 (taskq_create(a, b, c, d, e, f)) 100 #define taskq_create_sysdc(a, b, d, e, p, dc, f) \ 101 ((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f)) 102 extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t); 103 extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t, 104 clock_t); 105 extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t, 106 taskq_ent_t *); 107 extern int taskq_empty_ent(taskq_ent_t *); 108 extern void taskq_init_ent(taskq_ent_t *); 109 extern void taskq_destroy(taskq_t *); 110 extern void taskq_wait(taskq_t *); 111 extern void taskq_wait_id(taskq_t *, taskqid_t); 112 extern void taskq_wait_outstanding(taskq_t *, taskqid_t); 113 extern int taskq_member(taskq_t *, kthread_t *); 114 extern taskq_t *taskq_of_curthread(void); 115 extern int taskq_cancel_id(taskq_t *, taskqid_t); 116 extern void system_taskq_init(void); 117 extern void system_taskq_fini(void); 118 119 #endif /* _SYS_TASKQ_H */ 120