xref: /onnv-gate/usr/src/uts/common/sys/taskq_impl.h (revision 9515:d3b739d9d043)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9515SJonathan.Adams@Sun.COM  * Common Development and Distribution License (the "License").
6*9515SJonathan.Adams@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*9515SJonathan.Adams@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #ifndef	_SYS_TASKQ_IMPL_H
270Sstevel@tonic-gate #define	_SYS_TASKQ_IMPL_H
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/taskq.h>
300Sstevel@tonic-gate #include <sys/vmem.h>
310Sstevel@tonic-gate #include <sys/kstat.h>
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #ifdef	__cplusplus
340Sstevel@tonic-gate extern "C" {
350Sstevel@tonic-gate #endif
360Sstevel@tonic-gate 
370Sstevel@tonic-gate typedef struct taskq_bucket taskq_bucket_t;
380Sstevel@tonic-gate 
390Sstevel@tonic-gate typedef struct taskq_ent {
400Sstevel@tonic-gate 	struct taskq_ent	*tqent_next;
410Sstevel@tonic-gate 	struct taskq_ent	*tqent_prev;
420Sstevel@tonic-gate 	task_func_t		*tqent_func;
430Sstevel@tonic-gate 	void			*tqent_arg;
440Sstevel@tonic-gate 	taskq_bucket_t		*tqent_bucket;
450Sstevel@tonic-gate 	kthread_t		*tqent_thread;
460Sstevel@tonic-gate 	kcondvar_t		tqent_cv;
470Sstevel@tonic-gate } taskq_ent_t;
480Sstevel@tonic-gate 
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate  * Taskq Statistics fields are not protected by any locks.
510Sstevel@tonic-gate  */
520Sstevel@tonic-gate typedef struct tqstat {
530Sstevel@tonic-gate 	uint_t		tqs_hits;
540Sstevel@tonic-gate 	uint_t		tqs_misses;
550Sstevel@tonic-gate 	uint_t		tqs_overflow;	/* no threads to allocate   */
560Sstevel@tonic-gate 	uint_t		tqs_tcreates;	/* threads created 	*/
570Sstevel@tonic-gate 	uint_t		tqs_tdeaths;	/* threads died		*/
580Sstevel@tonic-gate 	uint_t		tqs_maxthreads;	/* max # of alive threads */
590Sstevel@tonic-gate 	uint_t		tqs_nomem;	/* # of times there were no memory */
600Sstevel@tonic-gate 	uint_t		tqs_disptcreates;
610Sstevel@tonic-gate } tqstat_t;
620Sstevel@tonic-gate 
630Sstevel@tonic-gate /*
640Sstevel@tonic-gate  * Per-CPU hash bucket manages taskq_bent_t structures using freelist.
650Sstevel@tonic-gate  */
660Sstevel@tonic-gate struct taskq_bucket {
670Sstevel@tonic-gate 	kmutex_t	tqbucket_lock;
680Sstevel@tonic-gate 	taskq_t		*tqbucket_taskq;	/* Enclosing taskq */
690Sstevel@tonic-gate 	taskq_ent_t	tqbucket_freelist;
700Sstevel@tonic-gate 	uint_t		tqbucket_nalloc;	/* # of allocated entries */
710Sstevel@tonic-gate 	uint_t		tqbucket_nfree;		/* # of free entries */
720Sstevel@tonic-gate 	kcondvar_t	tqbucket_cv;
730Sstevel@tonic-gate 	ushort_t	tqbucket_flags;
740Sstevel@tonic-gate 	hrtime_t	tqbucket_totaltime;
750Sstevel@tonic-gate 	tqstat_t	tqbucket_stat;
760Sstevel@tonic-gate };
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate  * Bucket flags.
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate #define	TQBUCKET_CLOSE		0x01
820Sstevel@tonic-gate #define	TQBUCKET_SUSPEND	0x02
830Sstevel@tonic-gate 
840Sstevel@tonic-gate /*
850Sstevel@tonic-gate  * taskq implementation flags: bit range 16-31
860Sstevel@tonic-gate  */
87*9515SJonathan.Adams@Sun.COM #define	TASKQ_CHANGING		0x00010000
880Sstevel@tonic-gate #define	TASKQ_SUSPENDED		0x00020000
890Sstevel@tonic-gate #define	TASKQ_NOINSTANCE	0x00040000
90*9515SJonathan.Adams@Sun.COM #define	TASKQ_THREAD_CREATED	0x00080000
910Sstevel@tonic-gate 
920Sstevel@tonic-gate struct taskq {
930Sstevel@tonic-gate 	char		tq_name[TASKQ_NAMELEN + 1];
940Sstevel@tonic-gate 	kmutex_t	tq_lock;
950Sstevel@tonic-gate 	krwlock_t	tq_threadlock;
960Sstevel@tonic-gate 	kcondvar_t	tq_dispatch_cv;
970Sstevel@tonic-gate 	kcondvar_t	tq_wait_cv;
98*9515SJonathan.Adams@Sun.COM 	kcondvar_t	tq_exit_cv;
99*9515SJonathan.Adams@Sun.COM 	pri_t		tq_pri;		/* Scheduling priority */
1000Sstevel@tonic-gate 	uint_t		tq_flags;
1010Sstevel@tonic-gate 	int		tq_active;
1020Sstevel@tonic-gate 	int		tq_nthreads;
103*9515SJonathan.Adams@Sun.COM 	int		tq_nthreads_target;
104*9515SJonathan.Adams@Sun.COM 	int		tq_nthreads_max;
105*9515SJonathan.Adams@Sun.COM 	int		tq_threads_ncpus_pct;
1060Sstevel@tonic-gate 	int		tq_nalloc;
1070Sstevel@tonic-gate 	int		tq_minalloc;
1080Sstevel@tonic-gate 	int		tq_maxalloc;
1090Sstevel@tonic-gate 	taskq_ent_t	*tq_freelist;
1100Sstevel@tonic-gate 	taskq_ent_t	tq_task;
1110Sstevel@tonic-gate 	int		tq_maxsize;
1120Sstevel@tonic-gate 	taskq_bucket_t	*tq_buckets;	/* Per-cpu array of buckets */
1130Sstevel@tonic-gate 	int		tq_instance;
1140Sstevel@tonic-gate 	uint_t		tq_nbuckets;	/* # of buckets	(2^n)	    */
1150Sstevel@tonic-gate 	union {
1160Sstevel@tonic-gate 		kthread_t *_tq_thread;
1170Sstevel@tonic-gate 		kthread_t **_tq_threadlist;
1180Sstevel@tonic-gate 	}		tq_thr;
1190Sstevel@tonic-gate 	/*
1200Sstevel@tonic-gate 	 * Statistics.
1210Sstevel@tonic-gate 	 */
1220Sstevel@tonic-gate 	kstat_t		*tq_kstat;	/* Exported statistics */
1230Sstevel@tonic-gate 	hrtime_t	tq_totaltime;	/* Time spent processing tasks */
1240Sstevel@tonic-gate 	int		tq_tasks;	/* Total # of tasks posted */
1250Sstevel@tonic-gate 	int		tq_executed;	/* Total # of tasks executed */
1260Sstevel@tonic-gate 	int		tq_maxtasks;	/* Max number of tasks in the queue */
1270Sstevel@tonic-gate 	int		tq_tcreates;
1280Sstevel@tonic-gate 	int		tq_tdeaths;
1290Sstevel@tonic-gate };
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate #define	tq_thread tq_thr._tq_thread
1320Sstevel@tonic-gate #define	tq_threadlist tq_thr._tq_threadlist
1330Sstevel@tonic-gate 
134*9515SJonathan.Adams@Sun.COM /* The MAX guarantees we have at least one thread */
135*9515SJonathan.Adams@Sun.COM #define	TASKQ_THREADS_PCT(ncpus, pct)	MAX(((ncpus) * (pct)) / 100, 1)
136*9515SJonathan.Adams@Sun.COM 
1370Sstevel@tonic-gate #ifdef	__cplusplus
1380Sstevel@tonic-gate }
1390Sstevel@tonic-gate #endif
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate #endif	/* _SYS_TASKQ_IMPL_H */
142