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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 31 #ifndef _SYS_DISP_H 32 #define _SYS_DISP_H 33 34 #pragma ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.11 */ 35 36 #include <sys/priocntl.h> 37 #include <sys/thread.h> 38 #include <sys/class.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /* 45 * The following is the format of a dispatcher queue entry. 46 */ 47 typedef struct dispq { 48 kthread_t *dq_first; /* first thread on queue or NULL */ 49 kthread_t *dq_last; /* last thread on queue or NULL */ 50 int dq_sruncnt; /* number of loaded, runnable */ 51 /* threads on queue */ 52 } dispq_t; 53 54 /* 55 * Dispatch queue structure. 56 */ 57 typedef struct _disp { 58 disp_lock_t disp_lock; /* protects dispatching fields */ 59 pri_t disp_npri; /* # of priority levels in queue */ 60 dispq_t *disp_q; /* the dispatch queue */ 61 dispq_t *disp_q_limit; /* ptr past end of dispatch queue */ 62 ulong_t *disp_qactmap; /* bitmap of active dispatch queues */ 63 64 /* 65 * Priorities: 66 * disp_maxrunpri is the maximum run priority of runnable threads 67 * on this queue. It is -1 if nothing is runnable. 68 * 69 * disp_max_unbound_pri is the maximum run priority of threads on 70 * this dispatch queue but runnable by any CPU. This may be left 71 * artificially high, then corrected when some CPU tries to take 72 * an unbound thread. It is -1 if nothing is runnable. 73 */ 74 pri_t disp_maxrunpri; /* maximum run priority */ 75 pri_t disp_max_unbound_pri; /* max pri of unbound threads */ 76 77 volatile int disp_nrunnable; /* runnable threads in cpu dispq */ 78 79 struct cpu *disp_cpu; /* cpu owning this queue or NULL */ 80 } disp_t; 81 82 #if defined(_KERNEL) 83 84 #define MAXCLSYSPRI 99 85 #define MINCLSYSPRI 60 86 87 88 /* 89 * Global scheduling variables. 90 * - See sys/cpuvar.h for CPU-local variables. 91 */ 92 extern int nswapped; /* number of swapped threads */ 93 /* nswapped protected by swap_lock */ 94 95 extern pri_t minclsyspri; /* minimum level of any system class */ 96 extern pri_t maxclsyspri; /* maximum level of any system class */ 97 extern pri_t intr_pri; /* interrupt thread priority base level */ 98 99 /* 100 * Amount of time that may elapse before a thread is considered to have 101 * lost it's cache investment. 102 */ 103 #define RECHOOSE_INTERVAL 3 104 extern int rechoose_interval; 105 106 /* 107 * Kernel preemption occurs if a higher-priority thread is runnable with 108 * a priority at or above kpreemptpri. 109 * 110 * So that other processors can watch for such threads, a separate 111 * dispatch queue with unbound work above kpreemptpri is maintained. 112 * This is part of the CPU partition structure (cpupart_t). 113 */ 114 extern pri_t kpreemptpri; /* level above which preemption takes place */ 115 116 extern void disp_kp_alloc(disp_t *, pri_t); /* allocate kp queue */ 117 extern void disp_kp_free(disp_t *); /* free kp queue */ 118 119 /* 120 * Macro for use by scheduling classes to decide whether the thread is about 121 * to be scheduled or not. This returns the maximum run priority. 122 */ 123 #define DISP_MAXRUNPRI(t) ((t)->t_disp_queue->disp_maxrunpri) 124 125 /* 126 * Platform callbacks for various dispatcher operations 127 * 128 * idle_cpu() is invoked when a cpu goes idle, and has nothing to do. 129 * disp_enq_thread() is invoked when a thread is placed on a run queue. 130 */ 131 extern void (*idle_cpu)(); 132 extern void (*disp_enq_thread)(struct cpu *, int); 133 134 135 extern int dispdeq(kthread_t *); 136 extern void dispinit(void); 137 extern void disp_add(sclass_t *); 138 extern int intr_active(struct cpu *, int); 139 extern int servicing_interrupt(void); 140 extern void preempt(void); 141 extern void setbackdq(kthread_t *); 142 extern void setfrontdq(kthread_t *); 143 extern void swtch(void); 144 extern void swtch_to(kthread_t *); 145 extern void swtch_from_zombie(void) 146 __NORETURN; 147 extern void dq_sruninc(kthread_t *); 148 extern void dq_srundec(kthread_t *); 149 extern void cpu_rechoose(kthread_t *); 150 extern void cpu_surrender(kthread_t *); 151 extern void kpreempt(int); 152 extern struct cpu *disp_lowpri_cpu(struct cpu *, struct lgrp_ld *, pri_t, 153 struct cpu *); 154 extern int disp_bound_threads(struct cpu *, int); 155 extern int disp_bound_anythreads(struct cpu *, int); 156 extern int disp_bound_partition(struct cpu *, int); 157 extern void disp_cpu_init(struct cpu *); 158 extern void disp_cpu_fini(struct cpu *); 159 extern void disp_cpu_inactive(struct cpu *); 160 extern void disp_adjust_unbound_pri(kthread_t *); 161 extern void resume(kthread_t *); 162 extern void resume_from_intr(kthread_t *); 163 extern void resume_from_zombie(kthread_t *) 164 __NORETURN; 165 extern void disp_swapped_enq(kthread_t *); 166 extern int disp_anywork(void); 167 168 #define KPREEMPT_SYNC (-1) 169 #define kpreempt_disable() \ 170 { \ 171 curthread->t_preempt++; \ 172 ASSERT(curthread->t_preempt >= 1); \ 173 } 174 #define kpreempt_enable() \ 175 { \ 176 ASSERT(curthread->t_preempt >= 1); \ 177 if (--curthread->t_preempt == 0 && \ 178 CPU->cpu_kprunrun) \ 179 kpreempt(KPREEMPT_SYNC); \ 180 } 181 182 #endif /* _KERNEL */ 183 184 #ifdef __cplusplus 185 } 186 #endif 187 188 #endif /* _SYS_DISP_H */ 189