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