2025-08-16 13:23:25 +03:00
|
|
|
// SPDX-License-Identifier: CDDL-1.0
|
|
|
|
|
/*
|
|
|
|
|
* CDDL HEADER START
|
|
|
|
|
*
|
|
|
|
|
* The contents of this file are subject to the terms of the
|
|
|
|
|
* Common Development and Distribution License (the "License").
|
|
|
|
|
* You may not use this file except in compliance with the License.
|
|
|
|
|
*
|
|
|
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
|
|
|
* or https://opensource.org/licenses/CDDL-1.0.
|
|
|
|
|
* See the License for the specific language governing permissions
|
|
|
|
|
* and limitations under the License.
|
|
|
|
|
*
|
|
|
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
|
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
|
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
|
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
|
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
|
|
|
*
|
|
|
|
|
* CDDL HEADER END
|
|
|
|
|
*/
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
|
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
|
|
|
|
|
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
|
|
|
|
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef _SYS_TASKQ_H
|
|
|
|
|
#define _SYS_TASKQ_H
|
|
|
|
|
|
|
|
|
|
#include <pthread.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <sys/mutex.h>
|
|
|
|
|
#include <sys/rwlock.h>
|
|
|
|
|
#include <sys/condvar.h>
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Task queues
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define TASKQ_NAMELEN 31
|
|
|
|
|
|
|
|
|
|
typedef uintptr_t taskqid_t;
|
|
|
|
|
typedef void (task_func_t)(void *);
|
|
|
|
|
|
|
|
|
|
typedef struct taskq_ent {
|
|
|
|
|
struct taskq_ent *tqent_next;
|
|
|
|
|
struct taskq_ent *tqent_prev;
|
|
|
|
|
task_func_t *tqent_func;
|
|
|
|
|
void *tqent_arg;
|
|
|
|
|
uintptr_t tqent_flags;
|
|
|
|
|
} taskq_ent_t;
|
|
|
|
|
|
|
|
|
|
typedef struct taskq {
|
|
|
|
|
char tq_name[TASKQ_NAMELEN + 1];
|
|
|
|
|
kmutex_t tq_lock;
|
|
|
|
|
krwlock_t tq_threadlock;
|
|
|
|
|
kcondvar_t tq_dispatch_cv;
|
|
|
|
|
kcondvar_t tq_wait_cv;
|
|
|
|
|
kthread_t **tq_threadlist;
|
|
|
|
|
int tq_flags;
|
|
|
|
|
int tq_active;
|
|
|
|
|
int tq_nthreads;
|
|
|
|
|
int tq_nalloc;
|
|
|
|
|
int tq_minalloc;
|
|
|
|
|
int tq_maxalloc;
|
|
|
|
|
kcondvar_t tq_maxalloc_cv;
|
|
|
|
|
int tq_maxalloc_wait;
|
|
|
|
|
taskq_ent_t *tq_freelist;
|
|
|
|
|
taskq_ent_t tq_task;
|
|
|
|
|
} taskq_t;
|
|
|
|
|
|
|
|
|
|
#define TQENT_FLAG_PREALLOC 0x1 /* taskq_dispatch_ent used */
|
|
|
|
|
|
|
|
|
|
#define TASKQ_PREPOPULATE 0x0001
|
|
|
|
|
#define TASKQ_CPR_SAFE 0x0002 /* Use CPR safe protocol */
|
|
|
|
|
#define TASKQ_DYNAMIC 0x0004 /* Use dynamic thread scheduling */
|
|
|
|
|
#define TASKQ_THREADS_CPU_PCT 0x0008 /* Scale # threads by # cpus */
|
|
|
|
|
#define TASKQ_DC_BATCH 0x0010 /* Mark threads as batch */
|
|
|
|
|
|
|
|
|
|
#define TQ_SLEEP KM_SLEEP /* Can block for memory */
|
|
|
|
|
#define TQ_NOSLEEP KM_NOSLEEP /* cannot block for memory; may fail */
|
|
|
|
|
#define TQ_NOQUEUE 0x02 /* Do not enqueue if can't dispatch */
|
|
|
|
|
#define TQ_FRONT 0x08 /* Queue in front */
|
|
|
|
|
|
|
|
|
|
#define TASKQID_INVALID ((taskqid_t)0)
|
|
|
|
|
|
2025-11-11 03:16:30 +03:00
|
|
|
extern taskq_t *_system_taskq(void);
|
|
|
|
|
extern taskq_t *_system_delay_taskq(void);
|
|
|
|
|
|
|
|
|
|
#define system_taskq _system_taskq()
|
|
|
|
|
#define system_delay_taskq _system_delay_taskq()
|
2025-08-16 13:23:25 +03:00
|
|
|
|
|
|
|
|
extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t);
|
|
|
|
|
extern taskq_t *taskq_create_synced(const char *, int, pri_t, int, int, uint_t,
|
|
|
|
|
kthread_t ***);
|
|
|
|
|
#define taskq_create_proc(a, b, c, d, e, p, f) \
|
|
|
|
|
(taskq_create(a, b, c, d, e, f))
|
|
|
|
|
#define taskq_create_sysdc(a, b, d, e, p, dc, f) \
|
|
|
|
|
((void) sizeof (dc), taskq_create(a, b, maxclsyspri, d, e, f))
|
|
|
|
|
extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
|
|
|
|
|
extern taskqid_t taskq_dispatch_delay(taskq_t *, task_func_t, void *, uint_t,
|
|
|
|
|
clock_t);
|
|
|
|
|
extern void taskq_dispatch_ent(taskq_t *, task_func_t, void *, uint_t,
|
|
|
|
|
taskq_ent_t *);
|
|
|
|
|
extern int taskq_empty_ent(taskq_ent_t *);
|
|
|
|
|
extern void taskq_init_ent(taskq_ent_t *);
|
|
|
|
|
extern void taskq_destroy(taskq_t *);
|
|
|
|
|
extern void taskq_wait(taskq_t *);
|
|
|
|
|
extern void taskq_wait_id(taskq_t *, taskqid_t);
|
|
|
|
|
extern void taskq_wait_outstanding(taskq_t *, taskqid_t);
|
|
|
|
|
extern int taskq_member(taskq_t *, kthread_t *);
|
|
|
|
|
extern taskq_t *taskq_of_curthread(void);
|
|
|
|
|
extern int taskq_cancel_id(taskq_t *, taskqid_t);
|
|
|
|
|
extern void system_taskq_init(void);
|
|
|
|
|
extern void system_taskq_fini(void);
|
|
|
|
|
|
|
|
|
|
#endif /* _SYS_TASKQ_H */
|