xref: /onnv-gate/usr/src/uts/common/sys/taskq_impl.h (revision 11854:5351ddd19d45)
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
59515SJonathan.Adams@Sun.COM  * Common Development and Distribution License (the "License").
69515SJonathan.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*11854SChris.Horne@Sun.COM  * Copyright 2010 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>
3011173SJonathan.Adams@Sun.COM #include <sys/inttypes.h>
310Sstevel@tonic-gate #include <sys/vmem.h>
3211173SJonathan.Adams@Sun.COM #include <sys/list.h>
330Sstevel@tonic-gate #include <sys/kstat.h>
340Sstevel@tonic-gate 
350Sstevel@tonic-gate #ifdef	__cplusplus
360Sstevel@tonic-gate extern "C" {
370Sstevel@tonic-gate #endif
380Sstevel@tonic-gate 
390Sstevel@tonic-gate typedef struct taskq_bucket taskq_bucket_t;
400Sstevel@tonic-gate 
410Sstevel@tonic-gate typedef struct taskq_ent {
420Sstevel@tonic-gate 	struct taskq_ent	*tqent_next;
430Sstevel@tonic-gate 	struct taskq_ent	*tqent_prev;
440Sstevel@tonic-gate 	task_func_t		*tqent_func;
450Sstevel@tonic-gate 	void			*tqent_arg;
460Sstevel@tonic-gate 	taskq_bucket_t		*tqent_bucket;
470Sstevel@tonic-gate 	kthread_t		*tqent_thread;
480Sstevel@tonic-gate 	kcondvar_t		tqent_cv;
490Sstevel@tonic-gate } taskq_ent_t;
500Sstevel@tonic-gate 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * Taskq Statistics fields are not protected by any locks.
530Sstevel@tonic-gate  */
540Sstevel@tonic-gate typedef struct tqstat {
550Sstevel@tonic-gate 	uint_t		tqs_hits;
560Sstevel@tonic-gate 	uint_t		tqs_misses;
570Sstevel@tonic-gate 	uint_t		tqs_overflow;	/* no threads to allocate   */
580Sstevel@tonic-gate 	uint_t		tqs_tcreates;	/* threads created 	*/
590Sstevel@tonic-gate 	uint_t		tqs_tdeaths;	/* threads died		*/
600Sstevel@tonic-gate 	uint_t		tqs_maxthreads;	/* max # of alive threads */
610Sstevel@tonic-gate 	uint_t		tqs_nomem;	/* # of times there were no memory */
620Sstevel@tonic-gate 	uint_t		tqs_disptcreates;
630Sstevel@tonic-gate } tqstat_t;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate /*
660Sstevel@tonic-gate  * Per-CPU hash bucket manages taskq_bent_t structures using freelist.
670Sstevel@tonic-gate  */
680Sstevel@tonic-gate struct taskq_bucket {
690Sstevel@tonic-gate 	kmutex_t	tqbucket_lock;
700Sstevel@tonic-gate 	taskq_t		*tqbucket_taskq;	/* Enclosing taskq */
710Sstevel@tonic-gate 	taskq_ent_t	tqbucket_freelist;
720Sstevel@tonic-gate 	uint_t		tqbucket_nalloc;	/* # of allocated entries */
730Sstevel@tonic-gate 	uint_t		tqbucket_nfree;		/* # of free entries */
740Sstevel@tonic-gate 	kcondvar_t	tqbucket_cv;
750Sstevel@tonic-gate 	ushort_t	tqbucket_flags;
760Sstevel@tonic-gate 	hrtime_t	tqbucket_totaltime;
770Sstevel@tonic-gate 	tqstat_t	tqbucket_stat;
780Sstevel@tonic-gate };
790Sstevel@tonic-gate 
800Sstevel@tonic-gate /*
810Sstevel@tonic-gate  * Bucket flags.
820Sstevel@tonic-gate  */
830Sstevel@tonic-gate #define	TQBUCKET_CLOSE		0x01
840Sstevel@tonic-gate #define	TQBUCKET_SUSPEND	0x02
850Sstevel@tonic-gate 
8611173SJonathan.Adams@Sun.COM #define	TASKQ_INTERFACE_FLAGS	0x0000ffff	/* defined in <sys/taskq.h> */
8711173SJonathan.Adams@Sun.COM 
880Sstevel@tonic-gate /*
890Sstevel@tonic-gate  * taskq implementation flags: bit range 16-31
900Sstevel@tonic-gate  */
9111173SJonathan.Adams@Sun.COM #define	TASKQ_CHANGING		0x00010000	/* nthreads != target */
9211173SJonathan.Adams@Sun.COM #define	TASKQ_SUSPENDED		0x00020000	/* taskq is suspended */
9311173SJonathan.Adams@Sun.COM #define	TASKQ_NOINSTANCE	0x00040000	/* no instance number */
9411173SJonathan.Adams@Sun.COM #define	TASKQ_THREAD_CREATED	0x00080000	/* a thread has been created */
9511173SJonathan.Adams@Sun.COM #define	TASKQ_DUTY_CYCLE	0x00100000	/* using the SDC class */
960Sstevel@tonic-gate 
970Sstevel@tonic-gate struct taskq {
980Sstevel@tonic-gate 	char		tq_name[TASKQ_NAMELEN + 1];
990Sstevel@tonic-gate 	kmutex_t	tq_lock;
1000Sstevel@tonic-gate 	krwlock_t	tq_threadlock;
1010Sstevel@tonic-gate 	kcondvar_t	tq_dispatch_cv;
1020Sstevel@tonic-gate 	kcondvar_t	tq_wait_cv;
1039515SJonathan.Adams@Sun.COM 	kcondvar_t	tq_exit_cv;
1049515SJonathan.Adams@Sun.COM 	pri_t		tq_pri;		/* Scheduling priority */
1050Sstevel@tonic-gate 	uint_t		tq_flags;
1060Sstevel@tonic-gate 	int		tq_active;
1070Sstevel@tonic-gate 	int		tq_nthreads;
1089515SJonathan.Adams@Sun.COM 	int		tq_nthreads_target;
1099515SJonathan.Adams@Sun.COM 	int		tq_nthreads_max;
1109515SJonathan.Adams@Sun.COM 	int		tq_threads_ncpus_pct;
1110Sstevel@tonic-gate 	int		tq_nalloc;
1120Sstevel@tonic-gate 	int		tq_minalloc;
1130Sstevel@tonic-gate 	int		tq_maxalloc;
114*11854SChris.Horne@Sun.COM 	kcondvar_t	tq_maxalloc_cv;
115*11854SChris.Horne@Sun.COM 	int		tq_maxalloc_wait;
1160Sstevel@tonic-gate 	taskq_ent_t	*tq_freelist;
1170Sstevel@tonic-gate 	taskq_ent_t	tq_task;
1180Sstevel@tonic-gate 	int		tq_maxsize;
1190Sstevel@tonic-gate 	taskq_bucket_t	*tq_buckets;	/* Per-cpu array of buckets */
1200Sstevel@tonic-gate 	int		tq_instance;
1210Sstevel@tonic-gate 	uint_t		tq_nbuckets;	/* # of buckets	(2^n)	    */
1220Sstevel@tonic-gate 	union {
1230Sstevel@tonic-gate 		kthread_t *_tq_thread;
1240Sstevel@tonic-gate 		kthread_t **_tq_threadlist;
1250Sstevel@tonic-gate 	}		tq_thr;
12611173SJonathan.Adams@Sun.COM 
12711173SJonathan.Adams@Sun.COM 	list_node_t	tq_cpupct_link;	/* linkage for taskq_cpupct_list */
12811173SJonathan.Adams@Sun.COM 	struct proc	*tq_proc;	/* process for taskq threads */
12911173SJonathan.Adams@Sun.COM 	int		tq_cpupart;	/* cpupart id bound to */
13011173SJonathan.Adams@Sun.COM 	uint_t		tq_DC;		/* duty cycle for SDC */
13111173SJonathan.Adams@Sun.COM 
1320Sstevel@tonic-gate 	/*
1330Sstevel@tonic-gate 	 * Statistics.
1340Sstevel@tonic-gate 	 */
1350Sstevel@tonic-gate 	kstat_t		*tq_kstat;	/* Exported statistics */
1360Sstevel@tonic-gate 	hrtime_t	tq_totaltime;	/* Time spent processing tasks */
13711173SJonathan.Adams@Sun.COM 	uint64_t	tq_tasks;	/* Total # of tasks posted */
13811173SJonathan.Adams@Sun.COM 	uint64_t	tq_executed;	/* Total # of tasks executed */
1390Sstevel@tonic-gate 	int		tq_maxtasks;	/* Max number of tasks in the queue */
1400Sstevel@tonic-gate 	int		tq_tcreates;
1410Sstevel@tonic-gate 	int		tq_tdeaths;
1420Sstevel@tonic-gate };
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #define	tq_thread tq_thr._tq_thread
1450Sstevel@tonic-gate #define	tq_threadlist tq_thr._tq_threadlist
1460Sstevel@tonic-gate 
1479515SJonathan.Adams@Sun.COM /* The MAX guarantees we have at least one thread */
1489515SJonathan.Adams@Sun.COM #define	TASKQ_THREADS_PCT(ncpus, pct)	MAX(((ncpus) * (pct)) / 100, 1)
1499515SJonathan.Adams@Sun.COM 
1500Sstevel@tonic-gate #ifdef	__cplusplus
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate #endif
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate #endif	/* _SYS_TASKQ_IMPL_H */
155