disp.h revision 3434:5142e1d7d0bc
1153761Swollman/*
2192886Sedwin * CDDL HEADER START
3192886Sedwin *
467578Swollman * The contents of this file are subject to the terms of the
52742Swollman * Common Development and Distribution License (the "License").
62742Swollman * You may not use this file except in compliance with the License.
7243003Sedwin *
82742Swollman * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9248307Sedwin * or http://www.opensolaris.org/os/licensing.
102742Swollman * See the License for the specific language governing permissions
112742Swollman * and limitations under the License.
12158421Swollman *
13158421Swollman * When distributing Covered Code, include this CDDL HEADER in each
142742Swollman * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1586222Swollman * If applicable, add the following below this CDDL HEADER, with the
1620094Swollman * fields enclosed by brackets "[]" replaced with your own identifying
1720094Swollman * information: Portions Copyright [yyyy] [name of copyright owner]
1820094Swollman *
1920094Swollman * CDDL HEADER END
2020094Swollman */
21158421Swollman/*
22158421Swollman * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2320094Swollman * Use is subject to license terms.
242742Swollman */
252742Swollman
262742Swollman/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
272742Swollman/*	  All Rights Reserved  	*/
28248307Sedwin
29248307Sedwin
30248307Sedwin#ifndef _SYS_DISP_H
31248307Sedwin#define	_SYS_DISP_H
3214343Swollman
3358787Sru#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.11	*/
3414343Swollman
3530711Swollman#include <sys/priocntl.h>
3630711Swollman#include <sys/thread.h>
37149514Swollman#include <sys/class.h>
3830711Swollman
3930711Swollman#ifdef	__cplusplus
4030711Swollmanextern "C" {
4130711Swollman#endif
4230711Swollman
432742Swollman/*
4430711Swollman * The following is the format of a dispatcher queue entry.
4530711Swollman */
4630711Swollmantypedef struct dispq {
4730711Swollman	kthread_t	*dq_first;	/* first thread on queue or NULL */
4830711Swollman	kthread_t	*dq_last;	/* last thread on queue or NULL */
492742Swollman	int		dq_sruncnt;	/* number of loaded, runnable */
5030711Swollman					/*    threads on queue */
5130711Swollman} dispq_t;
5230711Swollman
5330711Swollman/*
5430711Swollman * Dispatch queue structure.
5530711Swollman */
5630711Swollmantypedef struct _disp {
5730711Swollman	disp_lock_t	disp_lock;	/* protects dispatching fields */
5830711Swollman	pri_t		disp_npri;	/* # of priority levels in queue */
5930711Swollman	dispq_t		*disp_q;		/* the dispatch queue */
602742Swollman	dispq_t		*disp_q_limit;	/* ptr past end of dispatch queue */
6130711Swollman	ulong_t		*disp_qactmap;	/* bitmap of active dispatch queues */
6230711Swollman
6330711Swollman	/*
64226289Sedwin	 * Priorities:
6530711Swollman	 *	disp_maxrunpri is the maximum run priority of runnable threads
6630711Swollman	 * 	on this queue.  It is -1 if nothing is runnable.
672742Swollman	 *
6830711Swollman	 *	disp_max_unbound_pri is the maximum run priority of threads on
692742Swollman	 *	this dispatch queue but runnable by any CPU.  This may be left
702742Swollman	 * 	artificially high, then corrected when some CPU tries to take
712742Swollman	 *	an unbound thread.  It is -1 if nothing is runnable.
7219878Swollman	 */
73158421Swollman	pri_t		disp_maxrunpri;	/* maximum run priority */
7419878Swollman	pri_t		disp_max_unbound_pri;	/* max pri of unbound threads */
7519878Swollman
7619878Swollman	volatile int	disp_nrunnable;	/* runnable threads in cpu dispq */
7719878Swollman
782742Swollman	struct cpu	*disp_cpu;	/* cpu owning this queue or NULL */
7919878Swollman	hrtime_t	disp_steal;	/* time when threads become stealable */
802742Swollman} disp_t;
8119878Swollman
822742Swollman#if defined(_KERNEL)
83158421Swollman
842742Swollman#define	MAXCLSYSPRI	99
852742Swollman#define	MINCLSYSPRI	60
8619878Swollman
872742Swollman
8819878Swollman/*
892742Swollman * Global scheduling variables.
9019878Swollman *	- See sys/cpuvar.h for CPU-local variables.
912742Swollman */
9219878Swollmanextern int	nswapped;	/* number of swapped threads */
932742Swollman				/* nswapped protected by swap_lock */
94158421Swollman
95158421Swollmanextern	pri_t	minclsyspri;	/* minimum level of any system class */
962742Swollmanextern	pri_t	maxclsyspri;	/* maximum level of any system class */
972742Swollmanextern	pri_t	intr_pri;	/* interrupt thread priority base level */
9814343Swollman
9919878Swollman/*
10019878Swollman * Minimum amount of time that a thread can remain runnable before it can
1012742Swollman * be stolen by another CPU (in nanoseconds).
10219878Swollman */
10319878Swollmanextern hrtime_t nosteal_nsec;
10419878Swollman
10519878Swollman/*
10619878Swollman * Kernel preemption occurs if a higher-priority thread is runnable with
1072742Swollman * a priority at or above kpreemptpri.
1082742Swollman *
1092742Swollman * So that other processors can watch for such threads, a separate
1102742Swollman * dispatch queue with unbound work above kpreemptpri is maintained.
11186222Swollman * This is part of the CPU partition structure (cpupart_t).
11230711Swollman */
1132742Swollmanextern	pri_t	kpreemptpri;	/* level above which preemption takes place */
1142742Swollman
115158421Swollmanextern void		disp_kp_alloc(disp_t *, pri_t);	/* allocate kp queue */
116158421Swollmanextern void		disp_kp_free(disp_t *);		/* free kp queue */
1172742Swollman
1182742Swollman/*
11930711Swollman * Macro for use by scheduling classes to decide whether the thread is about
12030711Swollman * to be scheduled or not.  This returns the maximum run priority.
1212742Swollman */
1222742Swollman#define	DISP_MAXRUNPRI(t)	((t)->t_disp_queue->disp_maxrunpri)
123248307Sedwin
124248307Sedwin/*
125248307Sedwin * Platform callbacks for various dispatcher operations
1262742Swollman *
1272742Swollman * idle_cpu() is invoked when a cpu goes idle, and has nothing to do.
128248307Sedwin * disp_enq_thread() is invoked when a thread is placed on a run queue.
12930711Swollman */
13030711Swollmanextern void	(*idle_cpu)();
13130711Swollmanextern void	(*disp_enq_thread)(struct cpu *, int);
1322742Swollman
1332742Swollman
1342742Swollmanextern int		dispdeq(kthread_t *);
1352742Swollmanextern void		dispinit(void);
13630711Swollmanextern void		disp_add(sclass_t *);
1372742Swollmanextern int		intr_active(struct cpu *, int);
1382742Swollmanextern int		servicing_interrupt(void);
1392742Swollmanextern void		preempt(void);
1402742Swollmanextern void		setbackdq(kthread_t *);
14130711Swollmanextern void		setfrontdq(kthread_t *);
1422742Swollmanextern void		swtch(void);
1432742Swollmanextern void		swtch_to(kthread_t *);
144158421Swollmanextern void		swtch_from_zombie(void)
1452742Swollman				__NORETURN;
1462742Swollmanextern void		dq_sruninc(kthread_t *);
14730711Swollmanextern void		dq_srundec(kthread_t *);
1482742Swollmanextern void		cpu_rechoose(kthread_t *);
1492742Swollmanextern void		cpu_surrender(kthread_t *);
1502742Swollmanextern void		kpreempt(int);
1512742Swollmanextern struct cpu	*disp_lowpri_cpu(struct cpu *, struct lgrp_ld *, pri_t,
1522742Swollman			    struct cpu *);
1532742Swollmanextern int		disp_bound_threads(struct cpu *, int);
1542742Swollmanextern int		disp_bound_anythreads(struct cpu *, int);
15519878Swollmanextern int		disp_bound_partition(struct cpu *, int);
1562742Swollmanextern void		disp_cpu_init(struct cpu *);
1572742Swollmanextern void		disp_cpu_fini(struct cpu *);
1582742Swollmanextern void		disp_cpu_inactive(struct cpu *);
1592742Swollmanextern void		disp_adjust_unbound_pri(kthread_t *);
16030711Swollmanextern void		resume(kthread_t *);
1612742Swollmanextern void		resume_from_intr(kthread_t *);
1622742Swollmanextern void		resume_from_zombie(kthread_t *)
1632742Swollman				__NORETURN;
1642742Swollmanextern void		disp_swapped_enq(kthread_t *);
16530711Swollmanextern int		disp_anywork(void);
16630711Swollman
16730711Swollman#define	KPREEMPT_SYNC		(-1)
1682742Swollman#define	kpreempt_disable()				\
1692742Swollman	{						\
1702742Swollman		curthread->t_preempt++;			\
1712742Swollman		ASSERT(curthread->t_preempt >= 1);	\
1722742Swollman	}
1732742Swollman#define	kpreempt_enable()				\
17430711Swollman	{						\
1752742Swollman		ASSERT(curthread->t_preempt >= 1);	\
17630711Swollman		if (--curthread->t_preempt == 0 &&	\
17730711Swollman		    CPU->cpu_kprunrun)			\
17830711Swollman			kpreempt(KPREEMPT_SYNC);	\
17930711Swollman	}
18030711Swollman
18130711Swollman#endif	/* _KERNEL */
18230711Swollman
1832742Swollman#ifdef	__cplusplus
18430711Swollman}
1852742Swollman#endif
1862742Swollman
1872742Swollman#endif	/* _SYS_DISP_H */
1882742Swollman