1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_TASKQ_IMPL_H 27 #define _SYS_TASKQ_IMPL_H 28 29 #include <sys/taskq.h> 30 #include <sys/vmem.h> 31 #include <sys/kstat.h> 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 typedef struct taskq_bucket taskq_bucket_t; 38 39 typedef struct taskq_ent { 40 struct taskq_ent *tqent_next; 41 struct taskq_ent *tqent_prev; 42 task_func_t *tqent_func; 43 void *tqent_arg; 44 taskq_bucket_t *tqent_bucket; 45 kthread_t *tqent_thread; 46 kcondvar_t tqent_cv; 47 } taskq_ent_t; 48 49 /* 50 * Taskq Statistics fields are not protected by any locks. 51 */ 52 typedef struct tqstat { 53 uint_t tqs_hits; 54 uint_t tqs_misses; 55 uint_t tqs_overflow; /* no threads to allocate */ 56 uint_t tqs_tcreates; /* threads created */ 57 uint_t tqs_tdeaths; /* threads died */ 58 uint_t tqs_maxthreads; /* max # of alive threads */ 59 uint_t tqs_nomem; /* # of times there were no memory */ 60 uint_t tqs_disptcreates; 61 } tqstat_t; 62 63 /* 64 * Per-CPU hash bucket manages taskq_bent_t structures using freelist. 65 */ 66 struct taskq_bucket { 67 kmutex_t tqbucket_lock; 68 taskq_t *tqbucket_taskq; /* Enclosing taskq */ 69 taskq_ent_t tqbucket_freelist; 70 uint_t tqbucket_nalloc; /* # of allocated entries */ 71 uint_t tqbucket_nfree; /* # of free entries */ 72 kcondvar_t tqbucket_cv; 73 ushort_t tqbucket_flags; 74 hrtime_t tqbucket_totaltime; 75 tqstat_t tqbucket_stat; 76 }; 77 78 /* 79 * Bucket flags. 80 */ 81 #define TQBUCKET_CLOSE 0x01 82 #define TQBUCKET_SUSPEND 0x02 83 84 /* 85 * taskq implementation flags: bit range 16-31 86 */ 87 #define TASKQ_CHANGING 0x00010000 88 #define TASKQ_SUSPENDED 0x00020000 89 #define TASKQ_NOINSTANCE 0x00040000 90 #define TASKQ_THREAD_CREATED 0x00080000 91 92 struct taskq { 93 char tq_name[TASKQ_NAMELEN + 1]; 94 kmutex_t tq_lock; 95 krwlock_t tq_threadlock; 96 kcondvar_t tq_dispatch_cv; 97 kcondvar_t tq_wait_cv; 98 kcondvar_t tq_exit_cv; 99 pri_t tq_pri; /* Scheduling priority */ 100 uint_t tq_flags; 101 int tq_active; 102 int tq_nthreads; 103 int tq_nthreads_target; 104 int tq_nthreads_max; 105 int tq_threads_ncpus_pct; 106 int tq_nalloc; 107 int tq_minalloc; 108 int tq_maxalloc; 109 taskq_ent_t *tq_freelist; 110 taskq_ent_t tq_task; 111 int tq_maxsize; 112 taskq_bucket_t *tq_buckets; /* Per-cpu array of buckets */ 113 int tq_instance; 114 uint_t tq_nbuckets; /* # of buckets (2^n) */ 115 union { 116 kthread_t *_tq_thread; 117 kthread_t **_tq_threadlist; 118 } tq_thr; 119 /* 120 * Statistics. 121 */ 122 kstat_t *tq_kstat; /* Exported statistics */ 123 hrtime_t tq_totaltime; /* Time spent processing tasks */ 124 int tq_tasks; /* Total # of tasks posted */ 125 int tq_executed; /* Total # of tasks executed */ 126 int tq_maxtasks; /* Max number of tasks in the queue */ 127 int tq_tcreates; 128 int tq_tdeaths; 129 }; 130 131 #define tq_thread tq_thr._tq_thread 132 #define tq_threadlist tq_thr._tq_threadlist 133 134 /* The MAX guarantees we have at least one thread */ 135 #define TASKQ_THREADS_PCT(ncpus, pct) MAX(((ncpus) * (pct)) / 100, 1) 136 137 #ifdef __cplusplus 138 } 139 #endif 140 141 #endif /* _SYS_TASKQ_IMPL_H */ 142