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